chore: migrate from Poetry to uv with tox-uv#24
Conversation
Replaces Poetry with uv for dependency management and adds the tox-uv
plugin for faster CI venv creation.
pyproject.toml:
* Convert [tool.poetry] → PEP 621 [project]
* Switch build-backend from poetry-core to uv_build (>=0.11.2,<0.12.0)
* Drop authors/keywords/classifiers (not publishing to PyPI)
* Add license = "Apache-2.0" explicitly (avoids liccheck reading
README HTML as the license string)
* Dev deps moved to [dependency-groups] dev
* [tool.uv]: default-groups = "all", prerelease = "allow" so uv lock
accepts ipfshttpclient==0.8.0a2
Lock file: poetry.lock deleted, uv.lock generated (119 packages).
CI (.github/workflows/main_workflow.yml):
* lock_check job: snok/install-poetry → astral-sh/setup-uv@v6;
checks `uv lock --check` and `uv sync --all-groups -v` (dropped
poetry-version from the matrix)
* Every `pip install tomte[tox...]` line now also installs `tox-uv`
so tox invokes uv under the hood
tox.ini:
* [tox]: uv_seed = true (uv venvs don't ship pip, aea CLI imports
pip._internal — this seeds each venv with pip)
* [testenv] setenv: added UV_PRERELEASE=allow for pre-release
ipfshttpclient
* [deps-tests]: added `pip` so inheriting envs have it
* [testenv:check-generate-all-protocols] and [testenv:liccheck]:
added `pip` explicitly (custom deps, don't inherit deps-tests)
Verified locally — all these tox envs pass after migration:
* check-packages, check-hash, check-dependencies
* check-doc-hashes, check-abciapp-specs, abci-docstrings
* liccheck
* py3.14-darwin (empty template, pytest finds no tests → exits 0
via pytest-custom_exit_code)
* black-check, isort-check, flake8, mypy, pylint, darglint, bandit
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Post-migration cleanup. The uv migration commit swapped the build
backend and lock file but left a handful of tracked files still
referencing Poetry or Pipenv.
README.md:
* System requirements: [Poetry] >=2.0 -> [uv] >=0.11
* Setup: `poetry install` + `eval $(poetry env activate)` ->
`uv sync --all-groups` + `source .venv/bin/activate`
Makefile:
* clean-build: drop `rm -fr Pipfile.lock` (never existed here;
legacy cargo-culted from some upstream repo)
.gitignore:
* Drop `/Pipfile.lock` entry (Pipfile was never used here either)
.spelling:
* Drop `Pipenv` dictionary entry (no longer referenced in any doc)
Verified: `git ls-files | xargs grep -Eln "poetry|pipenv|Pipfile|Pipenv"`
returns no matches.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two CI fixes surfaced after the uv migration: 1. `safety` env failing with `AttributeError: module 'httpx' has no attribute 'NetworkError'` — root cause: UV_PRERELEASE=allow (set in [testenv] for ipfshttpclient==0.8.0a2) cascades to the safety env, letting uv resolve httpx to the 1.0.dev3 pre-release. safety 3.7.0 still imports httpx.NetworkError which doesn't exist there. Fix: `constraint-dependencies = ["httpx<1"]` in [tool.uv] — uv (and tox-uv by extension) honors this across all resolves and pins httpx to the stable 0.x series everywhere. 2. The project .venv built by `uv sync` had `tox` but not `tox-uv`, so `uv run tox` fell back to classic pip-based venv creation — which doesn't match CI (where `pip install tomte[tox] tox-uv` makes tox-uv active). Local runs couldn't surface the CI failure mode. Fix: add `tox-uv` to [dependency-groups] dev so `uv run tox` exercises the same tox-uv path that CI does. Verified locally: `uv run tox -e <all-critical-envs> -r` now green across bandit, safety, black-check, isort-check, flake8, mypy, pylint, darglint, check-hash, check-packages, check-dependencies, check-abciapp-specs, check-doc-hashes, abci-docstrings, liccheck. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- .gitignore: add .venv/ so following the README's `uv sync` step doesn't leave an untracked directory at the repo root - pyproject.toml: comment the `constraint-dependencies = ["httpx<1"]` line with the reason (safety 3.7.0 vs httpx 1.x NetworkError removal) so a future maintainer doesn't delete it and break CI again - README.md: replace the Linux-only `source .venv/bin/activate` with a Windows + Unix pair, and recommend `uv run <cmd>` as the idiomatic path so new template users don't have to activate at all Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| sudo apt-get autoremove | ||
| sudo apt-get autoclean | ||
| pip install tomte[tox,cli]==0.6.5 | ||
| pip install tomte[tox,cli]==0.6.5 tox-uv |
There was a problem hiding this comment.
shouldn't we include it in tomte?
There was a problem hiding this comment.
Yes, ideally this should live in tomte[tox] extras. I'll add it upstream in tomte and bump the pin here as a follow-up.
| deps = | ||
| tomte[tests]==0.6.5 | ||
| pytest-custom_exit_code==0.3.0 | ||
| pip |
There was a problem hiding this comment.
Good catch, it was half-redundant. uv_seed = true at the [tox] level seeds pip into every tox-uv venv, so the explicit pip in [deps-tests] was unnecessary for everything that inherits via {[deps-tests]deps} / {[deps-packages]deps}. Dropped it in ccfa90a — verified check-packages, check-hash, check-dependencies, check-doc-hashes, abci-docstrings, mypy, pylint all still pass.
Kept the explicit pip only in [testenv:liccheck] (+ [testenv:check-generate-all-protocols]), with an inline comment. liccheck 0.6.0 imports pip._internal.download.PipSession and uv_seed doesn't reliably expose pip in envs that install only tomte[liccheck,cli] — without explicit pip, tox -e liccheck fails with ModuleNotFoundError: No module named 'pip'.
| "open-aea-ci-helpers==2.2.1", | ||
| "open-aea-helpers==0.21.18", | ||
| "pytest-custom_exit_code==0.3.0", | ||
| "setuptools<=81.0.0", | ||
| "toml==0.10.2", |
There was a problem hiding this comment.
same comment, if any of them can be in development group, would be good to add them there.
There was a problem hiding this comment.
Good catch — turns out most of them can move. I'd assumed aea-ci check-dependencies enforced pyproject/tox parity, but digging into its source shows it only reads config["tool"]["poetry"]["dependencies"] (here). For PEP 621 pyproject (our post-migration format) it returns None and skips pyproject parity entirely — so moving CI-only deps to [dependency-groups] dev doesn't break the checker.
Moved to dev group in ccfa90a:
open-aea-ci-helpers— CI tool (aea-ci check-dependenciesetc.)open-aea-helpers— CI tool (aea-helpers check-doc-hashes)pytest-custom_exit_code— empty-template test tolerancesetuptools<=81.0.0— liccheck 0.6.0 workaround
Kept in main dependencies:
open-autonomy[all]— legitimate runtimetoml— build-config parsing
@OjusWiZard review on PR #24: tox.ini — drop redundant pip from [deps-packages] inheritance chain. uv_seed = true (at [tox] level) seeds pip into every tox-uv venv, so the explicit pip in [deps-tests] was redundant for every env that inherits via {[deps-tests]deps} or {[deps-packages]deps}. Verified by dropping it — check-packages/check-hash/check-deps/ check-doc-hashes/abci-docstrings/mypy/pylint all still pass. liccheck still needs its own explicit pip. uv_seed does not reliably expose pip in envs that only install tomte[liccheck,cli] — liccheck 0.6.0 imports pip._internal.download.PipSession and fails with ModuleNotFoundError without an explicit pin. Kept + added an inline comment explaining. pyproject.toml — move CI-only deps to [dependency-groups] dev. aea-ci check-dependencies only reads config["tool"]["poetry"]["dependencies"] (legacy Poetry layout). For PEP 621 (our post-migration format) it returns None and skips pyproject parity entirely, so moving to dev group doesn't break the checker. Moved: * open-aea-ci-helpers (CI tool: aea-ci check-dependencies etc.) * open-aea-helpers (CI tool: aea-helpers check-doc-hashes) * pytest-custom_exit_code (empty-template test tolerance) * setuptools<=81.0.0 (liccheck 0.6.0 workaround for pkg_resources) Kept in main dependencies: * open-autonomy[all] (legitimate runtime for template users) * toml (build-config parsing) Verified locally: all 15 uv run tox envs pass (check-packages/check-hash/check-dependencies/check-abciapp-specs/ check-doc-hashes/abci-docstrings/liccheck/safety/bandit/mypy/pylint/ black-check/isort-check/flake8/darglint). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Changes
Core migration (commit 1)
pyproject.toml
[tool.poetry]→ PEP 621[project]poetry-core→uv_build(>=0.11.2,<0.12.0)authors/keywords/classifiers(not publishing to PyPI)license = "Apache-2.0"so liccheck doesn't read README HTML[dependency-groups] dev[tool.uv]:default-groups = "all",prerelease = "allow"foripfshttpclient==0.8.0a2Lock file:
poetry.lockdeleted,uv.lockgenerated (119 packages).CI (
main_workflow.yml)lock_checkjob:snok/install-poetry→astral-sh/setup-uv@v6; runsuv lock --check+uv sync --all-groups -vpip install tomte[tox...]line now also installstox-uvtox.ini
uv_seed = trueunder[tox]— seeds pip into each venv (uv venvs don't include it; aea CLI importspip._internal)UV_PRERELEASE=allowin[testenv]setenvpipadded to[deps-tests]+[testenv:check-generate-all-protocols]+[testenv:liccheck]Stale-ref cleanup (commit 2)
Strip tracked-file references to Poetry / Pipenv:
README.md,Makefile(droprm -fr Pipfile.lock),.gitignore(drop/Pipfile.lock),.spelling(dropPipenv).CI-compat fixes (commit 3)
[tool.uv] constraint-dependencies = ["httpx<1"]—safety 3.7.0(pulled viatomte[safety]) importshttpx.NetworkError, which was removed inhttpx 1.x. Without this,UV_PRERELEASE=allowlets uv resolve tohttpx 1.0.devNand thesafetytox env breaks. Root cause of the initial CI red.tox-uvadded to[dependency-groups] devsouv run toxlocally uses the same tox-uv path that CI does (matching test harness).Review nits (commit 4)
.gitignore: add.venv/(README tells users touv sync→ creates.venv/at repo root)pyproject.toml: inline comment explaining thehttpx<1constraint so a future maintainer doesn't delete itREADME.md: Windows-compatible venv activation (.venv\Scripts\Activate.ps1) + recommenduv run <cmd>as the idiomatic pathVerified locally (via
uv run tox)All these envs pass on
uv run tox -e <name> -r:check-packages,check-hash,check-dependenciescheck-doc-hashes,check-abciapp-specs,abci-docstringsliccheck,safetyblack-check,isort-check,flake8,mypy,pylint,darglint,banditAudit:
git ls-files | xargs grep -Eln "poetry|pipenv|Pipfile|Pipenv"returns no matches.Test plan
lock_checkgreen on ubuntu/macos/windowscopyright_and_dependencies_checkgreenlinter_checksgreentestmatrix green across Python 3.10–3.14 × ubuntu/macos/windowsgitleaksgreen