From c19a1586b5f7b92e8ab076aa87ba38b14c75240b Mon Sep 17 00:00:00 2001 From: Ramesh Padmanabhaiah <22363102+codeforester@users.noreply.github.com> Date: Fri, 18 Sep 2026 23:58:04 +0530 Subject: [PATCH] fix: align supported Typer and Click ranges for #360 --- .github/workflows/compatibility.yml | 47 +++++++++++++++++++ CHANGELOG.md | 5 ++ .../consumers/beacon_typer/pyproject.toml | 2 +- docs/api-stability.md | 2 +- docs/compatibility-dashboard.md | 2 +- docs/dependency-support.md | 2 +- docs/optional-output-dependencies.md | 2 +- docs/typer-adapter.md | 14 ++++-- examples/typer_app/README.md | 9 ++-- examples/typer_app/pyproject.toml | 2 +- lib/python/base_cli/typer.py | 2 +- pyproject.toml | 3 +- .../test_generate_compatibility_dashboard.py | 2 +- 13 files changed, 78 insertions(+), 16 deletions(-) diff --git a/.github/workflows/compatibility.yml b/.github/workflows/compatibility.yml index 0a15288..b27a50a 100644 --- a/.github/workflows/compatibility.yml +++ b/.github/workflows/compatibility.yml @@ -37,6 +37,53 @@ jobs: - name: Run adapter and Beacon compatibility tests run: python -m pytest tests/test_typer_adapter.py compatibility/consumers/beacon_typer/tests + typer-click-boundaries: + name: Typer ${{ matrix.typer-version }} / Click ${{ matrix.click-version }} / Python ${{ matrix.python-version }} + runs-on: ubuntu-latest + timeout-minutes: 20 + strategy: + fail-fast: false + matrix: + include: + - python-version: "3.10" + typer-version: "0.25.1" + click-version: "8.2.1" + - python-version: "3.14" + typer-version: "0.25.1" + click-version: "8.2.1" + - python-version: "3.10" + typer-version: "0.25.1" + click-version: "8.5.0" + - python-version: "3.14" + typer-version: "0.25.1" + click-version: "8.5.0" + - python-version: "3.10" + typer-version: "0.27.2" + click-version: "8.2.1" + - python-version: "3.14" + typer-version: "0.27.2" + click-version: "8.2.1" + - python-version: "3.10" + typer-version: "0.27.2" + click-version: "8.5.0" + - python-version: "3.14" + typer-version: "0.27.2" + click-version: "8.5.0" + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Set up Python + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + with: + python-version: ${{ matrix.python-version }} + - name: Install framework and supported Typer adapter + run: python -m pip install ".[dev,typer]" + - name: Pin the tested Click/Typer boundary pair + run: python -m pip install --upgrade "click==${{ matrix.click-version }}" "typer==${{ matrix.typer-version }}" + - name: Install Beacon fixture without dependency resolution + run: python -m pip install --no-deps compatibility/consumers/beacon_typer + - name: Run adapter and Beacon compatibility tests + run: python -m pytest tests/test_typer_adapter.py compatibility/consumers/beacon_typer/tests + downstream: name: Install and test independent consumers runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index ec20c2e..88fab61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,11 @@ and versions are tracked in the repo-root `VERSION` file. - Continue compatibility hardening and adoption work for the next release. +### Changed + +- Align the Typer support floor with the tested matrix and cover representative + minimum/maximum Typer and Click version pairings. + ### Fixed - Preserve explicit application identities losslessly while using diff --git a/compatibility/consumers/beacon_typer/pyproject.toml b/compatibility/consumers/beacon_typer/pyproject.toml index 2522c82..9cda485 100644 --- a/compatibility/consumers/beacon_typer/pyproject.toml +++ b/compatibility/consumers/beacon_typer/pyproject.toml @@ -7,7 +7,7 @@ name = "base-cli-compat-consumer-beacon" version = "0.1.0" description = "Independent Typer consumer compatibility fixture for base-cli" requires-python = ">=3.10" -dependencies = ["base-cli>=0.3,<0.5", "typer>=0.12,<0.28"] +dependencies = ["base-cli>=0.3,<0.5", "typer>=0.25.1,<0.28"] [project.scripts] beacon-consumer = "beacon_typer.cli:main" diff --git a/docs/api-stability.md b/docs/api-stability.md index 8211b09..8b4927b 100644 --- a/docs/api-stability.md +++ b/docs/api-stability.md @@ -53,7 +53,7 @@ Click `>=8.1,<8.6`; the compatibility suite covers the 8.1, 8.2, 8.3, 8.4, and 8.5 lines on Python 3.10 and 3.14. YAML configuration and YAML output are provided by the optional `base-cli[yaml]` extra, which supplies PyYAML `>=6.0,<7`. Other optional integrations are independently versioned and constrained in `pyproject.toml`: Typer -`>=0.12,<0.28`, Rich `>=13.7,<15`, and OpenTelemetry API `>=1.24,<2`. The +`>=0.25.1,<0.28`, Rich `>=13.7,<15`, and OpenTelemetry API `>=1.24,<2`. The lower bounds are the minimum supported versions; a dependency minor or major release is supported only after it passes the compatibility suite. The tested core dependency matrix is maintained in [`dependency-support.md`](dependency-support.md). diff --git a/docs/compatibility-dashboard.md b/docs/compatibility-dashboard.md index abc9c50..674f63a 100644 --- a/docs/compatibility-dashboard.md +++ b/docs/compatibility-dashboard.md @@ -17,7 +17,7 @@ red badge means that evidence is pending or needs investigation. | Python | `>=3.10,<4` | Python 3.10, Python 3.11, Python 3.12, Python 3.13, Python 3.14 | Supported and tested | | Click | `click>=8.1,<8.6` | 8.1, 8.2, 8.3, 8.4, 8.5 | Supported and tested on Python 3.10 and 3.14 | | PyYAML extra | `PyYAML>=6.0,<7` | 6.0 | Supported when `base-cli[yaml]` is installed | -| Typer extra | `typer>=0.12,<0.28` | 0.25.1, 0.26.0, 0.27.1, 0.27.2 | Supported through `attach_typer()` | +| Typer extra | `typer>=0.25.1,<0.28` | 0.25.1, 0.26.0, 0.27.1, 0.27.2 | Supported through `attach_typer()` | | Platforms | Pure-Python core | macos-latest, ubuntu-latest, windows-latest, Debian 12, Fedora latest, WSL2 | Supported tiers documented below | ## What the labels mean diff --git a/docs/dependency-support.md b/docs/dependency-support.md index 81d3cee..e080767 100644 --- a/docs/dependency-support.md +++ b/docs/dependency-support.md @@ -23,7 +23,7 @@ Optional integrations are intentionally independent of the core window: | Extra | Declared window | Compatibility evidence | | --- | --- | --- | -| `typer` | `>=0.12,<0.28` | Typer 0.25.1, 0.26.0, 0.27.1, and 0.27.2 across Python 3.10--3.14 | +| `typer` | `>=0.25.1,<0.28` | Typer 0.25.1, 0.26.0, 0.27.1, and 0.27.2 across Python 3.10--3.14; Click 8.2.1 and 8.5 boundaries on Typer 0.25.1/0.27.2 | | `rich` | `>=13.7,<15` | Integration tests and graceful-degradation checks | | `telemetry` | `>=1.24,<2` | Telemetry integration tests | diff --git a/docs/optional-output-dependencies.md b/docs/optional-output-dependencies.md index 3b0c324..984c611 100644 --- a/docs/optional-output-dependencies.md +++ b/docs/optional-output-dependencies.md @@ -11,7 +11,7 @@ format available. | --- | --- | --- | | Human text, CSV, TSV, JSON, and NDJSON records | none | Available from the core package through `base_cli.output`; redirected text is TSV. | | YAML configuration or YAML output | `base-cli[yaml]` | Provides `PyYAML>=6.0,<7`; loading or rendering YAML without it fails with an actionable error. | -| Typer application adapter | `base-cli[typer]` | Provides `typer>=0.12,<0.28`; importing the adapter without it fails with an actionable error. | +| Typer application adapter | `base-cli[typer]` | Provides `typer>=0.25.1,<0.28`; importing the adapter without it fails with an actionable error. | | Rich interactive tables | `base-cli[rich]` | Optional presentation enhancement; the built-in deterministic table remains the fallback. | | OpenTelemetry lifecycle spans | `base-cli[telemetry]` | Optional instrumentation; missing or unhealthy telemetry is a no-op for command status. | diff --git a/docs/typer-adapter.md b/docs/typer-adapter.md index a9dbe3c..150073f 100644 --- a/docs/typer-adapter.md +++ b/docs/typer-adapter.md @@ -7,12 +7,16 @@ without making Typer a core dependency: python -m pip install 'base-cli[typer]' ``` -The extra supports Typer 0.12 through 0.27.x. Typer 0.26 and later ship a +The extra supports Typer 0.25.1 through 0.27.x. Typer 0.26 and later ship a private Click fork, so the adapter selects the Click dialect that owns the generated command tree. Lifecycle options, parameter types, command instrumentation, and exception handling are always created and interpreted by that same dialect; base-cli never mixes public Click objects into a vendored -Typer tree. +Typer tree. The declared minimum is the oldest Typer line exercised by the +compatibility workflow; older releases are not part of the supported window. +Typer 0.25.1 itself requires Click 8.2.1 or newer, so `base-cli[typer]` +resolves the effective Click window to `>=8.2.1,<8.6`; Click 8.1 remains part +of the core-only compatibility contract. Use `attach_typer()` at the same boundary where a Click app would use `attach()`: @@ -78,5 +82,7 @@ Typer is an optional extra and is imported lazily. Importing `base_cli` and using the Click integration never imports or requires Typer. The compatibility workflow exercises the adapter and a typed consumer against -Typer 0.25.1, 0.26.0, 0.27.1, and 0.27.2 on Python 3.10 through 3.14. Keep -this matrix green before widening the supported Typer range again. +Typer 0.25.1, 0.26.0, 0.27.1, and 0.27.2 on Python 3.10 through 3.14. It also +tests the lower and upper Click boundaries with the minimum and latest +supported Typer lines. Keep these combinations green before widening the +supported Typer range again. diff --git a/examples/typer_app/README.md b/examples/typer_app/README.md index 0be0547..1dac0be 100644 --- a/examples/typer_app/README.md +++ b/examples/typer_app/README.md @@ -13,8 +13,10 @@ python -m pip install . base-typer --help ``` -The example pins the supported Typer range (`0.12` through `0.25`) because -newer releases use a private Click fork that the adapter intentionally rejects. +The example uses the supported Typer range (`0.25.1` through `0.27.x`). Typer +0.26 and later use a private Click fork; the adapter selects the matching Click +dialect and the compatibility workflow tests both the minimum and current +lines. ## Configuration @@ -60,6 +62,7 @@ publishing. Announce adapter support-range changes as release notes. - Run with `--debug` and capture `--log-file` when diagnosing a command. - If help fails after a Typer upgrade, check that the version is within the - supported `>=0.12,<0.28` range. + supported `>=0.25.1,<0.28` range and review the Click/Typer pair in the + compatibility matrix. - Use `--count 1` to distinguish application failures from input validation. - Redact access codes and other credentials from issue reports and transcripts. diff --git a/examples/typer_app/pyproject.toml b/examples/typer_app/pyproject.toml index 652ccb0..a73345f 100644 --- a/examples/typer_app/pyproject.toml +++ b/examples/typer_app/pyproject.toml @@ -9,7 +9,7 @@ description = "Typed Typer base-cli reference application" requires-python = ">=3.10" dependencies = [ "base-cli>=0.3", - "typer>=0.12,<0.28", + "typer>=0.25.1,<0.28", ] [project.scripts] diff --git a/lib/python/base_cli/typer.py b/lib/python/base_cli/typer.py index bdbe3a1..1f97905 100644 --- a/lib/python/base_cli/typer.py +++ b/lib/python/base_cli/typer.py @@ -67,7 +67,7 @@ def get_typer_command(typer_app: _TyperApp) -> _ClickCommand: if not isinstance(command, dialect.Command): raise TypeError( "Typer did not produce a Click command; upgrade to a supported " - "Typer release (currently 0.12 through 0.27.x)." + "Typer release (currently 0.25.1 through 0.27.x)." ) return mark_command_dialect(command, dialect) diff --git a/pyproject.toml b/pyproject.toml index 0898139..859d5ea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,9 +63,10 @@ dev = [ "types-PyYAML>=6.0,<7", ] typer = [ + # Typer 0.25.1+ requires Click >=8.2.1; Click 8.1 remains core-only. # Typer 0.26+ ships a private Click fork; the adapter selects the matching # Click dialect so both pre-fork and vendored-Typer command trees work. - "typer>=0.12,<0.28", + "typer>=0.25.1,<0.28", ] rich = [ "rich>=13.7,<15", diff --git a/tests/test_generate_compatibility_dashboard.py b/tests/test_generate_compatibility_dashboard.py index d7f16c3..915dc9d 100644 --- a/tests/test_generate_compatibility_dashboard.py +++ b/tests/test_generate_compatibility_dashboard.py @@ -16,7 +16,7 @@ def test_dashboard_contains_declared_and_tested_surfaces(self) -> None: "`>=3.10,<4`", "`click>=8.1,<8.6`", "`PyYAML>=6.0,<7`", - "`typer>=0.12,<0.28`", + "`typer>=0.25.1,<0.28`", "8.1, 8.2, 8.3, 8.4, 8.5", "0.25.1, 0.26.0, 0.27.1", "Debian 12",