如何让setuptools忽略子版本库存?
在用setup.py打包一个Python包的时候,如果你使用了setuptools:
from setuptools import setup
...
通过以下方式创建的源代码分发:
python setup.py sdist
不仅会包含在MANIFEST.in中指定的文件,还会额外包含所有在包目录下被Subversion(一个版本控制工具)列为受控的文件。这让人非常烦恼。不仅让我们很难明确控制哪些文件会被打包,还意味着当我用“svn export”而不是“svn checkout”来构建我的包时,包的内容可能会大相径庭。因为没有.svn的元数据,setuptools会根据不同的选择来决定包含哪些文件。
我想问的是:如何关闭这种糟糕的行为,让“setuptools”在我使用Subversion、它从未听说过的版本控制工具,或者我在项目结束时创建的“svn export”裸树时,都能以相同的方式对待我的项目?
到目前为止,我找到的最好办法是一个很丑陋的猴子补丁:
from setuptools.command import sdist
del sdist.finders[:]
但这可是Python,不是丛林,所以我当然希望有一个更好的解决方案,完全不涉及猴子。我该如何驯服setuptools,关闭它的魔法,让它根据我在MANIFEST.py中可见且可预测的规则来合理地处理呢?
6 个回答
创建一个名为 MANIFEST.in 的文件,内容如下:
recursive-exclude .
# other MANIFEST.in commands go here
# to explicitly include whatever files you want
有关 MANIFEST.in 语法的详细信息,请查看 这个链接。
我知道你对这些内容已经很了解了,Brandon,但我还是尽量给出一个完整的回答(虽然我不是setuptools的专家),希望能对其他人有所帮助。
这里的问题是,setuptools本身涉及很多复杂的东西,包括一个叫做setuptools.file_finders的入口点,你可以在这里添加插件来查找要包含的文件。不过,我完全不知道怎么从中移除插件……
快速解决办法:把你的包用svn导出到一个临时目录,然后从那里运行setup.py。这意味着你没有svn,所以svn查找器找不到要包含的文件。:)
较长的解决办法:你真的需要setuptools吗?setuptools有很多功能,所以答案可能是需要,但主要这些功能是处理依赖关系(这样你的依赖就能通过easy_install安装)、命名空间包(比如foo.bar)和入口点。其实命名空间包也可以不使用setuptools来创建。如果你不使用这些功能,可能只用distutils就够了。
丑陋的解决办法:你在问题中给sdist的猴子补丁,这个补丁让插件没有任何查找器,并且快速退出。
所以你看,尽管我尽量让这个回答尽可能完整,但还是显得有些不够。我其实无法回答你的问题,不过我觉得答案是“你不能”。
简单的解决办法是,不要使用setuptools来创建源代码分发包,而是把这个命令降级到使用distutils。
from distutils.command.sdist import sdist
from setuptools import setup
setup(
# ... all the usual setup arguments ...
cmdclass = {'sdist': sdist},
)