使用setup.py打包Python模块时,*.pyd文件未被正确包含的问题
问题分析
.pyd是Python的扩展模块文件,这类文件不能用普通的data_files或仅靠MANIFEST.in处理——setuptools会把它们视为编译产物而非普通资源,哪怕MANIFEST.in包含了,安装阶段也不会正确部署到site-packages的包目录里。
解决方案
方法1:用package_data指定包内扩展文件
直接在setup.py里配置package_data,明确指定要包含的.pyd文件,这是setuptools专门用来处理包内非Python代码文件的参数:
from setuptools import setup, find_packages setup( name="pyil", packages=find_packages(), package_data={ "pyil": ["_pyil.pyd"], # 填写相对于包目录的.pyd文件路径 }, include_package_data=True, # 必须开启这个参数才能启用包数据包含 )
如果.pyd在子目录里,比如pyil/libs/_pyil.pyd,就把路径改成["libs/_pyil.pyd"]。
方法2:将.pyd声明为扩展模块
既然.pyd是SWIG生成的预编译扩展模块,可以直接在setup.py里用ext_modules声明(不需要重新编译):
from setuptools import setup from setuptools.extension import Extension # 声明扩展模块,sources留空因为已经预编译完成 ext = Extension( name="pyil._pyil", # 要和.pyd的模块名完全对应 sources=[], ) setup( name="pyil", ext_modules=[ext], packages=["pyil"], # 确保包结构被正确识别 )
这种方式会让setuptools把.pyd当成正式的扩展模块处理,确保安装到正确的位置。
方法3:检查.pyd的兼容性
确认你的.pyd是针对当前Python版本、系统架构(32/64位)编译的——如果版本不匹配,setuptools会自动跳过这个文件,哪怕它出现在SOURCES.txt里。
关键提醒
MANIFEST.in只负责控制源码包(sdist)里包含的文件,安装时的文件部署由setup.py的package_data、ext_modules等参数决定,两者分工不同。- 别用
data_files,它会把文件放到系统级目录,而非site-packages的包目录下,导致Python无法导入模块。
内容的提问来源于stack exchange,提问作者Ben Müller
相关产品推荐
相关产品推荐

