跳转到主要内容

Poetry插件,用于从__version__变量或Git标签动态提取包版本。

项目描述

Poetry版本插件

Test Publish Coverage Package version

Poetry插件,用于动态提取包版本

它可以读取文件__init__.py中的版本

# __init__.py

__version__ = "0.1.0"

或者,它可以从git tag读取版本,该标签通过GitHub发布或

$ git tag 0.1.0

🚨 请注意,这处于alpha阶段。请阅读下面的警告。

何时使用

这主要用于如果您正在构建一个供他人使用的包库,并且您想在不同于pyproject.toml的位置设置版本,但您仍然想保持一个单一的事实来源

在其他用例中,如使用Poetry管理本地应用程序环境,它将不会很有帮助。

如何使用

确保您有Poetry版本1.2.0a1或更高版本。如果您还没有安装它,请阅读下面的说明。

安装Poetry版本插件

将此插件安装到您的Poetry

$ poetry plugin add poetry-version-plugin

--> 100%

在初始化文件中设置版本号

将您的包版本设置在文件 __init__.py 中,例如

from .main import do_awesome_stuff, AwesomeClass

__version__ = "0.2.3"

然后编辑您的 pyproject.toml 文件,包含以下部分

[tool.poetry-version-plugin]
source = "init"

接下来,构建您的项目。输出将类似

$ poetry build
Using __init__.py file at my_awesome_package/__init__.py for dynamic version
Setting package dynamic version to __version__ variable from __init__.py: 0.1.9
Building my-awesome-package (0.1.9)
  - Building sdist
  - Built my-awesome-package-0.1.9.tar.gz
  - Building wheel
  - Built my-awesome-package-0.1.9-py3-none-any.whl

在Git标签中设置版本号

或者,要从Git标签提取版本号,添加一个部分

[tool.poetry-version-plugin]
source = "git-tag"

然后创建一个git标签,例如

$ git tag 0.1.3

在这种情况下,当构建您的项目时,输出将类似

$ poetry build
Git tag found, setting dynamic version to: 0.1.3
Building my-awesome-package (0.1.3)
  - Building sdist
  - Built my-awesome-package-0.1.3.tar.gz
  - Building wheel
  - Built my-awesome-package-0.1.3-py3-none-any.whl

pyproject.toml 中的版本号

目前(2021-05-24)Poetry需要在 pyproject.toml 中配置 version,即使您使用此插件也是如此。

当使用此插件时,该 version 配置不会使用,但Poetry仍然要求它在 pyproject.toml 中存在。

为了更明显地表明您没有使用该 version,您可以将其设置为 0

[tool.poetry]
name = "my-awesome-package"
version = "0"

这样,您将更容易注意到插件是否未安装,因为它将显示您正在构建一个版本为 0 的包,而不是动态设置的版本。

一个示例 pyproject.toml

一个简短的最小示例 pyproject.toml 可能看起来像

[tool.poetry]
name = "my-awesome-package"
version = "0"
description = ""
authors = ["Rick Sanchez <rick@rick-citadel.com>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.6"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.poetry-version-plugin]
source = "init"

原因

默认情况下,Poetry期望您在 pyproject.toml 中设置包版本。在大多数情况下,这都会工作。

但想象一下,您希望将包的版本暴露在 __version__ 变量中,以便用户可以执行类似以下操作

import my_awesome_package
print(my_awesome_package.__version__)

您可以手动编写 __version__ 变量,并自行处理与 pyproject.toml 之间的同步,这非常 容易出错

目前官方的解决方案是不重复值是使用 importlib.metadata

但是,该模块仅在Python 3.8及以上版本中可用。因此,对于Python 3.7和3.6,您必须将作为包依赖项的回滚版本安装

[tool.poetry.dependencies]
importlib-metadata = {version = "^1.0", python = "<3.8"}

但是,当它们发布回滚版本的每个新版本时(目前为4.0.1),您必须更新它(或不必更新)。并且您的用户必须手动处理与任何其他依赖 importlib-metadata 的包之间的冲突,这可能有很多,因为许多包可能正在执行相同的操作(我处理过这种情况)。

另一种选择是不在 pyproject.toml 中对您的 importlib-metadata 的任何版本范围进行固定,并寄希望于最好。

然后,您的 __init__.py 必须包含使用它的代码,如下所示

# I don't want this extra complexity 😔
# And it doesn't work in Docker 🐋
try:
    import importlib.metadata as importlib_metadata
except ModuleNotFoundError:
    import importlib_metadata

__version__ = importlib_metadata.version(__name__)

但是,这段代码增加了您代码中的额外复杂性和逻辑,在每个包中都需要。

🚨 此外,这只在您的包安装在Python环境中时才有效。例如,如果只是将代码放入一个 容器 中,这对于Web应用和分布式系统来说很常见,那么它将不起作用。

此插件如何解决这个问题

使用此插件,您的包不依赖于 importlib-metadata,因此用户不需要处理冲突或额外的依赖项。

相反,需要安装此插件的构建系统(Poetry)。

这样可以避免您方面的额外代码复杂性、用户之间的依赖项冲突以及支持其他用例,例如直接在容器内部复制的代码。

从Git标签获取版本号

此外,此插件还可以从Git标签中提取版本号。

因此,您只需要在Git标签(例如GitHub发布)中创建每个版本,而不是将其写入代码。

然后,在持续集成(例如GitHub Actions)上构建包。然后此插件将从这个Git标签中获取包的版本。

安装Poetry 1.2.0a1

为此插件能够工作,您需要Poetry版本 1.2.0a1 或更高版本。

最近发布了Poetry 1.2.0a1.

您很可能已经安装了Poetry 1.1.x

第一步是卸载它

$ curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py -O
--> 100%

$ python get-poetry.py --uninstall
--> 100%

然后使用新安装程序安装新的 Poetry

$ curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/install-poetry.py -O
--> 100%

$ python install-poetry.py --preview
--> 100%

🔍 注意,新安装程序文件的名称是 install-poetry.py 而不是 get-poetry.py。另外,目前,您需要设置 --preview 才能安装 alpha 版本 1.2.0a1

您可以使用以下方法检查是否安装成功:

$ poetry --version
Poetry (version 1.2.0a1)

init 文件中的版本支持

当在您的 __init__.py 中使用 __version__ 变量时,您可以在该文件中包含更多逻辑,导入模块,并在该变量的声明上方和下方进行更多操作。

但是,其值必须是字面字符串,例如

___version___ = "0.2.0"

...而不是调用一个函数或类似的东西。

该变量必须是顶层变量,因此不能位于 if 语句或类似的语句中。

这在您的 __init__.py 中都是可以正常使用且受支持的

# __init__.py

# This is all valid 👍✅

from .main import do_awesome_stuff, AwesomeClass

awesome = AwesomeClass()

# Some comment explaining why this is commented out
# __version__ = "1.0.0"

__version__ = "0.2.3"

if __name__ == "__main__":
    awesome.run()

以下示例是有效且受支持的,并且它包括

  • 导入
  • 其他对象和变量
  • 注释
  • 注释中相同的字符串 __version__
  • 周围的 if 块

但是,这不受支持

# 🚨 Not supported

if 2 == 2:
    __version__ = "0.1.0

而且,这也不受支持

# 🚨 Not supported

def get_version():
    return "0.2.0"

__version__ = get_version()

插件的工作方式

当 Poetry 在构建包时运行插件,并在创建“包发行版”(例如,wheel)之前设置版本。

版本变量的工作方式

如果您在 pyproject.toml 中的 packages 配置中声明了包(单个包),则插件将使用该包的 __init__.py 来查找 __version__ 变量。

如果您没有 packages 配置,则插件将假设您有一个名为您项目的单个包,但在模块版本中(将 - 替换为 _)。因此,如果您的包是 my-awesome-project,则插件将使用位于 my_awesome_project/__init__.py 的文件来查找 __version__ 变量。

如果您使用 poetry new 命令创建新项目,则此文件结构是默认的,因此应该按预期工作。✨

插件内部的工作方式是通过解析 __init__.py 文件。使用 ast 标准模块读取 Python 的“抽象语法树”,并提取字符串的字面值。因此,它不会在 __init__.py 中执行代码,而只是将其作为 Python 代码进行读取。

插件不会尝试导入和执行该 __init__.py 文件,因为这可能需要额外的计算、外部依赖项等。它也不会尝试使用正则表达式提取 __version__,因为这可能会出错,例如,如果代码中某个地方(在注释或字符串中)有另一个 __version__

警告

🚨 请注意,这是在 alpha 阶段。支持插件的 Poetry 1.2.0a1 已于 2021-05-21 发布。我在 3 天后(2021-05-24)开始编写此插件。

在 Poetry 或此插件中可能会出现错误。因此,请在完全采用它用于敏感系统之前仔细尝试并测试它。

其工作方式可能会改变,具体的配置可能会改变。

此外,如果您发现以下部分不够直观

[tool.poetry-version-plugin]
source = "init"

并且

[tool.poetry-version-plugin]
source = "git-tag"

请告诉我哪种替代配置对您来说更有意义,更直观。

👍 好消息是,假设您正在构建用于随后上传到 PyPI 以供用户下载和使用的包,如果出现问题,最坏的情况是您无法构建新版本,直到问题得到解决或更改。但是,您的用户不应该受到影响。

发行说明

最新更改

  • ✏️ 在 README.md 中修复了拼写错误和改写。由 @Gl0deanR 提交的 PR #8

0.1.3

  • ✨ 改进了日志记录,添加了插件名称前缀。由 @tiangolo 提交的 PR #6
  • 🔧 更新 pyproject 元数据。PR #5@tiangolo 提交。
  • ✅ 修复覆盖率。PR #4@tiangolo 提交。
  • 📝 改进文档。PR #3@tiangolo 提交。
  • 🐛 修复 CI 测试。PR #1@tiangolo 提交。
  • 👷 修复 Latest Changes 动作,将分支设置为 main。PR #2@tiangolo 提交。

许可证

本项目受 MIT 许可协议约束。

下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源代码分发

poetry-version-plugin-dontuse-0.1.4.tar.gz (9.7 kB 查看哈希值)

上传时间 源代码

构建分发

poetry_version_plugin_dontuse-0.1.4-py3-none-any.whl (8.5 kB 查看哈希值)

上传时间 Python 3

由以下机构支持