I am trying to use mypy to type check my program. The program uses argparse to parse command line arguments. I want to add type hints for the command line arguments.
import argparse
import typing
# define example types and a function that uses them
Seconds = typing.NewType("Seconds", float)
Minutes = typing.NewType("Minutes", float)
def sec_to_min(s: Seconds) -> Minutes:
return Minutes(s / 60)
# specify arguments and parse them
parser = argparse.ArgumentParser()
parser.add_argument("-t", "--time", default=1., type=float,
help="time in seconds")
args = parser.parse_args()
try:
# mypy reveals type Any
reveal_type(args.time)
except NameError:
pass
# (1) passes type check
seconds: Seconds = args.time
# (2) passes type check
sec_to_min(args.time)
I would like mypy to recognize args.time
as Seconds
. The current code should recognize args.time
as float and complain since passing a float to sec_to_min
complains as well.
I tried changing the type
argument of add_argument
to type=lambda x: Seconds(float(x))
. This had no effect, mypy still identified args.time
as any
.
As mentioned here, I have also tried to provide a custom NameSpace. This changed the revealed type of args.time
to Seconds
. I would like to avoid this, since I would have to duplicate the name for every argument and the default value from add_argument
is overridden by the custom namespace.
class TypedNameSpace(argparse.Namespace):
def __init__(self, *args, **kwargs):
self.time: Seconds = Seconds(0.)
super(TypedNameSpace, self).__init__(*args, **kwargs)