【问题标题】:How can I make setuptools ignore subversion inventory?如何让 setuptools 忽略颠覆清单?
【发布时间】:2010-11-10 21:07:06
【问题描述】:

使用 setup.py 打包 Python 包时,使用 setuptools:

from setuptools import setup
...

源代码分发创建者:

python setup.py sdist

不仅像往常一样包括在 MANIFEST.in 中指定的文件,而且还无偿地包括了 Subversion 在包目录下列出的所有受版本控制的文件。这非常烦人。不仅难以对与我的包一起分发的文件进行任何形式的显式控制,而且这意味着当我按照“svn export”而不是“svn checkout”构建包时,我的内容包可能完全不同,因为没有 .svn 元数据设置工具会对包含的内容做出不同的选择。

我的问题:我如何才能关闭这种可怕的行为,以便“setuptools”以相同的方式对待我的项目,无论我使用的是 Subversion,还是从未听说过的版本控制,或者使用“svn export”创建的裸树" 我在项目结束时创建的,以确保它在我的工作目录之外的某个地方干净地构建?

到目前为止,我做过的最好的事情是一个丑陋的猴子补丁:

from setuptools.command import sdist
del sdist.finders[:]

但这是 Python,而不是丛林,所以我当然想要一个完全不涉及猴子的更好的解决方案。我怎样才能驯服 setuptools,关闭它的魔力,并通过查看 MANIFEST.py 中可见的、可预测的规则来让它表现得明智?

【问题讨论】:

  • 我想我在这里遇到了完全相同的问题,只有 .git 和 py2app:stackoverflow.com/questions/9845590/…
  • 哇,它确实看起来像同样的问题!
  • 我发布了一个monkeypatch hack 作为我自己问题的答案。还没有找到更好的东西

标签: python packaging setuptools egg


【解决方案1】:

Brandon,我知道您对此了解很多,但为了他人的利益,我会尽量给出完整的答案(尽管我不是 setuptools 专家)。

这里的问题是 setuptools 本身涉及很多黑魔法,包括使用一个名为 setuptools.file_finders 的入口点,您可以在其中添加插件以查找要包含的文件。但是,我完全不知道如何从中删除插件...

  • 快速解决方法:svn 将您的包导出到一个临时目录并从那里运行 setup.py。这意味着你没有 svn,所以 svn finder 找不到要包含的文件。 :)

  • 更长的解决方法:您真的需要 setuptools 吗? Setuptools 有很多特性,所以答案可能是肯定的,但主要是这些特性是依赖项(因此您的依赖项由 easy_install 安装)、命名空间包 (foo.bar) 和入口点。命名空间包实际上也可以在没有 setuptools 的情况下创建。但是如果你不使用这些,你实际上可能只使用 distutils。

  • 丑陋的解决方法:您在问题中提供给 sdist 的猴子补丁,这只会使插件没有任何查找器,然后快速退出。

如您所见,这个答案虽然尽我所能完成,但仍然令人尴尬地不完整。我实际上无法回答您的问题,尽管我认为答案是“您不能”。

【讨论】:

    【解决方案2】:

    创建一个 MANIFEST.in 文件:

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

    请参阅http://docs.python.org/distutils/commandref.html#sdist-cmd 了解 MANIFEST.in 语法。

    【讨论】:

    • 这对我来说会产生错误。我不得不使用recursive-exclude . *
    【解决方案3】:

    简单的解决方案,不要使用 setuptools 来创建源代码分发,为该命令降级到 distutils:

    from distutils.command.sdist import sdist
    from setuptools import setup
    
    setup(
        # ... all the usual setup arguments ...
        cmdclass = {'sdist': sdist},
    )
    

    【讨论】:

    • 我不知道这个类可以按命令自定义!感谢您指出这一点。
    【解决方案4】:

    可能答案在您的 setup.py 中。你使用 find_packages 吗?此函数默认使用 VCS(例如 subversion、hg、...)。如果你不喜欢它,只需编写一个不同的 Python 函数,它只收集你想要的东西。

    【讨论】:

    • find_packages 实际上只是使用 listdir,并查找名为 __init__.py 的文件。
    【解决方案5】:

    我认为默认的 sdist 行为是正确的。当您构建 source 发行版时,我希望它包含已签入 Subversion 的所有内容。当然在特殊情况下能干净利落地覆盖就好了。

    将 sdist 与 bdist_egg 进行比较;我敢打赌,只有明确指定的文件才会被包含在内。

    我用三个文件做了一个简单的测试,都在svn中。空的 dummy.lkj 和 foobar.py 和 setup.py 看起来像这样:

    import setuptools
    setuptools.setup(name='foobar', version='0.1', py_modules=['foobar'])
    

    sdist 创建一个包含 dummy.lkj 的压缩包。 bdist_egg 创建一个不包含 dummy.lkj 的鸡蛋。

    【讨论】:

      【解决方案6】:

      你可能想要这样的东西:

      from distutils.core import setup
      
      def packages():
          import os
      
          packages = []
      
          for path, dirs, files in os.walk("yourprogram"):
              if ".svn" in dirs:
                  dirs.remove(".svn")
      
              if "__init__.py" in files:
                  packages.append(path.replace(os.sep, "."))
      
          return packages
      
      setup(
          # name, version, description, etc...
      
          packages = packages(),
      
          # pacakge_data, data_files, etc...
      )
      

      【讨论】:

      • +1:投反对票的请说明帖子无效的原因。这种方法似乎效果很好。
      猜你喜欢
      • 2011-08-13
      • 2023-04-05
      • 1970-01-01
      • 1970-01-01
      • 2011-09-09
      • 1970-01-01
      • 2012-10-29
      • 2014-03-21
      • 1970-01-01
      相关资源
      最近更新 更多