4. 创建源代码分发包

注解

这篇文档只有在 https://setuptools.readthedocs.io/en/latest/setuptools.html 上的 setuptools 文档独立涵盖此处包含的所有相关信息之前,才会单独保留。

一个简单的例子 一节所示,可以使用 sdist 命令来创建一个源代码分发包。 在最简单的场景下,:

python setup.py sdist

(假定你没有在设置脚本或配置文件中指定任何 sdist 选项),sdist 将创建基于当前平台的默认格式的归档。 在 Unix 上默认格式为 gzip 的 tar 文件,而在 Windows 上则为 ZIP 文件。

你可以使用 --formats 选项来指定任何你想要的格式,例如:

python setup.py sdist --formats=gztar,zip

创建一个 gzip 的 tar 文件和一个 zip 文件。 可用的格式有:

文件格式

描述

注释

zip

zip 文件 (.zip)

(1),(3)

gztar

gzip'ed tar 文件 (.tar.gz)

(2)

bztar

bzip2'ed tar 文件 (.tar.bz2)

(5)

xztar

xz'ed tar 文件 (.tar.xz)

(5)

ztar

压缩 tar 文件 (.tar.Z)

(4),(5)

tar

tar 文件 (.tar)

(5)

在 3.5 版更改: 添加了对 xztar 格式的支持

注释:

  1. 默认Windows

  2. 默认 Unix

  3. 需要有外部 zip 工具或 zipfile 模块(自 Python 1.6 起是标准 Python 库的一部分)

  4. 需要有 compress 程序。 请注意此格式计划要弃用并将在未来的 Python 版本中被移除。

  5. 已被 PEP 527 弃用; PyPI 只接受 .zip.tar.gz 文件。

当使用任意 tar 格式 (gztar, bztar, xztar, ztartar) 时,在 Unix 中你可以指定将为每个归档成员设置的 ownergroup 名称。

举例来说,如果你希望归档中所有文件均为 root 所有:

python setup.py sdist --owner=root --group=root

4.1. 指定要分发的文件

如果你没有显式提供文件列表(或如何生成该列表的说明),则 sdist 命令会将一个最小化默认集加入源代码分发版:

  • 通过 py_modulespackages 选项指明的所有 Python 源文件

  • ext_moduleslibraries 选项提及的所有 C 源代码文件

  • 通过 scripts 选项标识的脚本,参见 Installing Scripts

  • 任何看起来像是测试脚本的文件: test/test*.py (目前,Distutils 不会对测试脚本做除了将它们包括到源代码分发版以外的任何操作,但是在未来将会有一个测试 Python 模块分发版的标准)

  • 任何标准的 README 文件 (README, README.txtREADME.rst), setup.py (或任何你指定的安装脚本) 以及 setup.cfg

  • 所有匹配 package_data 元数据的文件。 参见 Installing Package Data

  • 所有匹配 data_files 元数据的文件。 参见 Installing Additional Files

有时这就足够了,但通常你还会希望指定要分发的额外文件。 实现这一点的通常方式是编写一个 声明模板,默认名称为 MANIFEST.in。 声明模板就是一个有关如何生成你的声明文件 MANIFEST 的指令列表,也就是要实际包括在你的源代码分发版中的文件的列表。 sdist 命令会处理这个模板并基于其指令及其在文件系统中的查找结果生成一个声明文件。

如果你想要制作你自己的声明文件,格式很简单:每行一个文件名,仅限常规文件。 如果你提供你自己的 MANIFEST,你必须指明一切:上面描述的默认集将不适用于这种情况。

在 3.1 版更改: 现有的已生成 MANIFEST 将被生成而无需 sdist 来将其修改时间与 MANIFEST.insetup.py 的修改时间进行比较。

在 3.1.3 版更改: MANIFEST 文件以一个表明它们已生成的注释开始。 没有这条注释的文件不会被覆盖或移除。

在 3.2.2 版更改: sdist 将在不存在 MANIFEST.in 时读取一个 MANIFEST 文件,如它以前所做的一样。

在 3.7 版更改: README.rst 现在已被包括在 distutils 标准 README 列表中。

声明模板每行都有一个命令,其中每个命令指定了一组源代码发布版中要包括或排除的文件。 举例来说,我们再次关注 Distutils 自己的声明模板:

include *.txt
recursive-include examples *.txt *.py
prune examples/sample?/build

其含义应当很清楚:包括发布在根目录中所有匹配 *.txt 的文件,在 examples 目录下任何位置上匹配 *.txt*.py 的所有文件,并排除匹配 examples/sample?/build 的所有目录。 所有这些操作都将在标准的包括集 之后 执行,因此你可以通过在声明模板中的显式指令来排除标准集中的文件。 (或者,你也可以使用 --no-defaults 选项来完全禁用标准集。) 在声明模板迷你语言中还有一些其他的可用命令;参见 创建源码发行包: sdist 命令 小节。

声明模板中命令的顺序是很重要的:在初始状态下,我们有如上所述的默认文件列表,而模板中的每个命令将在该文件列表中添加或移除条目。 一旦我们完全处理好声明模板,我们将再移除不应包括在源代码发布版中的文件:

  • Distutils "构建" 目录树中的所有文件 (默认值:file:build/)

  • 目录中所有名为 RCS, CVS, .svn, .hg, .git, .bzr_darcs 的文件

现在我们有了完整的文件列表,它已被写入声明以供将来引用,并随后用于构建源代码分发压缩 包。

你可以通过 --no-defaults 选项禁用默认的包括文件集,你还可以通过 --no-prune 禁用默认的排除文件集。

跟随 Distutils 自己的声明模板,让我们追踪' own manifest template, let's trace how the sdist 命令是如何构建要包括在 Distutils 源代码分发版中的文件列表的:

  1. 包括 distutilsdistutils/command 子目录中的所有 Python 源代码文件(因为与这两个目录对应的包在 setup 脚本的 packages 选项中被提及 --- 参见 编写安装脚本 一节)

  2. 包括 README.txt, setup.pysetup.cfg (标准文件)

  3. 包括 test/test*.py (标准文件)

  4. 包括分发根目录下的 *.txt (这将第二次找到 README.txt,但这样的冗余随后会被清除)

  5. 包括 examples 下所有子目录树中匹配 *.txt*.py 的任何文件,

  6. 排除从匹配 examples/sample?/build 的目录开始的子目录树中的所有文件 --- 这可能会排除之前两个步骤所包括的文件,因此重要的一点是声明模板中的 prune 命令应放在 recursive-include 命令之后

  7. 排除整个 build 目录树,以及任何 RCS, CVS, .svn, .hg, .git, .bzr and _darcs 目录

就像在设置脚本中一样,声明模板中的文件和目录名应当总是以斜杠分隔;Distutils 将会负责把它们转化为你的系统平台上的标准表示形式。 通过这种方式,声明模板将可跨操作系统移植。