如何让setuptools忽略子版本库存?

20 投票
6 回答
3727 浏览
提问于 2025-04-15 12:54

在用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 个回答

9

创建一个名为 MANIFEST.in 的文件,内容如下:

recursive-exclude .
# other MANIFEST.in commands go here
# to explicitly include whatever files you want

有关 MANIFEST.in 语法的详细信息,请查看 这个链接

14

我知道你对这些内容已经很了解了,Brandon,但我还是尽量给出一个完整的回答(虽然我不是setuptools的专家),希望能对其他人有所帮助。

这里的问题是,setuptools本身涉及很多复杂的东西,包括一个叫做setuptools.file_finders的入口点,你可以在这里添加插件来查找要包含的文件。不过,我完全不知道怎么从中移除插件……

  • 快速解决办法:把你的包用svn导出到一个临时目录,然后从那里运行setup.py。这意味着你没有svn,所以svn查找器找不到要包含的文件。:)

  • 较长的解决办法:你真的需要setuptools吗?setuptools有很多功能,所以答案可能是需要,但主要这些功能是处理依赖关系(这样你的依赖就能通过easy_install安装)、命名空间包(比如foo.bar)和入口点。其实命名空间包也可以不使用setuptools来创建。如果你不使用这些功能,可能只用distutils就够了。

  • 丑陋的解决办法:你在问题中给sdist的猴子补丁,这个补丁让插件没有任何查找器,并且快速退出。

所以你看,尽管我尽量让这个回答尽可能完整,但还是显得有些不够。我其实无法回答你的问题,不过我觉得答案是“你不能”。

1

简单的解决办法是,不要使用setuptools来创建源代码分发包,而是把这个命令降级到使用distutils。

from distutils.command.sdist import sdist
from setuptools import setup

setup(
    # ... all the usual setup arguments ...
    cmdclass = {'sdist': sdist},
)

撰写回答