如何使用setuptools安装额外包数据?配置问题咨询
问题分析与解决方案
你的问题核心在于文件路径配置不匹配,以及对package_data和MANIFEST.in的作用范围理解有偏差,具体来说:
package_data配置的是包内部的文件(也就是foopackage/目录下的文件),但你的README.txt在项目根目录,不在foopackage文件夹里,所以这个配置根本找不到目标文件。MANIFEST.in只是让源发行版(sdist)包含根目录的README.txt,但安装时setuptools不知道该把这个文件放到哪里——因为你没指定它的安装路径,所以安装后自然找不到。- Wheel包没包含
README.txt也是同样的原因:它不在包目录下,也没被正确配置为要打包的数据文件。
下面给你两个兼容Python 2.7和3.4+的解决方案,根据你的需求选一个:
方案一:将README移到包目录下(推荐)
这是最符合Python包规范的做法,把文档文件放到对应的包目录里:
先移动文件:
mv README.txt foopackage/调整
setup.py:你可以保留include_package_data=True,然后修改MANIFEST.in或者直接用package_data(二选一即可):- 方式A:用
package_data(明确指定)# -*- coding: utf-8 -*- from setuptools import setup, find_packages setup( name='foopackage', version='0.0.1', description='A Package Full of Foo', packages=find_packages(), package_data={ 'foopackage': [ 'README.txt', ], }, # include_package_data=True 可以保留,也可以去掉,因为已经明确指定了package_data ) - 方式B:用
include_package_data=True配合MANIFEST.in
修改MANIFEST.in为:include foopackage/README.txtsetup.py里保留include_package_data=True,可以去掉package_data配置。
- 方式A:用
重新构建并验证:
python setup.py sdist bdist_wheel # 检查wheel里是否包含文件 unzip -v dist/foopackage-0.0.1-py3-none-any.whl | grep README.txt # 安装后检查 pip install dist/foopackage-0.0.1.tar.gz find $(python -c "import foopackage; print(foopackage.__path__[0])") -name README.txt
方案二:保留根目录的README,指定安装路径
如果你一定要把README.txt留在项目根目录,可以用data_files参数指定它的安装位置(比如安装到foopackage的目录下):
修改setup.py,添加data_files配置:
# -*- coding: utf-8 -*- from setuptools import setup, find_packages setup( name='foopackage', version='0.0.1', description='A Package Full of Foo', packages=find_packages(), # 指定将根目录的README.txt安装到site-packages/foopackage/目录下 data_files=[('foopackage', ['README.txt'])], include_package_data=True, )
然后重新构建安装,就能在包的安装目录里找到README.txt了。
额外注意事项
- 确保你使用的
setuptools版本足够新(对于Python 2.7,建议用setuptools>=36.2.0;Python 3.4+用setuptools>=40.0.0),避免兼容性问题。 - 如果你用
include_package_data=True,它会优先读取版本控制系统(比如git)的忽略文件,同时也会遵循MANIFEST.in的规则,所以确保README.txt没有被版本控制忽略。
内容的提问来源于stack exchange,提问作者mpounsett
相关产品推荐
相关产品推荐

