You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
from __future__ importannotationsfromargparse_dataclassimportdataclass@dataclassclassMyArgs:
foo: int=0bar: str='hello'baz: bool=Falsedefmain():
print(MyArgs.parse_args())
if__name__=='__main__':
main()
$ python3 targ.py
Traceback (most recent call last):
File "/Users/ibadawi/targ.py", line 4, in<module>
@dataclass
^^^^^^^^^
File "/Users/ibadawi/Library/Python/3.11/lib/python/site-packages/argparse_dataclass.py", line 474, in dataclass
return wrap(cls)
^^^^^^^^^
File "/Users/ibadawi/Library/Python/3.11/lib/python/site-packages/argparse_dataclass.py", line 465, in wrap
cls.parse_args = staticmethod(ArgumentParser(cls).parse_args)
^^^^^^^^^^^^^^^^^^^
File "/Users/ibadawi/Library/Python/3.11/lib/python/site-packages/argparse_dataclass.py", line 423, in __init__
_add_dataclass_options(options_class, self)
File "/Users/ibadawi/Library/Python/3.11/lib/python/site-packages/argparse_dataclass.py", line 374, in _add_dataclass_options
parser.add_argument(*args, **kwargs)
File "/usr/local/Cellar/[email protected]/3.11.2_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/argparse.py", line 1448, in add_argument
raise ValueError('%r is not callable' % (type_func,))
ValueError: 'int' is not callable
Removing from __future__ import annotations works fine and prints MyArgs(foo=0, bar='hello', baz=False) as expected.
It looks like the types as returned by dataclasses.fields() are just strings in this case. I'm not super familiar with writing code to process annotations but a workaround might be to use typing.get_type_hints() instead of dataclasses.fields() to get at the field types:
typing.get_type_hints(MyArgs):
{'bar': <class 'str'>, 'baz': <class 'bool'>, 'foo': <class 'int'>}
dataclasses.fields(MyArgs):
(Field(name='foo',type='int',default=0,default_factory=<dataclasses._MISSING_TYPE object at 0x10b1d5610>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD),
Field(name='bar',type='str',default='hello',default_factory=<dataclasses._MISSING_TYPE object at 0x10b1d5610>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD),
Field(name='baz',type='bool',default=False,default_factory=<dataclasses._MISSING_TYPE object at 0x10b1d5610>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD))
The text was updated successfully, but these errors were encountered:
Personally I never do this import because it has caused problems in the past with other libraries but I would be willing to accept a PR that addresses this.
ymd-h
added a commit
to ymd-h/argparse_dataclass
that referenced
this issue
Jun 6, 2023
When importing __future__.annotations, class annotations are evaluated
lazily, and dataclasses.Field.type becomes str instead of actual type.
To access its accutual type, we patch the member.
Ref: mivade#47
With the below script, I get an exception:
Removing
from __future__ import annotations
works fine and printsMyArgs(foo=0, bar='hello', baz=False)
as expected.It looks like the types as returned by
dataclasses.fields()
are just strings in this case. I'm not super familiar with writing code to process annotations but a workaround might be to usetyping.get_type_hints()
instead ofdataclasses.fields()
to get at the field types:The text was updated successfully, but these errors were encountered: