Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/workflows/compatibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion compatibility/consumers/beacon_typer/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion docs/api-stability.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
2 changes: 1 addition & 1 deletion docs/compatibility-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion docs/dependency-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |

Expand Down
2 changes: 1 addition & 1 deletion docs/optional-output-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. |

Expand Down
14 changes: 10 additions & 4 deletions docs/typer-adapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -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()`:
Expand Down Expand Up @@ -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.
9 changes: 6 additions & 3 deletions examples/typer_app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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.
2 changes: 1 addition & 1 deletion examples/typer_app/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
2 changes: 1 addition & 1 deletion lib/python/base_cli/typer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion tests/test_generate_compatibility_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading