Setuptools 与 distutils: 为什么 distutils 仍然是一个东西?

Python 有一段令人困惑的工具史,可以用来打包和描述项目: 这些工具包括标准库中的 distutilsdistributedistutils2setuptools(也许还有更多)。看来,distributedistutils2已经停产,取而代之的是 setuptools,这就留下了两个相互竞争的标准。

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

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

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

并解释说:

尽管您可以对许多项目使用纯 distutils,但是它不支持定义对其他项目的依赖关系,并且缺少一些方便的实用工具来正确地自动填充由 setuptools提供的包元数据。在标准库之外,setuptools 还为不同版本的 Python 提供了更加一致的特性集,而且(与 distutils不同) ,setuptools将被更新,以便在所有支持的版本上生成即将推出的“ Metadata 2.0”标准格式。

即使对于选择使用 distutils的项目,当 pip 直接从源代码安装此类项目(而不是从预构建的轮文件安装)时,它实际上也会使用 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文件有什么缺点吗。

53657 次浏览

Setuptools 不在标准库中的事实是唯一的原因

这是原因之一。以下是来自 笨蛋 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 过去常常这样做,直到 补丁在某些情况下更喜欢 distutils。引用提交日志:

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

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

看看这个问题。它很好地解释了所有的包装方法,并可能有助于在一定程度上回答你的问题: 分发、 distutils、 setuptools 和 distutils2之间的区别?

蒸馏酒仍然是用 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 包进行了修补。它应该与皮普很好的工作。最新版本于2013年7月发布。

所以,正如你所看到的 setuptools 应该优先于 distutils,我也明白你的问题来自哪里,但是我不认为 distutils 会很快失去支持,简单地说,它在许多情况下被用于一些流行的遗留程序。正如您可能知道的那样,在遗留程序中更改这些类型的内容可能是相当痛苦的,并且会带来相当多的问题,例如不兼容性,这将导致开发人员不得不重写源代码。因此,还有一个事实,即 distutils 是标准 Python 库的一部分,而 setuptools 不是。因此,如果您正在创建一个 Python 程序,在当今这个时代,使用 setuptools,但是请记住,如果没有 distutils,setuptools 就不会存在。

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

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

其次,setuptools 提供了对 distutils 的增强。因此,它是以 distutils 工具集为模型的,并从那里获取它的所有结构。Setuptools 的文档假设读者熟悉 distutils,并且只描述它如何增强基本工具集。您可以认为 distutils 定义了方言,setuptools 增强了该方言。

我对新项目的个人方法是从假设我将使用 distutils 开始。只有当项目发展到需要 setuptools 的特性时,我才会进行升级。Setuptools 是 distutils 的替代品,它是对 setup.py 的一行更改。

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

setuptools不是 Python 标准库的一部分,因为它是由第三方而不是 Python 核心团队维护的。也就是说:

  • 它不包含在核心测试套件中,也不被核心功能所依赖
  • 它没有为插件模块设定核心标准(它们的位置、导入方式、 C 扩展的二进制接口等等)。
  • 它是独立于 Python 版本更新和发布的

实际上,核心团队已经缩小了 distutils 的范围,为自己保留“核心标准”和“最低限度必要的编译”部分 除此之外的所有东西(扩展编译器/包格式/任何支持) 之前覆盖这些“扩展部分”的代码已经过时了向后兼容。

来自 分发 Python 模块ーー Python 2.7.12文档:

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

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

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