使用pyproject.toml时如何仅在一处指定版本?

Hat*_*ind 2 dry version python-3.x python-poetry

我的包版本在两个地方定义:

  • __version__ = 1.2.3mypackage/__init__.py
  • version = "1.2.3"pyproject.toml(我正在使用诗歌)

每当我遇到烦人而不是 DRY 的版本时,我都必须更新两者。有没有办法让 Python 从 TOML 读取版本,或者让 TOML 从 Python 读取版本?

Alw*_*win 15

这段代码对我有用:

import importlib.metadata

__version__ = importlib_metadata.version(__package__ or __name__)
Run Code Online (Sandbox Code Playgroud)

但是,这仅在已使用 pip 或诗歌安装包的情况下才有效。

在较新的版本上(点而不是下划线):

__version__ = importlib.metadata.version(__package__ or __name__)
Run Code Online (Sandbox Code Playgroud)

  • 这适用于可编辑安装吗?从我所看到的情况来看,当 pyproject.toml 中的可编辑安装和更改版本不会得到反映时? (3认同)

fra*_*ans 7

也许过于复杂,但为了不将已安装的包版本与本地徘徊的实例混淆,我使用以下代码:


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()
Run Code Online (Sandbox Code Playgroud)

给我1.2.23已安装的软件包或类似的东西1.3.42-dev (at /project/location)


fin*_*mer 5

安装项目后 - 无论是在可编辑模式下poetry install还是从轮子 - 您可以通过importlib.metadataimportlib_metadata对于python <3.8)访问多个元数据。

因此,仅保留版本pyproject.toml并在您的 python 代码中使用它:

import importlib.metadata

__version__ = importlib.metadata.version("mypackage")
Run Code Online (Sandbox Code Playgroud)