Skip to content

fix: resolve UsageError from the installed typer's Click - #272

Merged
pzfreo merged 2 commits into
mainfrom
fix/typer-vendored-click
Aug 30, 2026
Merged

pzfreo merged 2 commits into
mainfrom
fix/typer-vendored-click

Conversation

@pzfreo

@pzfreo pzfreo commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Problem

uv tool install bambox (and pip install bambox) produces a CLI that crashes immediately:

File ".../site-packages/bambox/cli.py", line 10, in <module>
    import click
ModuleNotFoundError: No module named 'click'

cli.py imported click but never declared it — it arrived transitively via typer. typer 0.25+ vendors its own copy of Click (typer._click) and dropped the click requirement, so a fresh resolve gets typer 0.27.2 with no click in the environment.

uv.lock pins typer 0.24.1, which still depends on click, so local dev and CI never saw it.

Fix

Resolve UsageError from whichever Click the installed typer actually uses:

try:  # typer >= 0.25 vendors its own copy of Click
    from typer._click.exceptions import UsageError
except ImportError:  # typer < 0.25 depends on the click package
    from click.exceptions import UsageError

Adding click to dependencies would not have been sufficient: under typer 0.27 the standalone click.UsageError is a different class from the one typer raises, so main()'s handler would silently stop matching and usage errors would traceback instead of exiting 2.

Also refreshes the stale bambox version pin in uv.lock (0.4.7 → 0.6.1).

Verification

In a throwaway venv with typer 0.27.2 and no click installed:

  • bambox --help — works
  • bambox pack t.gcode -o t.gcode.3mf — writes a valid archive
  • bambox validate t.gcode.3mf — works
  • bambox --nonexistent-flag — prints ✘ No such option: --nonexistent-flag, exits 2

New test TestUsageErrorHandling asserts typer.BadParameter is a subclass of the UsageError cli.py resolved, so the hierarchy cannot drift again on either typer generation.

Pre-PR checklist: ruff check ✔, ruff format ✔, mypy ✔, pytest -m "not e2e" 398 passed. (The test_e2e_cura_vs_bbl.py errors on a full local run are pre-existing — they need the estampo CLI + Docker.)

🤖 Generated with Claude Code

https://claude.ai/code/session_011aB9rCzbxyCrr7ZcXEN7g5

Paul Fremantle and others added 2 commits August 30, 2026 09:37
typer 0.25+ vendors its own copy of Click and no longer depends on the
click package, so `import click` in cli.py broke every fresh install:
`uv tool install bambox` produced a CLI that died with
ModuleNotFoundError: No module named 'click'.

Declaring click as a dependency would not be enough — typer raises its
vendored typer._click UsageError, which is a different class from the
standalone click.UsageError, so main()'s handler would silently stop
matching and usage errors would traceback instead of exiting 2.

Resolve UsageError from typer's vendored Click, falling back to the
click package for typer < 0.25, and assert the hierarchy in a test so it
cannot drift again. Also refreshes the stale version pin in uv.lock.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011aB9rCzbxyCrr7ZcXEN7g5
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011aB9rCzbxyCrr7ZcXEN7g5
@codecov-commenter

Copy link
Copy Markdown

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

ℹ️ You can also turn on project coverage checks and project coverage reporting on Pull Request comment

Thanks for integrating Codecov - We've got you covered ☂️

@pzfreo
pzfreo merged commit ee5e0f6 into main Aug 30, 2026
12 checks passed
@pzfreo
pzfreo deleted the fix/typer-vendored-click branch August 30, 2026 08:41
@pzfreo pzfreo mentioned this pull request Aug 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants