4. 创建源分发

一个简单的例子部分所示,您使用 sdist 命令创建源分发。在最简单的情况下,

python setup.py sdist

(假设您未在设置脚本或配置文件中指定任何 sdist 选项), sdist 为当前平台创建默认格式的存档。默认格式是在 Unix 上为 gzip 压缩的 tar 文件(.tar.gz),在 Windows 上则为 ZIP 文件。

您可以使用--formats选项指定任意多种格式,例如:

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

创建一个压缩的 tarball 和一个 zip 文件。可用格式为:

FormatDescriptionNotes
zipzipfile(.zip)(1),(3)
gztargzip 压缩的 tar 文件(.tar.gz)(2)
bztarbzip2 编辑的 tar 文件(.tar.bz2)
ztar压缩的 tar 文件(.tar.Z)(4)
tartar 文件(.tar)

Notes:

  • Windows 默认

  • 在 Unix 上默认

  • 需要外部 zip Util 或zipfile模块(自 Python 1.6 以来为标准 Python 库的一部分)

  • 需要 compress 程序。

在 Unix 下使用任何tar格式(gztarbztarztartar)时,可以指定将为归档的每个成员设置的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.txt(或README),setup.py(或您所说的设置脚本)和setup.cfg

  • package_data元数据匹配的所有文件。参见安装包数据

  • data_files元数据匹配的所有文件。参见安装其他文件

有时这足够了,但是通常您会希望指定其他文件来分发。典型的方法是编写一个Lists 模板,默认情况下称为MANIFEST.in。Lists 模板只是有关如何生成 Lists 文件MANIFEST的指令列表,这是要包含在源分发中的文件的确切列表。 sdist 命令处理该模板,并根据其指令和在文件系统中找到的内容生成 Lists。

如果您喜欢滚动自己的 Lists 文件,则格式很简单:每行一个文件名,仅常规文件(或指向它们的符号链接)。如果您提供自己的MANIFEST,则必须指定所有内容:上述默认文件集在这种情况下不适用。

在 2.7 版中进行了更改:将生成的现有MANIFESTMANIFEST.insetup.py之一进行比较,无需 sdist 即可重新生成。

在版本 2.7.1 中更改:MANIFEST文件以 Comments 开头,指示已生成文件。没有此 Comments 的文件不会被覆盖或删除。

在 2.7.3 版中进行了更改:如果不存在MANIFEST.in,则 sdist 将读取MANIFEST文件,就像在 2.7 之前一样。

有关语法参考,请参见MANIFEST.in 模板部分。

4.2. 与 Lists 相关的选项

sdist 命令的正常操作过程如下:

  • 如果 Lists 文件(默认为MANIFEST)存在并且第一行没有 Comments,表明它是从MANIFEST.in生成的,则按原样使用它,不更改

  • 如果 Lists 文件不存在或先前已自动生成,请阅读MANIFEST.in并创建 Lists

  • 如果MANIFESTMANIFEST.in都不存在,则仅使用默认文件集创建 Lists

  • 现在使用MANIFEST中的文件列表(刚生成或读入)来创建源分发存档

有几个选项可以修改此行为。首先,使用--no-defaults--no-prune禁用标准的“包含”和“排除”集。

其次,您可能只想(重新)生成 Lists,但不创建源分发:

python setup.py sdist --manifest-only

4.3. MANIFEST.in 模板

可以在项目中添加MANIFEST.in文件,以定义要包含在 sdist 命令构建的发行版中的文件列表。

运行 sdist 时,它将查找MANIFEST.in文件并对其进行解释以生成MANIFEST文件,该文件包含将包含在软件包中的文件列表。

当默认文件列表不足时,可以使用此机制。 (请参见指定要分发的文件)。

4.3.1. Principle

Lists 模板每行有一个命令,其中每个命令指定一组文件,这些文件包括在源分发中或从源分发中排除。例如,让我们看一下 Distutils 自己的 Lists 模板:

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

含义应该非常清楚:包括分发根中与*.txt匹配的所有文件,在examples目录下与*.txt*.py匹配的所有文件,并排除与examples/sample?/build匹配的所有目录。所有这些操作都是在标准包含集之后完成的,因此您可以使用 Lists 模板中的明确说明从标准集中排除文件。 (或者,您可以使用--no-defaults选项完全禁用标准集.)

Lists 模板中命令的 Sequences 很重要:首先,我们具有如上所述的默认文件列表,并且模板中的每个命令都将添加到该文件列表或从中删除。完全处理 Lists 模板后,我们将删除不应包含在源代码分发中的文件:

  • Distutils“构建”树中的所有文件(默认为build/)

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

现在,我们有了完整的文件列表,将其写入 Lists 以供将来参考,然后用于构建源分发存档。

您可以使用--no-defaults选项禁用默认的包含文件集,也可以使用--no-prune禁用标准排除集。

按照 Distutils 自己的 Lists 模板,让我们跟踪 sdist 命令如何构建要包括在 Distutils 源代码分发中的文件列表:

  • distutilsdistutils/command子目录中包含所有 Python 源文件(因为在安装脚本的packages选项中提到了与这两个目录相对应的软件包,请参见编写安装脚本)

  • 包括README.txtsetup.pysetup.cfg(标准文件)

  • 包含test/test*.py(标准文件)

  • 在发布根目录中包含*.txt(这将再次找到README.txt,但稍后会删除此类冗余)

  • examples下的子树中包含与*.txt*.py匹配的任何内容,

  • 排除子树中所有与examples/sample?/build匹配的目录开始的文件-这可能会排除前两个步骤包括的文件,因此,Lists 模板中的prune命令在recursive-include命令之后是很重要的

  • 排除整个build树以及任何RCSCVS.svn.hg.git.bzr_darcs目录

就像在安装脚本中一样,Lists 模板中的文件和目录名称应始终用斜杠分隔; Distutils 将负责将它们转换为您平台上的标准表示形式。这样,Lists 模板可跨 os 移植。

4.3.2. Commands

Lists 模板命令为:

CommandDescription
包括 pat1 pat2 ...包括与任何列出的模式匹配的所有文件
不包括 pat1 pat2 ...排除与任何列出的模式匹配的所有文件
递归包括 dir pat1 pat2 ...包括* dir *下与所有列出的模式匹配的所有文件
递归排除 dir pat1 pat2 ...排除* dir *下与所有列出的模式匹配的所有文件
global-include pat1 pat2 ...包括所有与源树匹配的文件,以及任何列出的模式
全局排除 pat1 pat2 ...排除与源树匹配的任何文件,以及任何列出的模式
prune dir排除* dir *下的所有文件
graft dir包括* dir *下的所有文件

这里的模式是 Unix 样式的“全局”模式:*匹配任何常规文件名字符序列,?匹配任何单个常规文件名字符,[range]匹配* range *中的任何字符(例如a-za-zA-Za-f0-9_.)。 “常规文件名字符”的定义是特定于平台的:在 Unix 上,除斜杠外,其他任何东西都可以;在 Windows 上,反斜杠或冒号除外。