argparse support of/by argparse

Chris Angelico rosuav at gmail.com
Mon Jul 12 15:33:45 EDT 2021


On Tue, Jul 13, 2021 at 5:22 AM lucas <lucas at bourneuf.net> wrote:
>
> Hello everyone,
>
> Let us consider this patch of code:
>
>      import argparse
>
>      def parse_cli() -> argparse.Namespace:
>          parser = argparse.ArgumentParser()
>          parser.add_argument('n', type=int)
>          return parser.parse_args()
>
>      args = parse_cli()
>      print(args.n + ' ')  # type error
>
> Running CPython on it will raise a TypeError, and running Mypy on it
> will indicate that no issues were found.
>
> I was wondering if there is any way for me to have mypy detecting the
> args.n type, based on the type keyword of the parser.add_argument function ?
>
> It appears that some type annotations were added to tierce party
> modules, provided by mypy itself. Is there a technical issue preventing
> such work to be made for argparse (or other CLI ; i didn't find anything
> for others either)
>

Seems complicated, since it depends on a lot of run-time information.
What if you flip the problem on its head? Instead of creating the
argparser and letting that govern the types, maybe create a dataclass,
and then programmatically build the parser.

from dataclasses import dataclass
import argparse

@dataclass
class Args:
    n: int

def parse_cli() -> Args:
    parser = argparse.ArgumentParser()
    for field, typ in Args.__dataclass_fields__.items():
        if hasattr(typ, "type"): typ = typ.type # Python 3.10 changed
things a bit
        parser.add_argument(field, type=typ)
    return Args(**vars(parser.parse_args()))

args = parse_cli()
print(args.n + ' ')


Only barely tested it and didn't try MyPy, but that's the basic idea.
You'd have to figure out the tidiest way to define all the other
attributes of your arguments (help text, etc), but ideally, all the
info should be able to be coded in the dataclass.

Incidentally, you could choose to make parse_cli into a classmethod of
Args. Might be cleaner.

ChrisA


More information about the Python-list mailing list