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``): .. code-block:: console $ 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: ``test`` ``pytest``, ``pytest-cov``, ``coverage``, ``wheel``: everything needed to run the test suite, including the ``wheel`` package, which is used by tests as the subject of installed-wheel introspection. ``dev`` ``tox``, ``tox-uv``, ``uv``: the tools which drive the gates. ``typechecking`` ``mypy``, ``types-setuptools``: type-checking the sources and verifying that the in-tree ``*.pyi`` stubs do not drift. ``docs`` ``sphinx``. ``lint`` ``ruff``, ``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 `` (or simply ``tox -e ``): ``py311`` ... ``py315``, ``pypy312`` The test suite against each supported interpreter, recording coverage data. ``cover`` Aggregated cross-interpreter coverage report, gated at 100%. ``mypy`` Static type checking, plus ``stubtest`` against each module's stubs (on Python 3.12; see the note about newer-interpreter dunders in the config). ``docs`` Building the HTML documentation, and running the narrative doctests. ``manifest`` Checking 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 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.