setuptools vs. distutils:为什么distutils仍然是一个东西?

时间:2014-08-16 06:49:45

标签: python packaging setuptools distutils

Python有一个令人困惑的工具历史记录,可用于打包和描述项目:这些工具包括标准库中的distutilsdistributedistutils2setuptools (也许更多)。看来distributedistutils2已停止使用setuptools,这留下了两个相互竞争的标准。

据我所知setuptools提供了比distutils更多的选项(例如声明依赖关系,测试等),但是它没有包含在Python标准库中(但是?)。

Python包装用户指南 [1]现在建议:

  

使用setuptools定义项目并创建源分发。

并解释说:

  

尽管您可以在许多项目中使用纯distutils,但它不支持在其他项目上定义依赖项,并且缺少一些便捷实用程序来自动填充由setuptools提供的包元数据。作为标准库之外,setuptools还在不同版本的Python中提供更一致的功能集,并且(与distutils不同),setuptools将更新为生成即将推出的“Metadata 2.0”标准格式支持的版本。

     

即使对于选择使用distutils的项目,当pip直接从源安装此类项目(而不是从预构建的wheel文件安装)时,它实际上将使用setuptools来构建项目。

但是,查看各种项目的 setup.py 文件会发现这似乎不是一个真正的标准。许多软件包仍使用distutils,而支持setuptools的软件包通常会将setuptoolsdistutils混合使用,例如通过回退导入:

try:
    from setuptools import setup
except ImportError:
    from distutils.core import setup

之后尝试找到一种方法来编写可由setuptoolsdistutils安装的设置。这通常包括各种容易出错的依赖项检查方法,因为distutils不支持设置函数中的依赖项。

为什么人们仍然需要额外的努力来支持distutils - setuptools是不是标准库中唯一的原因? distutils的优点是什么?编写仅支持setuptools setup.py 文件有任何缺点。

4 个答案:

答案 0 :(得分:68)

看看这个问题。它很好地解释了所有包装方法,并可能在某种程度上帮助回答您的问题:Differences between distribute, distutils, setuptools and distutils2?

  

Distutils 仍然是Python中打包的标准工具。它包含在标准库(Python 2和Python 3.0到3.3)中。它对于简单的Python发行版很有用,但缺少功能。它介绍了可以在setup.py脚本中导入的distutils Python包。

     开发

Setuptools 是为了克服Distutils'限制,并未包含在标准库中。它引入了一个名为easy_install的命令行实用程序。它还介绍了可以在setup.py脚本中导入的setuptools Python包,以及可以在代码中导入的pkg_resources Python包,用于查找随分发安装的数据文件。它的一个问题是它对distutils Python包进行了修补。它应该与pip一起使用。最新版本于2013年7月发布。

所以,正如你所看到的那样,setuptools应该优先于distutils,我会看到你的问题来自哪里,但我不会看到distutils很快失去支持,因为,简单地说,它在许多情况下被使用与一些流行的遗产计划。而且您可能知道在遗留程序中更改这些类型的东西可能会非常麻烦并且会遇到很多问题,例如不兼容性,这会导致开发人员不得不重写源代码。所以有这个,而且distutils是标准python库的一部分,而setuptools则不是。所以,如果你正在创建一个python程序,在这个时代,使用setuptools,但请记住,如果没有distutils,setuptools将永远不会存在。

答案 1 :(得分:11)

  

是setuptools不在标准库中的唯一原因

这是一个原因。以下内容直接来自NumPy setup.py

if len(sys.argv) >= 2 and ('--help' in sys.argv[1:] or
        sys.argv[1] in ('--help-commands', 'egg_info', '--version',
                        'clean')):
    # Use setuptools for these commands (they don't work well or at all
    # with distutils).  For normal builds use distutils.
    try:
        from setuptools import setup
    except ImportError:
        from distutils.core import setup

所以NumPy更喜欢setuptools,如果能找到的话。但是SciPy曾经这样做,直到patched在某些情况下更喜欢distutils。引用提交日志:

Setuptools sets mode +x on the test scripts, so that Nose refuses to run
them. Better not do that.

当然,setuptoolsdistribute之间的merger应该在适当的时候解决所有这些问题,但许多软件包仍然需要支持Python 2.6安装。

答案 2 :(得分:9)

我们仍然谈论和使用distutils有几个原因,即使setuptools毫无疑问是更好的工具集。

首先,到处都有distutils。如果您希望构建一个模块以便与他人共享,并且没有任何复杂的要求,则可以保证在您的工作机器上可用。如果您必须支持旧版本的python,或者您发现自己在不熟悉的环境中工作,这一点尤为重要。

其次,setuptools为distutils提供了增强功能。因此,它是在distutils工具集之后建模的,并从那里获取所有结构。 setuptools的文档假设读者熟悉distutils并且只记录它如何增强基本工具集。你可以想到,distutils定义了方言,而setuptools则增强了这种方言。

我对新项目的个人方法是从假设我将使用distutils开始。只有当项目增长到需要setuptools的功能时才进行升级。 setuptools是distutils的替代品,它对我的​​setup.py进行了单行更改。

答案 3 :(得分:7)

基本上,这是由于责任分工。

setuptools不是Python标准库的一部分,因为它由第三方而不是Python核心团队维护。这意味着,除其他外:

  • 核心测试套件不涵盖它,核心功能不依赖它
  • 它不是本身为附加模块设置核心标准(它们的位置,导入方式,C扩展的二进制接口等)。
  • 它独立于Python版本更新和发布

实际上,核心团队缩小了distutils的范围,为自己保留了“核心标准”和“最少必要的编译”部分,同时保留了所有其他内容 strong>(扩展编译器/包格式/支持)到第三方。以前覆盖这些“扩展部分”的代码是陈旧的,以便向后兼容。

来自Distributing Python Modules — Python 2.7.12 documentation

  

虽然distutils的直接使用正在逐步取消,但它仍然奠定了基础   当前包装和配送基础设施的基础,   它不仅仅是标准库的一部分,还有它的名字   以其他方式存在(例如过去常用的邮件列表的名称)   协调Python包装标准开发)。

其他操作系统的软件包同样可能会单独提供setuptoolspip - 出于上述原因

  • 并且因为它们不是必需的 - 或者甚至对可维护性有害 - 当系统上已经有另一个包管理器时。