7. 擴展 Distutils?

備注

這篇文檔是歷史遺留文檔,在 https://setuptools.readthedocs.io/en/latest/setuptools.html 上的 setuptools 文檔獨立涵蓋此處包含的所有相關(guān)信息之后,將不再單獨作為正式文檔保留。

Distutils 可以通過(guò)各種方式擴展。 大多數擴展都采用新命令或現有命令的替換形式。 例如,可以編寫(xiě)新命令以支持新的特定于平臺的包格式,但是可以修改現有命令的替換,以修改命令在包上的操作細節。

distutils 的大多數擴展都在想要修改現有命令的 setup.py 腳本中編寫(xiě);其中許多只是簡(jiǎn)單地在 .py 文件以外添加了一些應當被拷貝到包中的文件后綴以便使用。

大多部 distutils 命令的實(shí)現都是 distutils.cmd.Command 類(lèi)的子類(lèi)。 新增命令可直接繼承自 Command,而替換命令往往間接派生自 Command, 直接子類(lèi)化它們所替換的命令。 所有命令都要求自 Command 派生。

7.1. 集成新的命令?

有多種方法可將新的命令實(shí)現集成到 distutils 中。 最困難的一種是鼓動(dòng)在 distutils 自身內部包含新特性,并等待(以及要求)某個(gè) Python 版本提供該支持。 出于多種原因,這確實(shí)是相當難的。

對于大多數需求來(lái)說(shuō)最為常見(jiàn)并且可能最為合理的一種則是通過(guò)你自己的 setup.py 腳本來(lái)包含新的實(shí)現,然后讓 distutils.core.setup() 函數使用它們:

from distutils.command.build_py import build_py as _build_py
from distutils.core import setup

class build_py(_build_py):
    """Specialized Python source builder."""

    # implement whatever needs to be different...

setup(cmdclass={'build_py': build_py},
      ...)

如果新的實(shí)現必須通過(guò)特定的包來(lái)使用則此方式最為適宜,因為每個(gè)對這個(gè)包感興趣的人都將會(huì )需要有新的命令實(shí)現。

從 Python 2.4 開(kāi)始,還有第三個(gè)選項可用,其目標是允許添加支持現有 setup.py 腳本的新命令,而不需要修改 Python 安裝包。 這預計可允許第三方擴展提供對附加打包系統的支持,而相應命令又可用于任何 distutils 命令可被使用的地方。 新的配置選項 command_packages (命令行選項為 --command-packages) 可用來(lái)指定附加包,以在其中查找實(shí)現新增命令的模塊。 像所有 distutils 選項一樣,這可以通過(guò)命令行或配置文件來(lái)指定。 此選項只能在配置文件的 [global] 小節之中或在命令行的任何命令之前設置。 如果是設置在配置文件中,則它可被命令行設置重載;如果在命令行中將其設為空字符串則將會(huì )使用默認值。 此選項絕不應當在隨特定包提供的配置文件中設置。

這個(gè)新選項可被用來(lái)添加任意數量的包到查找命令實(shí)現的包列表;多個(gè)包名應當以逗號分隔。 當未指明時(shí),查找將只在 distutils.command 包中進(jìn)行。 但是當 setup.py 附帶 --command-packages distcmds,buildcmds 選項運行時(shí),distutils.command, distcmdsbuildcmds 包將按此順序被查找。 新的命令應當在與命名同名的模塊中由同名的類(lèi)來(lái)實(shí)現。 給定上述示例命令行選項,則命令 bdist_openpkg 可由類(lèi) distcmds.bdist_openpkg.bdist_openpkgbuildcmds.bdist_openpkg.bdist_openpkg 來(lái)實(shí)現。

7.2. 添加新的發(fā)布類(lèi)型?

創(chuàng )建發(fā)布(在 dist/ 目錄中的文件)的命令需要將 (command, filename) 二元組添加到 self.distribution.dist_files 以便 upload 可以將其上傳到 PyPI。 二元組中的 filename 不包含路徑信息而只有文件名本身。 在 dry-run 模式下,二元組仍然應當被添加以表示必須創(chuàng )建的內容。