setuptools打包安装后资源文件未按预期包含如何解决
问题根因
配置不生效是两个核心问题共同导致的:
MANIFEST.in的作用范围认知错误:这个文件的规则仅作用于源码分发包(即执行python setup.py sdist生成的tar.gz/zip压缩包)的文件打包逻辑,默认不会干预pip install安装阶段往虚拟环境site-packages目录复制文件的流程——默认安装逻辑只会复制包内所有.py后缀的源代码文件,非py资源不会自动复制。- 资源路径配置错误:你的项目发布名是
wbn,find_packages()默认扫描当前目录下所有合法Python包(带__init__.py的目录),你写的recursive-include nl/cli *.yml规则指向nl/cli路径,和你实际要打包的wbn包路径不匹配,根本匹配不到目标yml文件。
修复方法
二选一即可,推荐第一种更稳定可控:
方法1:直接在setup中声明package_data
不需要依赖MANIFEST.in,直接在setup函数里明确指定每个包要带的资源文件,不管是打源码包还是本地安装都会生效,不会出现配置不一致问题。
修改你的setup代码如下:
from setuptools import setup, find_packages LONGDOC = """ To be completed """ PACKAGES = find_packages() def setup_package(): setup( name='wbn', version='3.10', description='knowledge matcher', long_description=LONGDOC, packages=PACKAGES, # 新增包资源配置,替换为你yml文件实际所在的包路径 package_data={ # 如果yml存放在wbn包下的cli目录,就写下面这行 "wbn.cli": ["*.yml"], # 如果要递归包含wbn包下所有子目录的yml文件,就替换为 # "wbn": ["**/*.yml"] }, # 开启后会自动识别包内的资源文件,避免漏装 include_package_data=True ) if __name__ == "__main__": setup_package()
方法2:修正MANIFEST.in配合安装参数
如果你习惯用MANIFEST.in管理资源,按两步修改:
- 修正MANIFEST.in里的路径规则,指向你实际存放yml的包目录,比如文件在
wbn/cli下的话,规则改为:recursive-include wbn/cli *.yml - 在setup()函数中添加
include_package_data=True参数,这个参数会告诉setuptools,安装时把MANIFEST.in匹配到的、位于Python包目录内的所有非py文件一并复制到site-packages的安装路径下。
注意:所有需要安装的资源文件必须放在对应Python包的目录内部,放在包目录外的文件哪怕被MANIFEST.in匹配到,也不会被安装到site-packages的wbn目录中。
- 改完配置后务必先清理旧构建缓存:删除项目根目录下的
build文件夹、后缀为.egg-info的文件夹,再重新执行pip install .,否则旧缓存会导致新配置不生效。
内容的提问来源于stack exchange,提问作者marlon
相关产品推荐
相关产品推荐

