Following system colour scheme - Python 增强提案 Selected dark colour scheme - Python 增强提案 Selected light colour scheme - Python 增强提案

Python增强提案

PEP 423 – 打包相关的命名规范和方案

作者:
Benoit Bryon <benoit at marmelune.net>
讨论邮件列表:
Distutils-SIG 邮件列表
状态:
已延期
类型:
信息性
主题:
打包
创建日期:
2012年5月24日
更新历史:


目录

摘要

本文档涉及

  • Python项目的名称,
  • 要分发的Python包或模块的名称,
  • 命名空间包。

它为发布者提供指导和方案

PEP延期

对该PEP的进一步考虑已被推迟,至少要等到PEP 426(包元数据2.0)和相关的更新解决之后。

术语

参考Python文档中的打包术语

与其他PEP的关系

  • PEP 8处理代码风格指南,包括Python包和模块的名称。它涵盖了包/模块名称的语法。
  • PEP 345处理打包元数据,并定义了packaging.core.setup()函数的name参数。
  • PEP 420处理命名空间包。它将命名空间包的支持引入Python核心。之前,命名空间包是由外部库实现的。
  • PEP 3108处理应用于标准库的Python 2.x和Python 3.x之间的转换:一些模块将被删除,一些将被重命名。它指出命名约定很重要,并且是转换计划的一个示例。

概述

以下总结了选择名称时应遵循的指南列表

如有疑问,请咨询

如果您在阅读本文档后仍不确定,请在IRC或邮件列表上咨询Python社区

顶级命名空间与代码所有权相关

这有助于避免项目名称之间的冲突。

所有权可以是

  • 个人。例如:gp.fileupload由Gael Pasgrimaud拥有和维护。
  • 组织。例如
    • zest.releaser由Zest Software拥有和维护。
    • Django由Django软件基金会拥有和维护。
  • 小组或社区。例如:sphinx由Sphinx项目的开发者维护,而不仅仅是由其作者Georg Brandl维护。
  • 与另一个包相关的小组或社区。例如:collective.recaptcha由其作者David Glick(Groundwire)拥有。但是,“collective”命名空间由Plone社区拥有。

尊重所有权

在使用命名空间之前,请了解其用途。

除非获得明确授权,否则不要插入您不拥有的命名空间。

如有疑问,请咨询.

例如,不要插入“django.contrib”命名空间,因为它由Django的核心贡献者管理。

项目作者可以定义例外情况。请参阅下面的组织社区贡献

此外,此规则也适用于非Python项目。

例如,不要使用“apache”作为顶级命名空间:“Apache”是现有项目的名称(在“Apache”的情况下,它也是一个商标)。

私有(包括闭源)项目使用命名空间

…因为私有项目由某人拥有。因此,请应用所有权规则

对于内部/客户项目,请使用您的公司名称作为命名空间。

此规则适用于闭源项目。

例如,如果您正在为“Python Sport”公司创建一个名为“climbing”的项目:请使用“pythonsport.climbing”名称,即使它是闭源的。

单个项目使用命名空间

…因为它们由个人拥有。因此,请应用所有权规则

即使项目具有“内部”或“个人”名称,将其作为开源发布也并无不妥。

如果项目发展到作者希望更改所有权的程度(即项目不再属于个人),请记住重命名项目很容易

社区拥有项目可以避免使用命名空间包

如果您的项目足够通用(即它不是对其他产品或框架的贡献),您可以避免使用命名空间包。基本条件通常是您的项目由一个专门负责此项目的团队(即开发团队)拥有。

只有当您确实打算将代码归社区所有时,才使用“共享”命名空间。

例如,sphinx项目属于Sphinx开发团队。无需在内部创建一个名为“sphinx”的命名空间包,其中只包含一个名为“sphinx.sphinx”的项目。

如有疑问,请使用个人/组织命名空间

如果您的项目确实是实验性的,最佳选择是使用个人或组织命名空间

  • 它允许项目尽早发布。
  • 如果项目被放弃,它不会阻塞名称。
  • 它不会阻止将来的更改。当项目变得成熟并且没有理由保留个人所有权时,仍然可以重命名项目

使用单个名称

每个项目只分发一个包(或一个模块),并使用包(或模块)名称作为项目名称。

  • 它避免了项目名称和分发包或模块名称之间可能产生的混淆。
  • 它使名称保持一致。
  • 它很明确:当一个人看到项目名称时,他可以猜测包/模块名称,反之亦然。
  • 它还限制了包/模块名称之间的隐式冲突。通过使用单个名称,当您将项目名称注册到PyPI时,您还执行了基本的包/模块名称可用性验证。

    例如,pipelinepython-pipelinedjango-pipeline都分发了一个名为“pipeline”的包或模块。因此,安装其中的两个会导致错误。如果这些发行版使用单个名称,则不会出现此问题。

  • 包名:“kheops.pyramid”,即import kheops.pyramid
  • 项目名称:“kheops.pyramid”,即pip install kheops.pyramid

  • 包名:“kheops”
  • 项目名称:“KheopsPyramid”

注意

由于历史原因,PyPI包含许多项目和分发包/模块名称不同的发行版。

多个包/模块应该很少见

从技术上讲,Python发行版可以提供多个包和/或模块。有关详细信息,请参阅安装脚本参考

有些发行版确实如此。例如,setuptoolsdistribute都在除了各自的“setuptools”和“distribute”包之外,还声明了“pkg_resources”、“easy_install”和“site”模块。

将此用例视为例外情况。在大多数情况下,您不需要此功能。因此,分发应该一次只提供一个包或模块。

不同的名称应该很少见

使用单个名称规则的一个显著例外是,当您明确需要不同的名称时。

例如,Pillow 项目提供了原始 PIL 分发的替代方案。这两个项目都分发了一个名为“PIL”的包。

将此用例视为例外情况。在大多数情况下,您不需要此功能。因此,分发包名称应等于项目名称。

遵循PEP 8中关于包和模块名称的语法规范

PEP 8 适用于 Python 包和模块的名称。

如果您使用单个名称PEP 8 也适用于项目名称。例外情况是命名空间包,其中项目名称需要使用点。

选择易记的名称

关于项目名称,有一点很重要,那就是它必须令人难忘。

例如,celery 不是一个有意义的名称。起初,并不明显它与消息队列有关。但它令人难忘,部分原因是它可以用来为 RabbitMQ 服务器提供数据。

选择有意义的名称

问问自己“我将如何用一句话描述这个名称的用途?”,然后“仅凭名称,是否有人能猜到它的用途?”。

例如,DateUtils 是一个有意义的名称。很明显,它与日期相关的实用程序有关。

当您使用命名空间时,请尝试使每个部分都具有意义。

使用打包元数据

将项目名称视为 PyPI 上的唯一标识符。

  • 这些标识符必须保持人类可读性很重要。
  • 如果这些标识符有意义则更好。
  • 但标识符的主要目的不是对项目进行分类或描述。

分类器和关键词元数据用于对分发进行分类。摘要和描述元数据用于描述项目。

例如,有一个“Framework :: Twisted”分类器。即使名称非常异构(它们不遵循特定的模式),我们也能得到列表。

为了组织社区贡献,关于名称和命名空间的约定很重要,但关于元数据的约定应该更加重要。

例如,我们可以在许多地方找到 Plone 端口。

  • plone.portlet.*
  • collective.portlet.*
  • collective.portlets.*
  • collective.*.portlets
  • 一些与供应商相关的项目,例如“quintagroup.portlet.cumulus”
  • 甚至一些名称中没有出现“portlet”模式的项目。

即使 Plone 社区有约定,使用名称对分发进行分类也是不合适的。通过根据名称过滤,不可能获得提供 Plone 端口的所有分发的完整列表。但如果所有这些分发都使用“Framework :: Plone”分类器和“portlet”关键词,则可以实现。

避免嵌套过深

Python 之禅 说“扁平胜于嵌套”。

两级几乎总是足够

不要在深度嵌套的层次结构中定义所有内容:您最终会得到像“pythonsport.common.maps.forest”这样的项目和包。这种类型的名称既冗长又笨拙(例如,如果您从包中导入了许多内容)。

此外,随着不同包之间的界限变得模糊,大型层次结构往往会随着时间的推移而崩溃。

共识是,最好使用两级嵌套。

例如,我们有plone.principalsource 而不是 plone.source.principal 或类似的东西。名称更短,包结构更简单,并且在这里进行三级嵌套几乎没有什么好处。将所有“核心 Plone”源(源是一种词汇表)放入 plone.source.* 命名空间中是不切实际的,部分原因是一些源是其他包的一部分,部分原因是源已经存在于其他地方。如果我们创建了一个新的命名空间,它将从一开始就使用不一致。

是:“pyranha”

是:“pythonsport.climbing”

是:“pythonsport.forestmap”

否:“pythonsport.maps.forest”

只使用一级表示所有权

不要使用 3 个级别在社区命名空间中设置个人/组织所有权。

例如,让我们考虑一下

  • 您正在连接到一个社区命名空间,例如“collective”。
  • 并且您希望添加一个更严格的“所有权”级别,以避免在社区内部发生冲突。

在这种情况下,**最好将最严格的所有权级别用作第一级。**

例如,“collective”是“gergovie”所属的主要社区命名空间,“vercingetorix”是“gergovie”作者的名称。

否:“collective.vercingetorix.gergovie”

是:“vercingetorix.gergovie”

不要使用命名空间级别进行分类

改用使用打包元数据

不要使用超过3级

从技术上讲,您可以创建深度嵌套的层次结构。但是,在大多数情况下,您不需要它。

注意

即使是命名空间标准化的社区,也不会使用超过 3 个级别。

在PyPI上注册名称

PyPI 是 Python 社区分发的中心位置。因此,它也是注册项目和包名称的地方。

有关详细信息,请参阅在软件包索引中注册

方案

以下食谱将帮助您遵循上述指南和约定。

如何检查名称可用性?

在选择项目名称之前,请确保它尚未在以下位置注册

  • PyPI
  • 仅此而已。PyPI 是唯一官方场所。

例如,您还可以检查各种位置(例如流行的代码托管服务),但请记住,PyPI 是您在 Python 社区中**注册**名称的唯一场所。

这就是为什么您需要使用 PyPI 注册名称很重要的原因。

还要确保已分发包或模块的名称尚未注册

使用单个名称”规则也有助于避免与包名称冲突:如果项目名称可用,那么包名称也很有可能可用。

如何重命名项目?

重命名项目是可能的,但请记住,这会导致一些混乱。因此,请特别注意 README 和文档,以便用户了解发生了什么。

  1. 首先,**不要从 PyPI 中删除旧版分发包**。因为一些用户可能正在使用它们。
  2. 复制旧项目,然后更改名称(项目和包/模块)。至少要注意以下方面:
    • 打包文件,
    • 包含源文件的文件夹名称,
    • 文档,包括 README,
    • 代码中的导入语句。
  3. 在 setup.cfg 文件中为新分发包分配 Obsoletes-Dist 元数据。请参阅 关于 Obsolete-Dist 的 PEP 345setup.cfg 规范
  4. 发布重命名项目的最新版本,然后发布它。
  5. 编辑旧项目
    • 添加对新项目的依赖项,
    • 删除除打包内容之外的所有内容,
    • 在 setup 脚本中添加 Development Status :: 7 - Inactive 分类器,
    • 发布一个新版本。

因此,旧版包的用户

  • 可以继续使用旧版分发包的已弃用版本,
  • 可以升级到旧版分发包的最后一个版本,该版本为空…
  • …并自动下载新分发包作为旧版分发包的依赖项。

发现旧项目的用户会看到它处于非活动状态。

改进PyPI上重命名项目的处理方式

如果许多项目遵循 重命名指南,那么许多旧版分发包将具有以下特征

  • Development Status :: 7 - Inactive 分类器。
  • 最新版本为空,除了打包内容。
  • 最新版本“重定向”到另一个分发包。例如,它对重命名项目只有一个依赖项。
  • 在较新的分发包中被引用为 Obsoletes-Dist

因此,将能够检测到重命名的项目并提高 PyPI 的可读性。以便用户可以专注于活动分发包。但是此功能现在不需要。没有紧急情况。本文档中不会介绍。

如何在现有项目上应用命名指南?

**现有项目没有义务重命名**。出于显而易见的原因,选择权留给项目作者和维护者。

但是,邀请项目作者

关于当前命名的说明

首先,重要的是您要说明当前的选择

  • 问问自己“我为什么选择当前名称?”,然后记录下来。
  • 如果与本文档中提供的指南存在差异,您应该告诉您的用户。
  • 如果可能,至少为了记录在案,在项目的错误跟踪器中创建问题。然后您可以自由地稍后解决它们,或者可能将其标记为“wontfix”。

旨在接收社区贡献的项目也应该组织社区贡献

推广迁移

每个 Python 开发人员都应该在可能的情况下迁移,或者在各自的社区中推广迁移。

在您的项目中应用这些指南,然后社区将看到它是安全的。

特别是,“领导者”(例如热门项目的作者)很有影响力,他们拥有权力,因此对社区负有责任。

在热门项目中应用这些指南,然后社区也将采用这些约定。

**项目在发布新(主要)版本时应推广迁移**,特别是如果此版本引入了对 Python 3.x、新的标准库打包或命名空间包的支持

机会

随着 Python 3.3 的开发

  • 许多项目与 Python 3.x 不兼容。这包括“大型”产品或框架。这意味着许多项目将不得不进行迁移以支持 Python 3.x。
  • 打包(又名 distutils2)已准备就绪。发布后,将邀请项目迁移并使用新的打包方式。
  • PEP 420 为 Python 带来了命名空间包的官方支持。

这意味着大多数活跃的项目都应该在明年(几年内)迁移以支持 Python 3.x、新的打包方式或新的命名空间包。

这样的机会是独一无二的,并且不会很快再次出现!因此,让我们尽快(即**现在**)引入和推广命名约定。

参考文献

其他背景资料

参考文献和脚注


来源:https://github.com/python/peps/blob/main/peps/pep-0423.rst

上次修改时间:2023-09-09 17:39:29 GMT