Skip to content

Commit 73a2522

Browse files
authored
Fix fail_untyped for Dataclasses (#242)
add_dataclass_arguments now supports the fail_untyped parameter #241.
1 parent dc5cdac commit 73a2522

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ v4.19.0 (2022-12-27)
4848

4949
Added
5050
^^^^^
51+
- ``add_dataclass_arguments`` now supports the ``fail_untyped`` parameter
5152
- ``CLI`` now supports the ``fail_untyped`` and ``parser_class`` parameters.
5253
- ``bytes`` and ``bytearray`` registered on first use and decodes from standard
5354
Base64.

jsonargparse/signatures.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ def _add_signature_parameter(
312312
kwargs['required'] = True
313313
is_subclass_typehint = False
314314
is_final_class_typehint = is_final_class(annotation)
315+
is_pure_dataclass_typehint = is_pure_dataclass(annotation)
315316
dest = (nested_key+'.' if nested_key else '') + name
316317
args = [dest if is_required and as_positional else '--'+dest]
317318
if param.origin:
@@ -326,7 +327,7 @@ def _add_signature_parameter(
326327
if annotation in {str, int, float, bool} or \
327328
is_subclass(annotation, (str, int, float)) or \
328329
is_final_class_typehint or \
329-
is_pure_dataclass(annotation):
330+
is_pure_dataclass_typehint:
330331
kwargs['type'] = annotation
331332
elif annotation != inspect_empty:
332333
try:
@@ -353,7 +354,7 @@ def _add_signature_parameter(
353354
'sub_configs': sub_configs,
354355
'instantiate': instantiate,
355356
}
356-
if is_final_class_typehint:
357+
if is_final_class_typehint or is_pure_dataclass_typehint:
357358
kwargs.update(sub_add_kwargs)
358359
action = group.add_argument(*args, **kwargs)
359360
action.sub_add_kwargs = sub_add_kwargs
@@ -370,6 +371,7 @@ def add_dataclass_arguments(
370371
nested_key: str,
371372
default: Optional[Union[Type, dict]] = None,
372373
as_group: bool = True,
374+
fail_untyped: bool = True,
373375
**kwargs
374376
) -> List[str]:
375377
"""Adds arguments from a dataclass based on its field types and docstrings.
@@ -379,6 +381,7 @@ def add_dataclass_arguments(
379381
nested_key: Key for nested namespace.
380382
default: Value for defaults. Must be instance of or kwargs for theclass.
381383
as_group: Whether arguments should be added to a new argument group.
384+
fail_untyped: Whether to raise exception if a required parameter does not have a type.
382385
383386
Returns:
384387
The list of arguments added.
@@ -413,6 +416,7 @@ def add_dataclass_arguments(
413416
nested_key,
414417
params[field.name],
415418
added_args,
419+
fail_untyped=fail_untyped,
416420
default=defaults.get(field.name, inspect_empty),
417421
)
418422

jsonargparse_tests/test_signatures.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,32 @@ class MyDataClass:
15711571
self.assertEqual({'a': 1.2, 'b': 3.4}, cfg['a2'])
15721572

15731573

1574+
def test_dataclass_fail_untyped(self):
1575+
1576+
class MyClass:
1577+
def __init__(self, c1) -> None:
1578+
self.c1 = c1
1579+
1580+
@dataclasses.dataclass
1581+
class MyDataclass:
1582+
a1: MyClass
1583+
a2: str = "a2"
1584+
a3: str = "a3"
1585+
1586+
parser = ArgumentParser(exit_on_error=False)
1587+
parser.add_argument('--cfg', type=MyDataclass, fail_untyped=False)
1588+
1589+
with mock_module(MyDataclass, MyClass) as module:
1590+
class_path = f'"class_path": "{module}.MyClass"'
1591+
init_args = '"init_args": {"c1": 1}'
1592+
cfg = parser.parse_args(['--cfg.a1={'+class_path+', '+init_args+'}'])
1593+
cfg = parser.instantiate_classes(cfg)
1594+
self.assertIsInstance(cfg['cfg'], MyDataclass)
1595+
self.assertIsInstance(cfg['cfg'].a1, MyClass)
1596+
self.assertIsInstance(cfg['cfg'].a2, str)
1597+
self.assertIsInstance(cfg['cfg'].a3, str)
1598+
1599+
15741600
def test_compose_dataclasses(self):
15751601

15761602
@dataclasses.dataclass

0 commit comments

Comments
 (0)