From cb05183d2b28fb6a78d4a6b8d00c16ae5be64970 Mon Sep 17 00:00:00 2001 From: David Robertson Date: Thu, 18 Aug 2022 19:30:21 +0100 Subject: [PATCH 1/4] argparse: type subparser helper's `add_parser` A drive-by. I grepped for TODO and this one seemed easy enough. --- stdlib/argparse.pyi | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/stdlib/argparse.pyi b/stdlib/argparse.pyi index 1b86a4e10cbb..6a6ba4ad281a 100644 --- a/stdlib/argparse.pyi +++ b/stdlib/argparse.pyi @@ -127,6 +127,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): _optionals: _ArgumentGroup _subparsers: _ArgumentGroup | None + # Note: the constructor arguments are also used in _SubParsersAction.add_parser. if sys.version_info >= (3, 9): def __init__( self, @@ -458,8 +459,43 @@ class _SubParsersAction(Action, Generic[_ArgumentParserT]): help: str | None = ..., metavar: str | tuple[str, ...] | None = ..., ) -> None: ... - # TODO: Type keyword args properly. - def add_parser(self, name: str, **kwargs: Any) -> _ArgumentParserT: ... + + # The signature of add_parser matches that of ArgumentParser.__init__, except + # add_parser returns an ArgumentParser. + if sys.version_info >= (3, 9): + def add_parser( + self, + prog: str | None = ..., + usage: str | None = ..., + description: str | None = ..., + epilog: str | None = ..., + parents: Sequence[_ArgumentParserT] = ..., + formatter_class: _FormatterClass = ..., + prefix_chars: str = ..., + fromfile_prefix_chars: str | None = ..., + argument_default: Any = ..., + conflict_handler: str = ..., + add_help: bool = ..., + allow_abbrev: bool = ..., + exit_on_error: bool = ..., + ) -> None: ... + else: + def add_parser( + self, + prog: str | None = ..., + usage: str | None = ..., + description: str | None = ..., + epilog: str | None = ..., + parents: Sequence[_ArgumentParserT] = ..., + formatter_class: _FormatterClass = ..., + prefix_chars: str = ..., + fromfile_prefix_chars: str | None = ..., + argument_default: Any = ..., + conflict_handler: str = ..., + add_help: bool = ..., + allow_abbrev: bool = ..., + ) -> _ArgumentParserT: ... + def _get_subactions(self) -> list[Action]: ... # undocumented From c816161e488eaa2b9cff520124523fef60be10d4 Mon Sep 17 00:00:00 2001 From: David Robertson Date: Fri, 19 Aug 2022 14:39:30 +0100 Subject: [PATCH 2/4] add missing `name` parameter Oops. Scan-read the docs without thinking. --- stdlib/argparse.pyi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/stdlib/argparse.pyi b/stdlib/argparse.pyi index 6a6ba4ad281a..57d6b4e06f4a 100644 --- a/stdlib/argparse.pyi +++ b/stdlib/argparse.pyi @@ -465,6 +465,8 @@ class _SubParsersAction(Action, Generic[_ArgumentParserT]): if sys.version_info >= (3, 9): def add_parser( self, + name: str, + *, prog: str | None = ..., usage: str | None = ..., description: str | None = ..., @@ -482,6 +484,8 @@ class _SubParsersAction(Action, Generic[_ArgumentParserT]): else: def add_parser( self, + name: str, + *, prog: str | None = ..., usage: str | None = ..., description: str | None = ..., From d1fc25fbc62991f1d5a8d5c55af667043c45e4df Mon Sep 17 00:00:00 2001 From: David Robertson Date: Fri, 19 Aug 2022 14:49:34 +0100 Subject: [PATCH 3/4] Add kwargs that don't get forward to parser ctor --- stdlib/argparse.pyi | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/stdlib/argparse.pyi b/stdlib/argparse.pyi index 57d6b4e06f4a..c70198a93784 100644 --- a/stdlib/argparse.pyi +++ b/stdlib/argparse.pyi @@ -460,13 +460,16 @@ class _SubParsersAction(Action, Generic[_ArgumentParserT]): metavar: str | tuple[str, ...] | None = ..., ) -> None: ... - # The signature of add_parser matches that of ArgumentParser.__init__, except - # add_parser returns an ArgumentParser. + # Note: `add_parser` accepts all kwargs of `ArgumentParser.__init__`. It also + # accepts its own `help` and `aliases` kwargs. if sys.version_info >= (3, 9): def add_parser( self, name: str, *, + help: str | None = ..., + aliases: Sequence[str] = ..., + # Kwargs from ArgumentParser constructor prog: str | None = ..., usage: str | None = ..., description: str | None = ..., @@ -486,6 +489,9 @@ class _SubParsersAction(Action, Generic[_ArgumentParserT]): self, name: str, *, + help: str | None = ..., + aliases: Sequence[str] = ..., + # Kwargs from ArgumentParser constructor prog: str | None = ..., usage: str | None = ..., description: str | None = ..., From 9dad0ec3de23aede6b02c30772002452574658a6 Mon Sep 17 00:00:00 2001 From: David Robertson Date: Fri, 19 Aug 2022 14:50:51 +0100 Subject: [PATCH 4/4] Fix typo in return type --- stdlib/argparse.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/argparse.pyi b/stdlib/argparse.pyi index c70198a93784..44f39c8c92d1 100644 --- a/stdlib/argparse.pyi +++ b/stdlib/argparse.pyi @@ -483,7 +483,7 @@ class _SubParsersAction(Action, Generic[_ArgumentParserT]): add_help: bool = ..., allow_abbrev: bool = ..., exit_on_error: bool = ..., - ) -> None: ... + ) -> _ArgumentParserT: ... else: def add_parser( self,