2

I was using argparse in a project when I noticed the following:

  • VS Code shows type hints for the arguments of ArgumentParser.add_argument:

    add_argument(*name_or_flags: Text, action: Union[Text, Type[Action]]=..., nargs: Union[int, Text]=..., const: Any=..., default: Any=..., type: Union[Callable[[Text], _T], Callable[[str], _T], FileType]=..., choices: Iterable[_T]=..., required: bool=..., help: Optional[Text]=..., metavar: Optional[Union[Text, Tuple[Text, ...]]]=..., dest: Optional[Text]=..., version: Text=..., **kwargs: Any) -> Action
    param *name_or_flags: Text
    
    add_argument(dest, ..., name=value, ...)
    add_argument(option_string, option_string, ..., name=value, ...)
    
  • The source code of argparse does not have these hints (https://github.com/python/cpython/blob/master/Lib/argparse.py ):

        # =======================
        # Adding argument actions
        # =======================
        def add_argument(self, *args, **kwargs):
            """
            add_argument(dest, ..., name=value, ...)
            add_argument(option_string, option_string, ..., name=value, ...)
            """
    
            # if no positional args are supplied or only one is supplied and
            # it doesn't look like an option string, parse a positional
            # argument
    

How would I write a function in my own code that shows type hints in the same way (i.e. the function I write has *args and **kwargs as the arguments, but any user of the function can see the names and types of the expected kwargs)?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
BX21
  • 391
  • 6
  • 19

1 Answers1

3

That type information comes from the typeshed:

Typeshed contains external type annotations for the Python standard library and Python builtins, as well as third party packages as contributed by people external to those projects.

This data can e.g. be used for static analysis, type checking or type inference.

You can see the specific types for add_argument here:

def add_argument(self,
                 *name_or_flags: Text,
                 action: Union[Text, Type[Action]] = ...,
                 nargs: Union[int, Text] = ...,
                 const: Any = ...,
                 default: Any = ...,
                 type: Union[Callable[[Text], _T], Callable[[str], _T], FileType] = ...,
                 choices: Iterable[_T] = ...,
                 required: bool = ...,
                 help: Optional[Text] = ...,
                 metavar: Optional[Union[Text, Tuple[Text, ...]]] = ...,
                 dest: Optional[Text] = ...,
                 version: Text = ...,
                 **kwargs: Any) -> Action: ...

For your own code, you can just add those type hints in directly, unless you need to support older versions of Python (syntax available from 3.0 per PEP-3107, typing module available from 3.5 per PEP-0484).

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437