为什么可嵌入的 Python 发行版无法定位原生模块?



我正在尝试为Windows构建WeasyPrint的独立发行版。我下载了可嵌入的Python 3.8 ZIP文件,并将其解压缩到一个名为dist的目录中。然后,在MSYS2中,我使用了一个完整的Python 3.8解释器和Pip将WeasyPrint安装到dist目录中(解释了在MSYS2中安装Pillow时的一个错误(:

pip install --target dist --global-option=build_ext --global-option="-ldl" pillow
pip install --target dist weasyprint

现在,当我运行WeasyPrint:时

./dist/python.exe -m weasyprint http://weasyprint.org test.pdf

我得到:

Traceback (most recent call last):
File "runpy.py", line 184, in _run_module_as_main
File "runpy.py", line 143, in _get_module_details
File "runpy.py", line 110, in _get_module_details
File "C:msys64homeDaviddistweasyprint__init__.py", line 440, in <module>
from .css import preprocess_stylesheet  # noqa isort:skip
File "C:msys64homeDaviddistweasyprintcss__init__.py", line 30, in <module>
from . import computed_values, media_queries
File "C:msys64homeDaviddistweasyprintcsscomputed_values.py", line 18, in <module>
from .. import text
File "C:msys64homeDaviddistweasyprinttext.py", line 14, in <module>
import cairocffi as cairo
File "C:msys64homeDaviddistcairocffi__init__.py", line 17, in <module>
from ._generated.ffi import ffi
File "C:msys64homeDaviddistcairocffi_generatedffi.py", line 2, in <module>
import _cffi_backend
ModuleNotFoundError: No module named '_cffi_backend'

Python是如何找到其他模块而不是本地模块的?在dist目录中有一个名为_cffi_backend-cpython-38.dll的文件。如果我将文件重命名为_cffi_backend.dll,它仍然不起作用。

正如Smankusors在评论中提到的那样,这是由MSYS2 Python和可嵌入Python为扩展模块使用不同后缀引起的:

可嵌入Python:

$ ./dist/python.exe -c 'from importlib.machinery import EXTENSION_SUFFIXES; print(EXTENSION_SUFFIXES)'
['.cp38-win_amd64.pyd', '.pyd']

MSYS2 Python:

$ python -c 'from importlib.machinery import EXTENSION_SUFFIXES; print(EXTENSION_SUFFIXES)'
['-cpython-38.dll', '-abi3.dll', '.cp38.pyd', '.pyd']

因此,当CFFI轮子是用MSYS2 Python构建的时,会使用MSYS2 Python后缀,但Embeddable Python不知道要找它。解决方法是重命名DLL以使用一个Embeddable Python后缀,或者使用Python的本地Windows安装来安装模块。

最新更新