[Python] Revert back the behavior of loading dlls to before python 3.8 and the new...

Discussão em 'Python' iniciado por Stack, Outubro 24, 2024.

  1. Stack

    Stack Membro Participativo

    The python doc explains the breaking change:


    New in version 3.8: Previous versions of CPython would resolve DLLs using the default behavior for the current process. This led to inconsistencies, such as only sometimes searching PATH or the current working directory, and OS functions such as AddDllDirectory having no effect.
    ​

    I've never had such issues, and I'd be happy for a specific example. I've never heard about AddDllDirectory before, and I was happy. I used to have a reliable process: dll dirs coincide with the environment path. This allowed me to easily test if necessary dlls are in the path, e.g., via dlldiag. I was able to easily read and modify the env path. This applies to any executable on Windows, and I had robust tools to handle any dll issues.

    Now, I have this os.add_dll_directory(). I don't see any way to read it, and there's no convenient var to modify. I can't compare what's there to verified locations of my dlls. Rumor has it, that this function uses in the end AddDllDirectory, and there are no additional convenient functions in its family.

    I tried the following simple solution:

    import os
    for p in os.environ[ 'path' ].split( ';' ):
    if os.path.isdir( p ):
    os.add_dll_directory( p )


    This resolved the useless error message


    ImportError: DLL load failed while importing foo: The specified module could not be found
    ​

    which meant couldn't find a dependent dll (god forbids it will tell me clearly that a dll is missing and which one).

    Now, however, I have a completely new useless message:


    ImportError: DLL load failed while importing foo: The operating system cannot run %1
    ​

    which apparently means that there are two candidate dlls in the path, and it doesn't know what to do (or the wrong one was loaded or something).

    This is a new can of worms. I usually have in the path both release and debug versions of the dlls, and there was never such an issue. Now, I have to be very careful to separate them and specify each dir with the proper release or debug that I'm running. If in my pipeline I have a script that executes another one as a different process, well, bad luck, these new dll paths aren't inherited anymore, and you need somehow to pass them down the line.

    How am I suppose to conveniently handle that without burdening the user with these dir specification? How do I keep this cross platform? Now, I need special code for Windows.

    Python suddenly decides to break from its nice cross-platform behavior and starts meddling with obscure Windows functions (using a platform specific command). Moreover, the function of win32api.LoadLibrary() is now inconsistent with how ctypes loads a dll.

    How can I revert back the behavior of loading dlls to the way it was before Python 3.8?

    Continue reading...

Compartilhe esta Página