Development¶
Requirements and tooling¶
The packaging metadata, and the test / tool dependency groups, live in
pyproject.toml. uv manages the development
environment and its lockfile (uv.lock):
$ uv sync --all-groups
The local gates are driven by tox, configured natively inside
pyproject.toml ([tool.tox]), using uv’s venv runner (tox-uv).
Dependency groups¶
The [dependency-groups] section (PEP 735) of pyproject.toml defines
the following groups:
testpytest,pytest-cov,coverage,wheel: everything needed to run the test suite, including thewheelpackage, which is used by tests as the subject of installed-wheel introspection.devtox,tox-uv,uv: the tools which drive the gates.typecheckingmypy,types-setuptools: type-checking the sources and verifying that the in-tree*.pyistubs do not drift.docssphinx.lintruff,check-manifest,breezy,build,twine: source linting, sdist manifest checking, and release tooling.
The project itself has no runtime dependencies, and none of these groups affect the published distribution metadata: they are development-only concerns, per PEP 735.
Gates¶
The following gates are runnable via uv run tox -e <env> (or simply
tox -e <env>):
py311…py315,pypy312The test suite against each supported interpreter, recording coverage data.
coverAggregated cross-interpreter coverage report, gated at 100%.
mypyStatic type checking, plus
stubtestagainst each module’s stubs (on Python 3.12; see the note about newer-interpreter dunders in the config).docsBuilding the HTML documentation, and running the narrative doctests.
manifestChecking that the sdist contents match the version control state: the test fixtures and type stubs must ship inside the sdist, while development files (e.g.,
uv.lock) must not.
The same checks run in the GitHub Actions workflow (.github/workflows/ci.yml)
without involving tox, as an independent check of the toolchain.
Test layout¶
The test suite lives at tests/unit, outside the pkginfo package:
test modules import the APIs under test inside test functions and helpers
(see tests/unit/_helpers.py for the shared checkers). Test fixtures
which emulate installed distributions (e.g., dodgy, manky,
wonky, tricky) are package trees placed on sys.path by the
fixtures in tests/unit/conftest.py; their metadata files are
hand-maintained data, checked into version control, not generated by
builds.
Release process¶
Releases are tagged with signed tags: the body of the tag carries the release’s changelog entries, rendered as the release notes via the GitHub releases page. For example:
$ git tag -s -F <changelog-body.txt> v1.14.0
$ git push origin v1.14.0
The sdist and wheel are built, checked, and published using the tools in
the lint group:
$ uv run build
$ uv run twine check dist/*
$ uv run twine upload dist/*
Creating and publishing the release itself (e.g., via
gh release create) is what actually publishes to PyPI: the release
workflow (.github/workflows/pypi.yml) reacts to the release published
event, verifying that the release’s tag matches the version declared in
pyproject.toml, building the sdist and wheel, and publishing them via
PyPI’s Trusted Publisher mechanism.
The Changelog project URL points at the
releases page, which is
the canonical changelog; release 1.13.3 was the last tracked in the
repo’s own CHANGES.txt file.