PyWin32 and Python 3.8.0

冷暖自知 提交于 2020-05-17 07:12:46

问题


Python 3.8.0 has been recently released (on 20191014, and can be downloaded from [Python]: Python 3.8.0).
PyWin32 has builds for it on [PyPI]: pywin32 225 (released on 20190915). Unfortunately, after pip installing, it doesn't work.

Sample:

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q058631512]> sopr.bat
*** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ***

[prompt]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe"
Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import win32api
>>> ^Z


[prompt]> "e:\Work\Dev\VEnvs\py_064_03.08.00_test0\Scripts\python.exe"
Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import win32api
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: DLL load failed while importing win32api: The specified module could not be found.
>>> ^Z

Notes:

  • For Python 3.7, I also upgraded my PyWin32 module to the latest, and it works
  • Older PyWin32 versions work on older Python versions (2.7, 3.5, 3.6)
  • Reproducible on 64bit and 32bit

回答1:


Spoiler alert!!!

Applied #2.2. (from below) to the original .whls, and published them on [GitHub]: CristiFati/Prebuilt-Binaries - (master) Prebuilt-Binaries/PyWin32/v225 (win_amd64, win32 for Python 3.8).

After installing (one of) them, existing code should work OOTB (with respect to this issue).



The problem has been reported on [GitHub]: mhammond/pywin32 - python 3.8.

The above URL references 2 more:

  • [Python 3.8.Docs]: What’s New In Python 3.8 - Changes in the Python API which states (emphasis is mine):
    • DLL dependencies for extension modules and DLLs loaded with ctypes on Windows are now resolved more securely. Only the system paths, the directory containing the DLL or PYD file, and directories added with add_dll_directory() are searched for load-time dependencies. Specifically, PATH and the current working directory are no longer used, and modifications to these will no longer have any effect on normal DLL resolution.
  • [Python 3.Docs]: os.add_dll_directory(path) which states (emphasis still mine):

    This search path is used when resolving dependencies for imported extension modules (the module itself is resolved through sys.path), and also by ctypes.

In the same time, I did some digging of my own and discovered that (for win32api.pyd) it's pywintypes38.dll (which is a dependency for the .pyds) that is not found (I also specified this in a comment on the issue).

Solutions (actually workarounds (more or less) until an official and backwards compatible fix is released):

  1. Force pywintypes38.dll load by importing it (as it's also a Python module and in this scenario it doesn't fall under the above rule) before any PyWin32 module:

    import pywintypes
    import win32api
    

    If working with COM, you'd need import pythoncom

  2. Adding pywin32_system32 to the .dll search paths (following the new model from above). There are multiple ways:

    1. v-python's comment from the issue URL which provides a small snippet (I didn't test it)
    2. I also submitted [GitHub]: mhammond/pywin32 - Support for Python 3.8, where I do everything in the pywin32.pth file ("executed" when the interpreter starts, so no changes needed for existing code). Unfortunately, there is a problem with the AppVeyor automated tests which fail (but for some other reasons), so it has been stuck there for a while. Note that in the meantime, the PR was closed and another (similar) approach was pushed. Note that v226 (released on 20191110) which contains the fix, does not work on VirtualEnv ([SO]: PyWin32 (226) and virtual environments (@CristiFati's answer)).
      Anyway, applying the changes locally (1) (on both my Python VirtualEnvs), solved the problem (on one, and didn't break the other):

      [cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q058631512]> sopr.bat
      *** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ***
      
      [prompt]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" -c "import win32api"
      
      [prompt]> "e:\Work\Dev\VEnvs\py_064_03.08.00_test0\Scripts\python.exe" -c "import win32api"
      
      [prompt]>
      
    3. Other ways like copying the .dlls (e.g. in %SystemRoot%\System32), or symlinking them, but (personally) I wouldn't recommend those



Update #0

[PyPI]: pywin32 227 (which addresses this issue), was published on 20191114!



Footnotes

  • #1: Check [SO]: Run / Debug a Django application's UnitTests from the mouse right click context menu in PyCharm Community Edition? (@CristiFati's answer) (Patching utrunner section) for how to apply patches (on Win).



回答2:


Managed to install pywin32 v225 with pycharm on python 3.8.

importing pywintypes before win32api

import pywintypes
import win32api


来源:https://stackoverflow.com/questions/61717476/loading-python-module-depending-on-dll-not-next-to-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!