fix(deps): make toon_format an optional extra, and reject --output toon before the command runs - #331
Merged
Merged
Conversation
…nt releases Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
tomaz-lc
force-pushed
the
fix-toon-optional-extra
branch
from
July 30, 2026 11:26
65c4525 to
78e36db
Compare
tomaz-lc
marked this pull request as ready for review
July 30, 2026 11:33
…o <0.12 Follow-up to making toon_format an optional extra. Filed under 5.6.1, which is the tag these entries ship in. Refusing TOON only at render time means the command has already done its work: a search runs to completion, bills the organization, and buffers every page before discovering it has no encoder. That was unreachable while toon_format was a hard dependency and became a normal path once it moved to an extra. ensure_format_available() now guards the format as the CLI selects it, sharing one message with the render-time guard in format_toon() so the two cannot drift. The root group callback runs before a subcommand parses its own --help, so the check exempts help and completion; without that exemption `--output toon <command> --help` would fail on a default install. uv 0.12.0 changed its default pre-release mode to resolve transitive pre-releases the way pip does, which fixes the resolution failure that motivated the extra. The extra still matters for uv 0.11 and older, but every present-tense claim that uv "cannot install" us is now wrong for current uv, so the CHANGELOG, README, CLI docs, pyproject comment, and the error message itself are scoped to uv older than 0.12. Also: - The dev extra self-references limacharlie[toon] instead of repeating the version range, leaving one place to bump when toon_format ships a stable release. Verified that both `pip install .[dev]` and `pip install -e .[dev]` still pull the encoder. - test_cli_reports_the_extra_without_a_traceback asserted no traceback while main() prints one when LC_DEBUG is set, so it failed for anyone with that exported. It now clears the variable. - getting-started.md said `pip install limacharlie` with no mention that TOON became opt-in, and the README ran the pip and uv forms together in one block as though both were needed. - The CHANGELOG credits @Nynir for finding and fixing the uv fallback, and references the originating issue and PRs. Verified against a wheel built from this branch: uv 0.11.33 installs it with no flags and pulls no toon-format, uv 0.12.0 and pip both resolve it, and the wheel plus [toon] restores TOON output. Full suite passes both with the extra (3859 passed, 5 skipped) and without it (3845 passed, 19 skipped). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
tomaz-lc
force-pushed
the
fix-toon-optional-extra
branch
from
July 30, 2026 11:37
78e36db to
0a97613
Compare
tomaz-lc
enabled auto-merge (squash)
July 30, 2026 11:38
lc-kirill
approved these changes
Jul 30, 2026
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.
Credit
The diagnosis and the fix in this PR are @Nynir's work, contributed in #325 and reported in #324. Thank you. This was a genuinely hard bug to see from our side: uv reported success on every install, just for a release three months of features behind, and nothing in our CI or on PyPI looked wrong. It took someone noticing that
uv tool upgrade limacharliekept saying "Nothing to upgrade" and then chasing it all the way down to a transitive pre-release rule in the resolver.Their commit is preserved here with its authorship intact, and everything this PR adds on top is a separate commit. The CHANGELOG credits them under a
### Thanksentry.Details
This carries #325 by @Nynir, rebased onto current master, with follow-up fixes. Closes #324.
The CHANGELOG entries are filed under 5.6.1, dated July 30, 2026, on the assumption that this branch is tagged
5.6.1on merge. If the merge slips past today, that date needs adjusting before tagging. There is no version constant to bump: the package version is derived from the git tag by setuptools-scm.toon_formatmoves out of[project.dependencies]into an optionaltoonextra. The onlytoon_formatrelease in our supported range is a pre-release (0.9.0b1), and uv before 0.12 refuses pre-releases reached through another package's metadata. Rather than reporting a conflict it backtracks to the newest release that does not need one, which is 5.3.0, silently:uv tool install limacharlie,uvx limacharlie, anduv pip install limacharliehave all been landing on a release that predates the dependency, withuv tool upgrade limacharliereporting "Nothing to upgrade". Making the dependency optional lets those uv versions install the current release. Behavior change: a default install no longer supports--output toon;pip install 'limacharlie[toon]'restores it. The other five output formats are unaffected, andtoonstays in the--outputchoice list so it still validates and tab-completes.Two things are worth flagging for the merge decision. First, uv 0.12.0 fixed the underlying resolver behavior on 2026-07-28 (astral-sh/uv#19993) by switching the default pre-release mode to
if-necessary, so current uv resolves transitive pre-releases the way pip does and installs the newest release either way. The extra is still what unblocks anyone pinned to uv 0.11 or older, but it is no longer fixing a problem that every uv user has, and it is worth deciding explicitly whether the behavior change is worth it on that basis. Second, the obvious lighter alternative does not work: widening the range so a stable release qualifies fails becausetoon_format0.1.0 is a stub whoseencode()raisesNotImplementedError. Moving it to an extra is the only fix that does not require a newtoon_formatrelease upstream.The second commit adds an up-front check. Refusing TOON only at render time means the command has already done its work: a search runs to completion, bills the organization, and buffers every page before discovering it has no encoder. That path was unreachable while
toon_formatwas a hard dependency and becomes a normal one once it moves to an extra, soensure_format_available()now guards the format as the CLI selects it. It shares a single message constant with the render-time guard informat_toon()so the two cannot drift apart, andformat_toon()keeps its own guard because it is public SDK API that callers reach directly. The check exempts help and completion: the root group callback runs before a subcommand parses its own--help, so without that exemptionlimacharlie --output toon sensor --helpwould fail on a default install.The rest of the second commit is correctness cleanup on the original: the CHANGELOG, README, CLI docs,
pyproject.tomlcomment, and the error message all asserted the uv breakage in the present tense and are now scoped to uv older than 0.12; thedevextra self-referenceslimacharlie[toon]instead of repeating the version range, leaving one place to bump whentoon_formatships a stable release;test_cli_reports_the_extra_without_a_tracebackasserted no traceback whilemain()prints one whenLC_DEBUGis set, so it failed for anyone with that variable exported; anddoc/getting-started.mdstill advertised a barepip install limacharliewith no mention that TOON became opt-in.Verification
Resolver behavior was checked against a wheel built from this branch, and the failure it fixes was reproduced against real PyPI first. Every uv from 0.5.31 through 0.11.33 installs
limacharlie==5.3.0when asked forlimacharlietoday; uv 0.12.0 installs 5.5.5 withtoon-format0.9.0b1. With this branch's wheel, uv 0.11.33 installs it with no flags and pulls notoon-format,<wheel>[toon]restores the encoder, and uv 0.12.0 and pip both resolve it normally.Full suite passes both ways, and CI's install path is unchanged because
[dev]still pulls the encoder:Live CLI on a default install with no encoder:
--output toonexits 1 with a one-line hint and no traceback,--help/sensor --help/completion bash/--output jsonall still work, and reinstalling the extra restores real TOON output. Bothpip install ".[dev]"andpip install -e ".[dev]"were confirmed to still pull the encoder through the new self-reference.Blast radius / isolation
Packaging metadata plus the CLI's output-format selection. The only runtime code touched is
limacharlie/output.py(one new function, one message constant) and the root group callback inlimacharlie/cli.py.Not affected: every other
--outputformat, all SDK APIs other thanformat_toon(), authentication, transport, and every command's own logic. No command module changes. Existing installs do not lose TOON on upgrade, becausepip install -U limacharliedoes not uninstall atoon_formatthat is already present; only fresh installs are affected. CI is unaffected on both GitHub Actions and Cloud Build, which install.[dev]; the Cloud Build wheel-smoke steps only runlimacharlie --version.Performance characteristics
No measurable change.
ensure_format_available()is one string comparison and one identity check against a module global, run once per invocation inside the callback that already importslimacharlie.output. The help exemption scanssys.argv, which is a handful of elements. No new imports on any startup path, so the lazy-import work that keeps--helpand--versionfast is preserved. A default install now resolves one fewer package.Notable contracts / APIs
limacharlie.output.ensure_format_available(fmt)is new and public. It raisesImportErrorfor a format whose encoder ships in an extra and is a no-op otherwise, including forNone.format_toon()keeps raisingImportErrorwith the same message when the encoder is missing. The message text changed (it now names the extra and the uv form); nothing should be matching on it, but it is a user-visible string.limacharlieno longer requirestoon_format, and a newtoonextra provides it. This is the backward-incompatible part, and it is why the CHANGELOG entry is marked as a behavior change.Rollback
Revert the
pyproject.tomlhunk to puttoon_formatback in[project.dependencies]; the up-front check degrades to a no-op on its own, since the encoder is then always importable. Reverting the whole branch is also safe, since nothing here is persisted or versioned outside package metadata.Related PRs
--prerelease=allowand a version floor. That workaround can be dropped for future releases once this lands, along with its noted trade-off that--prerelease=allowcould also admit a pre-release oflimacharlieitself.🤖 Generated with Claude Code