【问题标题】:setuptools vs. distutils: why is distutils still a thing?setuptools vs. distutils:为什么 distutils 仍然存在?
【发布时间】:2014-10-09 20:31:48
【问题描述】:

Python 在可用于打包和描述项目的工具方面有着令人困惑的历史:这些工具包括标准库中的 distutilsdistributedistutils2setuptools(可能还有更多)。似乎 distributedistutils2 已停止使用,取而代之的是 setuptools,这留下了两个相互竞争的标准。

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

Python 打包用户指南[1] 现在推荐:

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

并解释:

虽然您可以将纯distutils 用于许多项目,但它不支持定义对其他项目的依赖关系,并且缺少setuptools 提供的用于正确自动填充包元数据的几个便利实用程序。在标准库之外,setuptools 还为不同版本的 Python 提供了更一致的功能集,并且(与 distutils 不同),setuptools 将被更新以在所有支持的版本上生成即将推出的“元数据 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 不支持 setup 函数中的依赖项。

为什么人们仍在努力支持distutils - 这是setuptools 不在标准库中的唯一原因吗? distutils 的优点是什么,编写只支持 setuptoolssetup.py 文件有什么缺点。

【问题讨论】:

标签: python packaging setuptools distutils


【解决方案1】:

看看这个 SO 问题。它很好地解释了所有的打包方法,并且可能在一定程度上帮助回答您的问题: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 将永远存在。

【讨论】:

  • “Distutils 仍然是 Python 打包的标准工具。”与 Python 打包用户指南相矛盾。
  • 我不相信,它是否明确表示 setuptools 是标准。另请注意,该短语是从我提供的网站中引用的,因此,这些不是我的话。然而,这是我和许多其他人都同意的观点。
  • 我奖励了你,因为社区似乎同意你的观点。不幸的是,这个问题并没有像我希望的那样受到关注。
  • easy_install 是我拒绝 setuptools 的主要原因 - 在使用它的软件包中对我来说这是一个巨大的问题来源(更容易重新打包)。其他功能还可以。
【解决方案2】:

是 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 安装。

【讨论】:

  • distributesetuptools 的一个分支,现在合并回来。
【解决方案3】:

我们仍在谈论和使用 distutils 有几个原因,尽管 setuptools 无疑是更好的工具集。

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

其次,setuptools 提供了对 distutils 的增强。因此,它以 distutils 工具集为模型,并从那里获取它的所有结构。 setuptools 的文档假定读者熟悉 distutils,并且仅记录它如何增强基本工具集。你可以认为 distutils 定义了方言,而 setuptools 增强了方言。

我对新项目的个人方法是假设我将使用 distutils。只有当项目发展到需要 setuptools 的功能时,我才会进行升级。 setuptools 是 distutils 的直接替代品,它是对我的 setup.py 的单行更改。

【讨论】:

  • 感谢您的回答。我认为可用性参数不可能那么重要,因为 setuptools 安装可以引导。我看到如果 distutils 提供足够的功能 - 使用它确实有意义。但在我看来,混合 distutils 和 setuptools 并不是实现目标的一种非常干净的方式。虽然,@larsmans 在他的回答中显示了 setuptools 的一些困难,这些困难迫使 distutils 用于某些任务。
【解决方案4】:

基本上是分工造成的。

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

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

实际上,核心团队缩小了 distutils 的范围,为自己保留了“核心标准”和“最少必要的编译”部分同时保留了除此之外的所有内容 strong>(扩展编译器/包格式/任何支持)到第 3 方。之前覆盖这些“扩展部分”的代码已过时,以实现向后兼容性。

来自Distributing Python Modules — Python 2.7.12 documentation

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

其他操作系统的软件包也可能分别提供setuptoolspip - 出于上述原因

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

【讨论】:

    猜你喜欢
    • 2016-09-17
    • 2010-11-28
    • 2015-05-16
    • 2021-06-19
    • 2010-12-28
    • 2011-09-14
    • 2011-11-23
    相关资源
    最近更新 更多