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

setuptools vs. distutils: why is distutils still a thing?

python有一段混乱的工具历史,可以用来打包和描述项目:这些工具包括标准库中的distutilsdistributedistutils2setuptools等。看来,为了支持setuptoolsdistributedistutils2已经停止使用,这留下了两个竞争标准。

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

python packaging用户指南[1]现在建议:

Use setuptools to define projects and create Source Distributions.

并解释:

Although you can use pure distutils for many projects, it does not support defining dependencies on other projects and is missing several convenience utilities for automatically populating package metadata correctly that are provided by setuptools. Being outside the standard library, setuptools also offers a more consistent feature set across different versions of Python, and (unlike distutils), setuptools will be updated to produce the upcoming"Metadata 2.0" standard formats on all supported versions.

Even for projects that do choose to use distutils, when pip installs such projects directly from source (rather than installing from a prebuilt wheel file), it will actually build your project using setuptools instead.

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

1
2
3
4
try:
    from setuptools import setup
except ImportError:
    from distutils.core import setup

然后尝试编写一个可以由setuptoolsdistutils安装的安装程序。这通常包括各种容易出错的依赖项检查方法,因为distutils不支持安装函数中的依赖项。

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


看看这个问题。它很好地解释了所有的打包方法,并在一定程度上帮助回答您的问题:distribute、distuils、setuptools和distuils2之间的差异?

Distutils is still the standard tool for packaging in Python. It is included in the standard library (Python 2 and Python 3.0 to 3.3). It is useful for simple Python distributions, but lacks features. It introduces the distutils Python package that can be imported in your setup.py script.

Setuptools was developed to overcome Distutils' limitations, and is not included in the standard library. It introduced a command-line utility called easy_install. It also introduced the setuptools Python package that can be imported in your setup.py script, and the pkg_resources Python package that can be imported in your code to locate data files installed with a distribution. One of its gotchas is that it monkey-patches the distutils Python package. It should work well with pip. The latest version was released in July 2013.

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


is the fact that setuptools is not in the standard library the only reason

这是一个原因。以下直接从numpy setup.py开始:

1
2
3
4
5
6
7
8
9
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。但后来西皮就这样做了,直到它被修补,在某些情况下更喜欢distutils。引用提交日志:

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

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


尽管SETUPTOOLS无疑是更好的工具集,但我们仍然讨论和使用distuils的原因有很多。

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

其次,SETUPTOOLS为distuils提供了增强功能。因此,它是根据distutils工具集建模的,并从中获取所有的结构。SETUPTOOLS的文档假定读者熟悉distuils,并且只记录它如何增强基本工具集。您可以认为distutils定义了方言,而setuptools增强了方言。

我对新项目的个人方法是从假设我将使用distutils开始的。只有当项目增长到需要安装工具的特性时,我才能进行升级。SETUPTOOLS是distutils的替代品,它是对my setup.py的一行更改。


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

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

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

    实际上,核心团队已经缩小了distuils的范围,为自己保留了"核心标准"和"最少必要的编译"部分,同时将所有超出这一范围的内容(扩展编译器/包格式/任何支持)留给第三方。以前覆盖这些"扩展部分"的代码由于向后兼容性而过时。

    分发python模块-python 2.7.12文档:

    While direct use of distutils is being phased out, it still laid the
    foundation for the current packaging and distribution infrastructure,
    and it not only remains part of the standard library, but its name
    lives on in other ways (such as the name of the mailing list used to
    coordinate Python packaging standards development).

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

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