plesty.sdk.semver ================= .. py:module:: plesty.sdk.semver .. autoapi-nested-parse:: Authoritative semantic-versioning support for gate 8 of ``plesty check``. Compares the public API of the working tree against the newest release published on its own line (static analysis via griffe โ€” the analyzed code is never imported) and derives the minimum version a breaking change requires: a minor bump before 1.0.0, a major bump afterwards. Attributes ---------- .. autoapisummary:: plesty.sdk.semver._PYPI_TIMEOUT Classes ------- .. autoapisummary:: plesty.sdk.semver.PypiBaseline Functions --------- .. autoapisummary:: plesty.sdk.semver._wheel_url plesty.sdk.semver.fetch_pypi_baseline plesty.sdk.semver.download_wheel plesty.sdk.semver.find_api_breakages plesty.sdk.semver.required_minimum_version plesty.sdk.semver.latest_tag_version Module Contents --------------- .. py:data:: _PYPI_TIMEOUT :value: 15 Timeout for PyPI requests in seconds. .. py:class:: PypiBaseline The published release used as the API-diff baseline. .. py:attribute:: version :type: packaging.version.Version Version of that release on PyPI. .. py:attribute:: wheel_url :type: str Download URL of its wheel. .. py:function:: _wheel_url(files: list[dict[str, Any]]) -> str | None The download URL of the first usable wheel among *files*, if any. Yanked files are skipped: a yanked release is one the maintainer has withdrawn, and diffing against it would measure an API nobody should be running. .. py:function:: fetch_pypi_baseline(name: str, line: tuple[int, int] | None = None) -> PypiBaseline | None Return the release on PyPI to diff the working tree against. Without *line* this is the newest release, which is right whenever the tree continues the newest line. A maintenance branch does not: it takes fixes to its own features and merges only upward, so it never gains what a later line added. Diffing it against the newest release would read that line's additions as removals from the older tree โ€” every one of them, on every run, for as long as the line is supported. Passing *line* picks the newest release the tree could actually be a successor of. :param name: The distribution name (e.g. ``plesty-sdk``). :param line: ``(major, minor)`` of the line being built. The baseline is then the newest release at or below it โ€” at or below, not equal to, so the first release of a new line still has a predecessor to diff against. :returns: The baseline, or ``None`` when the package is not published, has no wheel, or PyPI is unreachable (offline runs degrade gracefully). .. py:function:: download_wheel(url: str, dest: pathlib.Path) -> pathlib.Path Download a wheel and extract it, returning the extraction directory. :param url: Wheel download URL (from the PyPI JSON API). :param dest: Working directory for the download and extraction. :returns: The directory containing the extracted top-level packages. .. py:function:: find_api_breakages(packages: list[str], old_root: pathlib.Path, new_root: pathlib.Path) -> list[str] Diff the public API of top-level packages between two source roots. :param packages: Top-level package names to compare (e.g. ``["plesty"]``). :param old_root: Root directory of the baseline (extracted release wheel). :param new_root: Root directory of the working tree. :returns: One human-readable line per breaking change; empty when the new API is backwards-compatible. .. py:function:: required_minimum_version(published: packaging.version.Version) -> packaging.version.Version Return the minimum next version a breaking change requires. Pre-1.0 releases may break in a minor bump (SemVer ยง4 convention); from 1.0.0 on, breaking changes require a major bump. :param published: The latest published version. :returns: The lowest acceptable version for a release containing breakages. .. py:function:: latest_tag_version(project_dir: pathlib.Path) -> packaging.version.Version | None Return the version of the latest reachable git tag, or ``None``. :param project_dir: Root directory of the target project.