Keep the sub-app's deprecated flag in add_typer() - #1934
Open
VenishPaneliya wants to merge 1 commit into
Open
Conversation
add_typer() declared `deprecated` as a plain False while every other setting in the same signature uses the Default() sentinel, including `hidden` on the line above it. solve_typer_info_defaults() relies on that sentinel to tell "the caller passed this to add_typer()" apart from "the caller said nothing". A bare False is not a DefaultPlaceholder, so Priority 1 always matched and the callback and sub-app instance were never consulted: a sub-app that marked itself deprecated lost the flag as soon as it was added to a parent. Passing deprecated=True to add_typer() directly already worked, and the sibling `hidden` propagates correctly, so only the default was wrong. Typer.command() also uses a bare False, but it builds a CommandInfo, which never goes through solve_typer_info_defaults(), so it is left as is.
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.
Typer.add_typer()declares itsdeprecatedparameter as a plainFalse, while every other setting in the same signature uses theDefault()sentinel — includinghidden, which sits directly above it:solve_typer_info_defaults()uses that sentinel to tell "the caller passed this toadd_typer()" apart from "the caller said nothing":A bare
Falseis not aDefaultPlaceholder, so Priority 1 always fires and Priorities 2 and 3 are never reached. A sub-app that marked itself deprecated silently loses that flag the moment it is added to a parent.Reproduction
--helpon the parent:expected:
Why this is the default and not a judgement call
Two controls, same shape, both behave correctly:
sub_app = typer.Typer(hidden=True)— sibling,Default()-wrappedapp.add_typer(sub_app, deprecated=True)— passed at the call site(deprecated)sub_app = typer.Typer(deprecated=True)— this bugSo the plumbing is fine end to end; only the default is wrong.
TyperInfois constructed in exactly three places, and all three flow throughsolve_typer_info_defaults():deprecateddefaultTyper.__init__Default(False)Typer.callback()Default(False)Typer.add_typer()False←Typer.command()also uses a bareFalse, but that one builds aCommandInfo, which never goes through the solver — so it is correctly different and is left alone here.Change
One token:
] = False,→] = Default(False),.Defaultis already imported in the module.Tests
Added
test_add_typer_keeps_sub_app_deprecatedtotests/test_deprecation.py, parametrised over rich / non-rich the same waytests/test_hidden.pydoes, since the marker renders as(deprecated)under Rich and(DEPRECATED)without it.master: both parametrisations failruff checkandruff format --checkclean on both changed filesmypy typerreports the same 6 pre-existing errors before and after (identical set); none inmain.py