我的包版本在两个地方定义:
__version__ = 1.2.3
在 mypackage/__init__.py
version = "1.2.3"
在pyproject.toml
(我正在使用诗歌)每当我更新版本时,我都必须更新这两个版本,这很烦人,而且不干。有没有办法让Python从TOML读取版本,或者让TOML从Python读取版本?
安装项目后 - 无论是通过
poetry install
在可编辑模式下还是通过滚轮 - 您可以通过 importlib.metadata
(对于 Python importlib_metadata
访问多个元数据)
< 3.8).因此,仅将版本保留在pyproject.toml
中,并在Python代码中使用它:
import importlib.metadata
__version__ = importlib.metadata.version("mypackage")
import importlib.metadata
__version__ = importlib_metadata.version(__package__ or __name__)
但是,这仅在已经使用 pip 或诗歌安装了软件包的情况下才有效。 在新版本上(点而不是下划线):
__version__ = importlib.metadata.version(__package__ or __name__)
from contextlib import suppress
import importlib.metadata
from pathlib import Path
def extract_version() -> str:
"""Returns either the version of installed package or the one
found in nearby pyproject.toml"""
with suppress(FileNotFoundError, StopIteration):
with open((root_dir := Path(__file__).parent.parent)
/ "pyproject.toml", encoding="utf-8") as pyproject_toml:
version = (
next(line for line in pyproject_toml if line.startswith("version"))
.split("=")[1]
.strip("'\"\n ")
)
return f"{version}-dev (at {root_dir})"
return importlib.metadata.version(__package__
or __name__.split(".", maxsplit=1)[0])
__version__ = extract_version()
给我
1.2.23
安装的软件包或类似
1.3.42-dev (at /project/location)
的评论中指出的那样,当未安装软件包时,这些方法会破坏 CI 管道等。为了与 @z33k 对这个问题的评论保持一致,一种解决方案是从 pyproject.toml
读取值。
作为包管理器,另一个解决方案是使用 poetry-bumpversion 插件,通过 poetry
的
version
命令来管理版本颠簸。例如,假设您有一个名为 widget
的包,其中 __version__
定义在 widget/__init__.py
中,其值与 pyproject.toml
的 version
的值相同。使用 poetry-bumpversion
插件,您可以添加[tool.poetry_bumpversion.file."widget/__init__.py"]
到
pyproject.toml
,然后
% poetry version patch
Bumping version from 0.7.9 to 0.7.10
poetry_bumpversion: processed file widget/__init__.py
% git diff -U0
diff --git a/widget/__init__.py b/widget/__init__.py
index 18c7cbf..9ff9982 100644
--- a/widget/__init__.py
+++ b/widget/__init__.py
@@ -1 +1 @@
-__version__ = "0.7.9"
+__version__ = "0.7.10"
diff --git a/pyproject.toml b/pyproject.toml
index 1b86c6e..5de1ce1 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -3 +3 @@ name = "widget"
-version = "0.7.9"
+version = "0.7.10"
@@ -55,0 +56,2 @@ tox = "^4.6.4"
+[tool.poetry_bumpversion.file."widget/__init__.py"]
+
project.toml
中,您可以通过不同的方式指定版本:
[tool.poetry]
中的版本:
[tool.poetry]
name = "my-package"
version = "0.1.0"
[project]
部分:
[project]
name = "my-package"
version = "2020.0.0"
下一步是您可能想查看已安装软件包的版本(例如通过
pip
或
poetry
)或您的应用程序。下一个:import importlib.metadata
version = importlib.metadata.version("my-package")
print(version)
此代码适用于已安装的软件包。要使其与您的项目一起使用,您应该使用
pip install -e .
或类似的东西安装它。
from pathlib import Path
import toml
version = "unknown"
# adopt path to your pyproject.toml
pyproject_toml_file = Path(__file__).parent / "pyproject.toml"
if pyproject_toml_file.exists() and pyproject_toml_file.is_file():
data = toml.load(pyproject_toml_file)
# check project.version
if "project" in data and "version" in data["project"]:
version = data["project"]["version"]
# check tool.poetry.version
elif "tool" in data and "poetry" in data["tool"] and "version" in data["tool"]["poetry"]:
version = data["tool"]["poetry"]["version"]
print(version)
toml