Skip to main content

PyAhead

A little foresight for your Python code.
Find the CPython deprecations and removals a codebase will hit — and when — before the upgrade does.

PyPI version Supported host Python versions CI status Apache-2.0 license

The PyAhead website after scanning paramiko 2.7.2 for Python 3.9 through 3.14: 7 breaking and 1 deprecated finding, the first a base64.decodestring call marked deprecated in 3.1 and removed in 3.9, with the replacement and a link to the Python 3.9 release notes.
www.diegor.it/pyahead — paramiko 2.7.2 scanned in the browser for Python 3.9 through 3.14. Nothing leaves your machine.

PyAhead scans a repository without importing or executing its code and presents one timeline per finding: when CPython deprecated the API, when it is or will be removed, what to use instead, and the "What's New" entry that says so. Every rule in its registry cites the change at the version it happened.

Try it without installing anything

www.diegor.it/pyahead scans a public GitHub repository in your browser. PyAhead runs there as WebAssembly: the page fetches the repository's Python files, analyses them on your machine, and renders the report. Nothing is uploaded, nothing is stored, and no account is needed — there is no server to send anything to.

It reads public repositories only, and fetches file by file under a cap, so a large repository produces a scan that says it is incomplete rather than one that looks clean. For private code, continuous scanning, or CI, install the command below.

Limitations — read before use

PyAhead is a public alpha. A clean scan is not proof of compatibility. The bundled registry covers reviewed, statically representable Python-level entries from selected CPython sources; it does not cover arbitrary runtime behavior, dependencies, C extensions, reflection, generated code, or every Python API. Run the repository's tests on every supported target interpreter as well.

The default static command does not execute target code, install target dependencies, infer general receiver types, resolve arbitrary dynamic imports, access the network, or send telemetry. Dependency evidence is a separate opt-in command with explicit targets, network policy, and deadlines. Version helpers, user-defined constants, patch-level guards, and general control flow outside the documented lexical grammar remain unknown. Skipped, unreadable, oversized, unparseable, or over-limit source entries make analysis incomplete rather than silently clean. See all documented limitations.

What you get

  • A timeline, not a lint. Each finding says which Python versions it reaches, when the API was deprecated, when it goes away, and what replaces it — grouped by the version the change lands in, so the 3.13 work is separate from the 3.10 work.
  • Sources you can check. The registry's 205 rules are curated from CPython's own release notes — every "What's New" page from 3.9 to 3.15 censused entry by entry — and each rule links the section that announced the change at the version it happened.
  • Static, offline, deterministic. LibCST parsing only: no imports, no execution, no network, byte-identical reports for identical input. Version guards (sys.version_info, TYPE_CHECKING) narrow what a finding reaches.
  • Made for CI. SARIF and JSON output, a --fail-on gate, baselines that adopt existing findings without hiding them, and rule-specific inline suppressions that stay auditable.
  • Measured precision. Findings are validated against the PyPI top 1000 with a real interpreter adjudicating them; the approved record is in docs/evidence.

Install

pipx install pyahead==0.7.0
# or run without a persistent tool environment
uvx pyahead==0.7.0 --version

To build and install a candidate from this repository instead:

uv build
pipx install dist/pyahead-0.7.0-py3-none-any.whl

Installing PyAhead may contact the configured package index to obtain PyAhead and its dependencies. Running pyahead check itself is offline.

Quick start

Scan a repository with an explicit inclusive policy:

pyahead check . --baseline-python 3.9 --horizon-python 3.14

For paramiko 2.7.2 that reports eight findings, grouped by the Python version each change lands in:

PyAhead 0.7.0
Policy: Python 3.9 through 3.14
Registry: 2026.10.10 (fa9db725e612)

Python 3.9 — 2 upgrade blockers
  CPY0178  paramiko/py3compat.py:40:19  base64.encodestring (breaking; high confidence)
    base64.encodestring is removed
    Match evidence: qualified_names=[base64.encodestring]; reference_context=read; resolution=exact-import
    Reachable targets: 3.9, 3.10, 3.11, 3.12, 3.13, 3.14
    Usage contexts: runtime
    States: breaking on 3.9 through 3.14
    Timeline: deprecated in 3.1 (released); removed in 3.9 (released)
    Guidance: Call base64.encodebytes().
    Remediation documentation: https://docs.python.org/3.9/whatsnew/3.9.html#removed
    Source: What's New in Python 3.9 — Removed — https://docs.python.org/3.9/whatsnew/3.9.html#removed

  ...

Python 3.10 — 2 compatibility findings
  CPY0153  paramiko/py3compat.py:162:30  collections.Callable (breaking; high confidence)
    collections.Callable is removed
    Match evidence: qualified_names=[collections.Callable]; reference_context=read; resolution=exact-import
    Reachable targets: 3.9, 3.10, 3.11, 3.12, 3.13, 3.14
    Usage contexts: runtime, typing
    States: deprecated on 3.9; breaking on 3.10 through 3.14
    Timeline: deprecated in 3.3 (released); removed in 3.10 (released)
    Guidance: Import Callable from collections.abc.
    Remediation documentation: https://docs.python.org/3.9/library/collections.html
    Source: Python 3.9 collections documentation — https://docs.python.org/3.9/library/collections.html
    Source: What's New in Python 3.10 — Removed — https://docs.python.org/3.10/whatsnew/3.10.html#removed

  ...

Result: 8 findings (7 breaking, 1 deprecated); 84 files analyzed; 0 files incomplete.

Or declare strict configuration in pyproject.toml:

[tool.pyahead]
baseline-python = "3.11"
horizon-python = "3.14"
include = ["src/**/*.py", "tests/**/*.py"]
exclude = ["src/generated/**"]
source-roots = ["src"]
minimum-confidence = "high"
fail-on = "breaking"
respect-gitignore = true
show-unscheduled = true

Then run:

pyahead check

When the baseline is omitted, PyAhead can infer the lowest supported registry minor from [project].requires-python and records that provenance in the report. It never infers the baseline from the host interpreter.

Exit code 1 means an unsuppressed finding met the selected fail-on gate; 2 means invalid command, configuration, or registry input; 3 means analysis was incomplete; and 4 means an unexpected internal failure. Exit 0 means only that the configured static scan completed without a gated finding.

Status

Version 0.7.0 is the current public-alpha release. It provides deterministic text, JSON, and SARIF 2.1.0 reports; strict project configuration; baselines and rule-specific suppressions; version-guard and typing-context reachability; a source-linked, coverage-audited CPython registry; opt-in pytest warning evidence; and opt-in dependency metadata and isolated-resolution evidence.

PyAhead supports host Python 3.11 through 3.14 on Linux, macOS, and Windows. The host interpreter is independent of the baseline and horizon Python versions being assessed. Python 3.15 prerelease CI is advisory until support is claimed.

The first opt-in dynamic provider collects deprecation warnings with an explicit pytest plugin in the repository owner's CI, then merges its versioned artifact with pyahead check --evidence. Observed warnings stay separate from static inference; unmatched and different-commit evidence remains visible. PyAhead does not run those tests in a hosted scanner.

pyahead dependencies separately inspects supplied wheel, source-distribution, or Core Metadata files without executing build backends. An optional isolated uv adapter has explicit offline/online and timeout controls. Dependency results distinguish exact declared incompatibility, independently corroborated constraint failures, closed-wheelhouse target-artifact absence, sample-level artifact availability, and incomplete evidence. Direct artifact samples remain compatibility unverified until a complete resolution closes the relevant inventory, except that an exact, final Requires-Python exclusion remains declared incompatible.

Gate B is exercised by repository tests and clean wheel/sdist installation. Gate C requires evidence from 100 active public repositories, at least 95% sampled precision for high-confidence findings, false-positive regressions, retained limitations, and accountable product-owner approval. Continuous-use adoption is measured after the alpha is publicly available; it is not a prerequisite for the M7–M8 dynamic-evidence work.

CI and review workflows

The repository is also a GitHub Action. It installs the PyAhead release named by the tag you reference, scans, uploads the SARIF report to code scanning, and then fails the job if a finding meets the gate:

jobs:
  pyahead:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
    steps:
      - uses: actions/checkout@v7
      - uses: diegorusso/pyahead@v0.7.0
        with:
          baseline-python: "3.11"

Inputs mirror the command line (path, baseline-python, horizon-python, fail-on, minimum-confidence); upload: "false" keeps the report local, and the exit-code and sarif-file outputs are there for later steps. See action.yml.

Outside GitHub Actions, or to drive it yourself:

Write SARIF or deterministic JSON atomically:

pyahead check --format sarif --output pyahead.sarif
pyahead check --format json --output pyahead.json --fail-on never

Adopt existing findings without hiding them from reports:

pyahead baseline create --output .pyahead-baseline.json
pyahead check --baseline-file .pyahead-baseline.json --fail-new-only

Inline suppressions are rule-specific and stay auditable:

import cgi  # pyahead: ignore[CPY0001] -- migration tracked in issue 42

Unknown rule IDs remain visible diagnostics. Report, baseline, and output paths must remain beneath the selected project root, including through symlinks.

Inspect the bundled registry without scanning a repository:

pyahead registry validate
pyahead registry coverage
pyahead registry list
pyahead explain CPY0001

Documentation

Development

PyAhead requires Python 3.11 or newer. The locked development environment uses uv:

uv sync --frozen
uv run ruff check .
uv run ruff format --check .
uv run mypy src scripts
uv run pytest
uv build
uv run pyahead --version
uv run python scripts/install_smoke.py --dist-dir dist --kind wheel
uv run python scripts/install_smoke.py --dist-dir dist --kind sdist
uv run python scripts/benchmark.py --repeat 1 --output -
git diff --check

Project-wide branch coverage is enforced at 90%. A focused pytest invocation may therefore fail only because it did not cover the whole package; use --no-cov for isolated iteration, then run the complete suite.

Read the contribution guide before proposing a change.

License

PyAhead is licensed under the Apache License 2.0. See LICENSE.

Metadata

Release files for pyahead 0.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyahead 0.7.0
File Size Uploaded Provenance
pyahead-0.7.0.tar.gz 766.6 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pyahead 0.7.0
File Interpreter ABI Platform
pyahead-0.7.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.2 MB

Release files / pyahead-0.7.0.tar.gz

Download URL pyahead-0.7.0.tar.gz
Size 766.6 kB
Tags Source
SHA-256 checksum
How to use checksums
e39ff9a0a2692badcdec5c63d905ff788aec2f2aae5c621a457600b781de721c
BLAKE2b-256 checksum
How to use checksums
7428091ca0c58fa6db35a348d790fa338f51d13cdc46335e3d2a6eba3771b08d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Release files / pyahead-0.7.0-py3-none-any.whl

Download URL pyahead-0.7.0-py3-none-any.whl
Size 392.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f11e72ea8bc6598f6aaaee414a612bbe35214dc39c67f8c3cbee993c09e0d4ec
BLAKE2b-256 checksum
How to use checksums
288f6ba829ebc485f4c7864cead1e82bc684dce375d2161dbafff4cd7423657d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Security for pyahead 0.7.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pyahead-0.7.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page