Expose ClickException and UsageError from the typer namespace#1868
Open
uttam12331 wants to merge 1 commit into
Open
Expose ClickException and UsageError from the typer namespace#1868uttam12331 wants to merge 1 commit into
uttam12331 wants to merge 1 commit into
Conversation
After vendoring Click in 0.26.0, Typer re-exports several vendored exception
types (BadParameter, Abort, Exit) but not the general-purpose ClickException /
UsageError, leaving no public way to raise a concise user-facing CLI error
without reaching into the private ._click module.
Re-export ClickException and UsageError so apps can do
`raise typer.ClickException("...")` and get Typer's error rendering and the
expected exit code.
Closes fastapi#1867
JoyboyBrian
added a commit
to Osmosis-AI/osmosis-sdk-python
that referenced
this pull request
Jul 1, 2026
## Summary Typer 0.26 vendors Click ([breaking change](https://github.com/fastapi/typer/releases/tag/0.26.0)), so exceptions raised by Typer are no longer instances of the external `click` package's classes — the reason for our previous `typer <0.26` cap. Instead of staying frozen on 0.25 forever, this migrates the CLI off direct `import click` entirely and moves to `typer>=0.26,<0.27`. Closes #243 (supersedes the Dependabot range widening; that PR would have broken the CLI's top-level error handling). ## Changes - **New [`cli/_click_compat.py`](../blob/refactor/migrate-typer-0.26/osmosis_ai/cli/_click_compat.py)** — single import point for the vendored symbols Typer does not publicly re-export yet (`UsageError`, `ClickException`, `NoArgsIsHelpError`, `Context`, `Command`, `get_current_context`; see fastapi/typer#1868). The `<0.27` cap keeps these private paths stable; the module is deleted once upstream exports them. Everything else uses public typer API (`typer.Exit`, `typer.Abort`). - **`main()` error handling** — the fragile "empty-message UsageError means help was already printed" hack is replaced with an explicit `except NoArgsIsHelpError`. - **`get_output_context()`** — the ContextVar set by `install_output_context()` is now the source of truth; the redundant reach into Click's threadlocal context stack is gone. - **`OsmosisGroup` is kept unchanged** — tests pin its deliberate behaviors (single-candidate suggestion format, hidden-command filtering, the `osmosis help` nudge). Typer's native `suggest_commands` is explicitly disabled so it cannot double-append its own (unfiltered, multi-candidate) suggestions. - **Tests** — construct vendored objects (`typer.core.TyperCommand`; the vendored `Command` is now abstract) and use `typer.testing.CliRunner`; the removed ctx.obj resolution layer's test is replaced by two tests asserting the new ContextVar contract. ## Behavior No user-facing behavior changes. Verified via the full suite plus real-process smoke tests: bare `osmosis` (rich help, exit 0), typo suggestions, `osmosis help` nudge, `--version`, and the `--json` structured error envelope. CLI code no longer depends on the external `click` package at all, which also ends click version conflicts with other click-dependent dependencies in user environments. ## Verification - `pytest`: 1721 passed - `ruff check` / `ruff format --check`: clean - `pyright osmosis_ai/`: 0 errors; `--verifytypes`: no unexpected public API errors ## Note for local editable installs Dependencies of editable installs do not auto-update: run `pip install -e ".[dev]"` (or `uv sync`) after pulling this change to pick up typer 0.26. <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Migrate the CLI to `typer` 0.26 (vendored Click) and remove direct `click` usage to keep error handling correct and avoid version conflicts. Add a hard guard against `typer-slim` overlays and fail fast with a clear ImportError if a corrupted `typer` install is detected; no user-facing changes otherwise. - **Refactors** - Add `osmosis_ai/cli/_click_compat.py` to import vendored types (`UsageError`, `ClickException`, `NoArgsIsHelpError`, `Context`, `Command`, `get_current_context`). - Replace the empty-message `UsageError` hack with `NoArgsIsHelpError`; use `typer.Exit`/`typer.Abort`. - Make the ContextVar set by `install_output_context()` the source of truth in `get_output_context()`; remove threadlocal lookups. - Preserve `OsmosisGroup` suggestions and disable Typer’s `suggest_commands`; tests updated to `typer.core` and `typer.testing`. - Assert Typer↔vendored Click lineage at import and raise an actionable ImportError if `typer` files were overlaid (guides reinstall). - **Dependencies** - Pin `typer>=0.26,<0.27` and add `typer-slim>=0.22` to prevent overlay corruption; CLI no longer imports `click`. - For editable installs, run `pip install -e ".[dev]"` or `uv sync` to pick up the new versions. <sup>Written for commit 1a01816. Summary will update on new commits.</sup> <a href="https://cubic.dev/pr/Osmosis-AI/osmosis-sdk-python/pull/248?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #1867.
After vendoring Click in 0.26.0, Typer re-exports several vendored exception types —
typer.BadParameter,typer.Abort,typer.Exit— but not the general-purposeClickException/UsageError. That leaves no public way to raise a concise user-facing CLI error without importing from the privatetyper._clickmodule (which the 0.26.0 vendoring guidance tells users not to do).Change
Re-export the two vendored base errors alongside the existing ones, keeping the imports alphabetically ordered:
Apps can now do:
Tests
Added
test_click_exceptionandtest_usage_errortotests/test_exit_errors.pyasserting the exit codes (1 and 2) and that the message reaches the output.Verified locally:
pytest tests/test_exit_errors.py→ 6 passed;ruff checkclean.