setuptools 问题 -- 排除包,包含数据文件
我对setuptools还比较陌生。看到一些类似的问题让我有点抓狂,因为我按照网上的建议去做,但setuptools的表现却和我想的不一样。
这是我项目的结构:
.
..
package1/
__init__.py
abc.py
...
tests/
__init__.py
test_package1.py
LICENSE
README.md
RELEASE
setup.py
这是我的setup.py文件的内容:
#!/usr/bin/env python
import os
#from distutils.core import setup
from setuptools import setup, find_packages
setup(
name='package1',
version='1.1',
test_suite="tests",
packages=find_packages(exclude=['tests']),
include_package_data=True,
package_data = {
'': ['LICENSE', 'README.md5', 'RELEASE']
},
)
另外,在我的清单文件中,我有:
include LICENSE
include RELEASE
include README.md
我用以下命令构建tar包:
python setup.py sdist
我想要做到:
- 把
tests
目录从源代码分发中排除掉; - 把LICENSE、README.md和RELEASE文件放到site-packages目录中,可以放在顶层,也可以放在package1目录里(这两种方式我都可以接受)。
但是,实际发生的情况是:
tests
目录仍然出现在生成的tar包中,并且被安装到了site-packages里;- 文件被复制到归档中,但没有安装到包的site-packages目录里。
我现在没有头绪了,有人能告诉我我哪里做错了吗?怎么才能解决这个问题?
5 个回答
我试了很多方法,但都没有效果,直到我删除了 build
这个文件夹(我看到有个回答提到 *.egg-info/
文件夹),然后它终于好了。你也可以用 python setup.py clean --all
这个命令来解决问题。
find_packages
这个函数用 fnmatchcase
来过滤掉不需要的包。你可以通过下面的方式来测试你的排除模式是否和包名匹配:
>>> from fnmatch import fnmatchcase
>>> fnmatchcase('my.package.name.tests', 'tests')
False
假设你项目中的所有测试都在包名以 tests
结尾的包里,或者是这些包的子包,那么下面的代码就可以用来排除所有的测试代码:
setup(
name='package1',
version='1.1',
packages=find_packages(exclude=['tests', '*.tests', '*.tests.*']),
)
如果你还想把 tests
文件夹从源代码分发中排除,可以在 MANIFEST.in 文件中添加以下内容:
recursive-exclude tests *
你需要在你的包的根目录下创建一个叫做 MANIFEST.in
的新文件,然后按照以下步骤操作:
为了控制哪些文件会被打包到你的 tar 文件里,你需要在包的根目录下创建一个叫做
MANIFEST.in
的新文件。比如,你可以使用MANIFEST.in
文件里的recursive-exclude
来排除整个目录不被打包。在你的情况下,你需要在MANIFEST.in
文件中包含:recursive-exclude tests *
通常情况下,不会把 README 和其他文件放在 site-packages 目录里,但如果你真的想这样做,那么你需要进入
package1
目录,并为你想要包含的文件创建符号链接:cd package1 ln -s ../LICENSE ln -s ../README.md ln -s ../RELEASE
然后在你的 setup.py 文件中修改以下这一行:
package_data = { '': ['LICENSE', 'README.md', 'RELEASE']
改成:
package_data = { 'package1': ['LICENSE', 'README.md', 'RELEASE']