[Python] uvとpoetry-dynamic-versioningでバージョン管理(2025年10月版)

GitGraphでバージョンタグを表示
Git Graphでバージョンタグを表示

Pythonの仮想環境管理やパッケージ管理はAstralのuv一つで日々の作業の大体のことができるようになってきましたが、2025年10月時点でうまくできていないことがあります。それは、Gitなどのバージョン管理システムに登録してあるバージョン番号を、ビルドしたパッケージに反映できていないことです。

uvにはuv-dynamic-versioningというプラグインがあるのですが、uv標準のビルドバックエンドではまだうまく動作しないように思います(hatchlingでは動作します)。そこで、uvのビルドバックエンドにPoetryを使って、バージョン管理システムに登録してあるバージョン番号をパッケージに反映できるようにします。

uvのビルドバックエンドをPoetryにするところからスタート

uvでよく使うコマンドを以下のページにまとめています。Pythonプロジェクトを新規作成するuv initでは--build-backend poetryを引数に追加してPoetryをビルドバックエンドに使うように説明しましたが、これが今回の記事の伏線😅になります。

ターミナルを開いて、ビルドバックエンドがPoetryのPythonプロジェクトを作成するコマンドを実行します。

cd <開発用フォルダーのルート>
# プロジェクト名は"SimpleWxApp"
uv init --python 3.11 --build-backend poetry SimpleWxApp

ここからはVisual Studio CodeやCursorなどのテキストエディタを使います。ターミナルからcode SimpleWxAppというコマンドを入力すると、Visual Studio CodeがSimpleWxAppを開きます。

以下はuv initが作成したpyproject.tomlの内容になります。なお、本記事を書き始めた時点でのuvのバージョンはv0.9.4です。書き終わった頃にはuvのバージョンが更新されているかもしれません😅

[project]
name = "simplewxapp"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
authors = [
    { name = "名前", email = "メールアドレス" }
]
requires-python = ">=3.11"
dependencies = []

[project.scripts]
simplewxapp = "simplewxapp:main"

[build-system]
requires = ["poetry-core>=2,<3"]
build-backend = "poetry.core.masonry.api"

参考までに、--build-backend poetryを指定せずに作成した場合のpyproject.tomlは、以下のように[build-system]の部分がuv_buildになっています。

poetryを使わない場合のpyproject.toml (uv init --packageで作成)
[project]
name = "simplewxapp"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
authors = [
    { name = "名前", email = "メールアドレス" }
]
requires-python = ">=3.11"
dependencies = []

[project.scripts]
simplewxapp = "simplewxapp:main"

[build-system]
requires = ["uv_build>=0.9.4,<0.10.0"]
build-backend = "uv_build"

poetry-dynamic-versioningを使うようにpyproject.tomlを変更

バージョン管理システムに登録するバージョン番号をPythonパッケージに反映するため、poetry-dynamic-versioningを使うようにpyproject.tomlを変更します。

[project]
# version行を消してdynamic行を追加
# version = "0.1.0"
dynamic = ["version"]

[build-system]
# poetry-dynamic-versioningを追加
requires = ["poetry-core>=2,<3", "poetry-dynamic-versioning>=1.0.0,<2.0.0"]
# poetry_dynamic_versioning.backendに変更
build-backend = "poetry_dynamic_versioning.backend"

# 以下のセクションを追加
[tool.poetry]
version = "0.0.0"

# 以下のセクションを追加
[tool.poetry-dynamic-versioning]
enable = true
  • [project]セクションのversion行を削除してdynamic = ["version"]を追加します。
  • 既存の[build-system]セクションを変更して、requirespoetry-dynamic-versioningを追加し、build-backendpoetry_dynamic_versioning.backendを指定します。
  • 新たに[tool.property]セクションと[tool.poetry-dynamic-versioning]セクションを追加します。
    • 参考までに、バージョンタグの数字が2桁になったとき(例えばv1.2.34)に、パッケージのバージョンへ反映できなかったことがあるため、[tool.poetry-dynamic-versioning]セクションにpattern = "(?P<base>\\d+\\.\\d+\\.\\d+)"という行を追加していたことがあります。
  • PyPIのドキュメントでは[tool.poetry.requires-plugins]セクションを追加する旨が説明されていますが、これは以下の説明のようにPoetryのコマンドラインインターフェイス(CLI)と統合するものらしいので、とりあえず外しておきます。

 When installed with the plugin feature (i.e., poetry-dynamic-versioning[plugin]), it also integrates with the Poetry CLI to trigger the versioning in commands like poetry build.

プログラムを実装してバージョンを取得してみる

uv init --build-backend(あるいは--package)でPythonプロジェクトを作成すると、フォルダーの中にファイルが以下のように配置されます。

<開発用フォルダーのルート>$ tree -a SimpleWxApp
SimpleWxApp/
├── .git
│   └── 省略
├── .gitignore
├── .python-version
├── pyproject.toml
├── README.md
└── src
    └── simplewxapp
        └── __init__.py

初期状態では、src/simplewxapp/__init__.pyにはサンプルのmain関数が入っています。このファイルを変更して、Pythonパッケージのバージョン番号を表示するwxPythonのGUIアプリを実装してみます。

ターミナルでwxPythonのパッケージをプロジェクトに追加して、src/simplewxapp/__init__.pyを書き換えます。

# Visual Studio Codeのターミナルの場合、cdコマンドは不要
cd SimpleWxApp
uv add wxPython
import wx
from importlib.metadata import version, metadata

package_name = metadata(__package__).get('Name') # type: ignore
version_number = version(package_name)

class MainFrame(wx.Frame):
    def __init__(self, *args, **kw):
        super().__init__(*args, **kw)
        panel = wx.Panel(self)
        sizer = wx.GridSizer(2, 1, gap=wx.Size(0, 32))
        sizer.Add(
            wx.StaticText(panel, label=package_name), 
            flag=wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_BOTTOM
        )
        sizer.Add(
            wx.StaticText(panel, label=f'Version {version_number}'), 
            flag=wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_TOP
        )
        panel.SetSizer(sizer)

def main() -> None:
    app = wx.App()
    main_frame = MainFrame(None, title='Example')
    main_frame.Show()
    app.MainLoop()

以下のコマンドを実行すると、wxPythonのウィンドウが開いて、Pythonパッケージ名とバージョン番号を表示します。

uv run simplewxapp
コミットがないときのバージョンは 0.0.0
コミットしていないときのバージョンは 0.0.0

今はまだバージョン管理システムにソースコードをコミットしていない状態なので、バージョン番号は0.0.0と表示されます。

バージョン管理システムでバージョン番号のタグを付ける

uvで作成したPythonプロジェクトはデフォルトでGitリポジトリが準備されます。--vcsオプションでバージョン管理システムを指定できるようですが、バージョン0.9.4ではgitnone(バージョン管理システム無し)だけ指定できるようになっています。

ターミナルからコマンド入力して、Gitリポジトリに作成したプログラムをコミットします。

# 作業フォルダーはSimpleWxAppフォルダー
git add .
git commit -m "initial commit"

次にバージョン番号のタグを付けます。

# git tag v1.2.34 でもOK
git tag -a v1.2.34 -m "バージョン 1.2.34"

この状態で、もう一度uv run simplewxappを実行すると、以下のようにgitに登録したバージョン番号が表示されるようになります。

コミットしてバージョン番号のタグを付けるとPythonパッケージに反映される
コミットしてバージョン番号のタグを付けるとPythonパッケージに反映される

ちなみに、コミットにバージョン番号のタグを付けなかった場合、バージョン番号は以下のように表示されます。poetry-dynamic-versioningを使うとPEP-440の仕様に準拠したバージョン識別子が付くようになっています。

初回のコミットにバージョン番号のタグを付けていない状態
初回のコミットにバージョン番号のタグを付けていない状態
バージョン番号のタグが付いているコミットの後にコミットを追加した状態
バージョン番号のタグが付いているコミットの後にコミットを追加した状態

Pythonパッケージのビルドはuv buildでOK

Poetryをビルドバックエンドに変更しましたが、ビルド操作はuvで行います。

# 作業フォルダーはSimpleWxAppフォルダー
uv build

distフォルダーの中にsimplewxapp-1.2.34.tar.gzsimplewxapp-1.2.34-py3-none-any.whlができます。別のフォルダーで新しい仮想環境を構築してインストールと実行をお試しください。

# 別の作業フォルダーを作ってください
uv venv
uv pip install /path/to/dist/simplewxapp-1.2.34-py3-none-any.whl
uv run simplewxapp

uvのおかげでPythonの仮想環境管理やプロジェクト管理が随分と楽になったと感じますが、Pythonプロジェクトのバージョン管理については、しばらくPoetryとpoetry-dynamic-versioningを使うのが良さそうです。

uv-dynamic-versioning(GitHubのサイトはこちら)が一日も早くuv標準のビルドバックエンドで正常に動くようになることを願っています。

タイトルとURLをコピーしました