如何让 setuptools 忽略 subversion inventory?
当使用 setuptools 的 setup.py 打包 Python 包时:
from setuptools import setup
...
创建的源代码发行版:
python setup.py sdist
不仅像往常一样包括 MANIFEST.in 中指定的文件,而且还无偿地包括 Subversion 列出的所有文件作为包目录下的版本控制。 这非常烦人。 这不仅使得对随我的包分发哪些文件进行任何类型的显式控制变得困难,而且这意味着当我按照“svn导出”而不是“svn签出”构建我的包时,我的包的内容包可能会完全不同,因为如果没有 .svn 元数据,安装工具将对要包含的内容做出不同的选择。
我的问题:我怎样才能关闭这种可怕的行为,以便“setuptools”以同样的方式对待我的项目,无论我使用的是Subversion,还是从未听说过的版本控制,或者是使用我使用的“svn导出”创建的裸树在我的项目结束时创建,以确保它在我的工作目录之外的某个地方干净地构建?
到目前为止,我做得最好的是一个丑陋的猴子补丁:
from setuptools.command import sdist
del sdist.finders[:]
但这是Python,而不是丛林,所以我当然想要一个完全不涉及猴子的更好的解决方案。 我怎样才能驯服 setuptools,关闭它的魔力,并通过查看 MANIFEST.py 中可见的、可预测的规则让它表现得明智?
When packaging a Python package with a setup.py that uses the setuptools:
from setuptools import setup
...
the source distribution created by:
python setup.py sdist
not only includes, as usual, the files specified in MANIFEST.in, but it also, gratuitously, includes all of the files that Subversion lists as being version controlled beneath the package directory. This is vastly annoying. Not only does it make it difficult to exercise any sort of explicit control over what files get distributed with my package, but it means that when I build my package following an "svn export" instead of an "svn checkout", the contents of my package might be quite different, since without the .svn metadata setuptools will make different choices about what to include.
My question: how can I turn off this terrible behavior, so that "setuptools" treats my project the same way whether I'm using Subversion, or version control it's never heard of, or a bare tree created with "svn export" that I've created at the end of my project to make sure it builds cleanly somewhere besides my working directory?
The best I have managed so far is an ugly monkey-patch:
from setuptools.command import sdist
del sdist.finders[:]
But this is Python, not the jungle, so of course I want a better solution that involves no monkeys at all. How can I tame setuptools, turn off its magic, and have it behave sensibly by looking at the visible, predictable rules in my MANIFEST.py instead?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我知道你对此了解很多,布兰登,但为了其他人的利益,我会尽力给出完整的答案(尽管我不是安装工具专家)。
这里的问题是 setuptools 本身涉及相当多的黑魔法,包括使用名为 setuptools.file_finders 的入口点,您可以在其中添加插件来查找要包含的文件。 然而,我完全不知道如何从中删除插件...
快速解决方法:svn 将包导出到临时目录并从那里运行 setup.py。 这意味着您没有 svn,因此 svn finder 找不到要包含的文件。 :)
更长的解决方法:你真的需要安装工具吗? setuptools 有很多功能,所以答案可能是肯定的,但这些功能主要是依赖项(因此您的依赖项通过 easy_install 安装)、命名空间包 (foo.bar) 和入口点。 实际上也可以在没有 setuptools 的情况下创建命名空间包。 但如果你不使用这些,你实际上可能只使用 distutils 就可以逃脱惩罚。
丑陋的解决方法:您在问题中给 sdist 的 Monkeypatch,这只会使插件没有任何查找器,并快速退出。
丑陋的解决方法:
正如你所看到的,这个答案虽然我能做到的很完整,但仍然是令人尴尬的不完整。 我实际上无法回答你的问题,尽管我认为答案是“你不能”。
I know you know much of this, Brandon, but I'll try to give as a complete answer as I can (although I'm no setuptools gury) for the benefit of others.
The problem here is that setuptools itself involves quite a lot of black magick, including using an entry point called setuptools.file_finders where you can add plugins to find files to include. I am, however, at a complete loss as to how REMOVE plugins from it...
Quick workaround: svn export your package to a temporary directory and run the setup.py from there. That means you have no svn, so the svn finder finds no files to include. :)
Longer workaround: Do you really need setuptools? Setuptools have a lot of features, so the answer is likely yes, but mainly those features are depdenencies (so your dependencies get installed by easy_install), namespace packages (foo.bar), and entry points. Namespace packages can actually be created without setuptools as well. But if you use none of these you might actually get away with just using distutils.
Ugly workaround: The monkeypatch you gave to sdist in your question, which simply makes the plugin not have any finders, and exit quickly.
So as you see, this answer, although as complete as I can make it, is still embarrassingly incomplete. I can't actually answer your question, though I think the answer is "You can't".
创建 MANIFEST.in 文件:
请参阅 http://docs.python.org/ distutils/commandref.html#sdist-cmd 用于 MANIFEST.in 语法。
Create a MANIFEST.in file with:
See http://docs.python.org/distutils/commandref.html#sdist-cmd for the MANIFEST.in syntax.
简单的解决方案,不要使用 setuptools 来创建源代码分发,针对该命令降级到 distutils:
Simple solution, do not use setuptools for creating the source distribution, downgrade to distutils for that command:
也许答案就在你的 setup.py 中。 你使用find_packages吗? 该函数默认使用VCS(例如subversion、hg...)。 如果你不喜欢它,只需编写一个不同的 Python 函数,它只收集你想要的东西。
Probably the answer is in your setup.py. Do you use find_packages? This function by default uses the VCS (e.g. subversion, hg, ...). If you don't like it, just write a different Python function which collects only the things you want.
我认为默认的 sdist 行为是正确的。 当您构建源代码发行版时,我希望它包含签入 Subversion 的所有内容。 当然,如果能够在特殊情况下干净地覆盖它那就太好了。
比较 sdist 和 bdist_egg; 我敢打赌,只有明确指定的文件才会被包含在内。
我用三个文件做了一个简单的测试,都在 svn 中。 清空 dummy.lkj 和 foobar.py,setup.py 如下所示:
sdist 创建一个包含 dummy.lkj 的 tarball。 bdist_egg 创建一个不包含 dummy.lkj 的 Egg。
I would argue that the default sdist behavior is correct. When you are building a source distribution, I would expect it to contain everything that is checked into Subversion. Of course it would be nice to be able to override it cleanly in special circumstances.
Compare sdist to bdist_egg; I bet only the files that are specified explicitly get included.
I did a simple test with three files, all in svn. Empty dummy.lkj and foobar.py and with setup.py looking like this:
sdist creates a tarball that includes dummy.lkj. bdist_egg creates an egg that does not include dummy.lkj.
你可能想要这样的东西:
You probably want something like this: