3

我们有一段代码使用 PyWin32,偶尔也会调用 Py_Finalize() 和 Py_Initialize() 来重新初始化 python。我们发现了一个错误,其中动态创建的类class error是从 pywintypes 中的字符串创建的PyRun_String()PyWinTypesmodule.cpp,第 860 行),在重新初始化后不会重新创建。此类最终在重新初始化后被使用,并在尝试调用该函数时抛出“NoneType is not callable”错误len()

Py_Finalize()我们已经观察到,如果在调用之前立即调用PyWinTypes export ,则错误停止发生PyWinGlobals_Free(),它位于上面链接的同一源文件中。

在 PyWin32 代码库的其他地方(在dllmain.cpp中),有以下函数,在 regsvr32.exe 中进行 COM 注册/取消注册后清理时调用该函数:

void PyCom_DLLReleaseRef(void)
{
    /*** NOTE: We no longer finalize Python EVER in the COM world
         see pycom-dev mailing list archives from April 2000 for why
    ***/
    // Must be thread-safe, although cant have the Python lock!
    // only needed when we finalize.
    //  CEnterLeaveFramework _celf;
    LONG cnt = InterlockedDecrement(&g_cLockCount);
    // Not optimal, but anything better is hard - g_cLockCount
    // could always transition 1->0->1 at some stage, screwing this
    // up.  Oh well...
    if (cnt==0) {
        // Send a quit message to the registered thread (if we have one)
        if (dwQuitThreadId)
            PostThreadMessage(dwQuitThreadId, WM_QUIT, 0, 0);
        /*** Old finalize code
             if (bDidInitPython) {
             PyEval_RestoreThread(ptsGlobal);
             PyWinGlobals_Free();
             FreeGatewayModule();
             Py_Finalize();

             bDidInitPython=FALSE;
             }
        ***/
    }
}

这里有两点值得注意:

  1. 顶部有一个神秘的注释,暗示在这种情况下没有最终确定 Python 是有原因的。不幸的是,它所引用的“pycom-dev”邮件列表似乎不再存在。我认为是有问题的线程的正确链接,但 pythonpros.com 似乎是一些 sedo 域停放的东西。

  2. 注释掉的“旧的最终确定代码”确实在确定 python 之前调用了 PyWinGlobals_Free(),这表明我们的修复可能在正确的轨道上。然而,除了源代码中这段神秘的代码片段之外,我们还没有在网络上找到任何文档或信息,表明在使用 PyWin32 时,在最终确定 python 之前必须做任何特别的事情。还有其他一些调用:FreeGatewayModules() 和 PyEval_RestoreThread()。我不确定我们是否应该自己调用这些。

我们的修复似乎有效,在没有更多信息的情况下,我们可能会接受它,但如果能得到一些确认会很好。

4

1 回答 1

2

答案来自 python-win32 邮件列表: http: //mail.python.org/pipermail/python-win32/2013-January/012671.html

不幸的是,重复初始化和完成 Python 存在许多问题,因此您在 pywin32 中看到的代码不再尝试支持它。简而言之,使用 pywin32 不支持这样做(至少在 Python 中的问题通过支持此功能的新模块 API 修复之前,并且 pywin32 进行了相应调整)

马克[哈蒙德]

于 2013-01-21T10:21:31.880 回答