diff --git a/dcargs/_fields.py b/dcargs/_fields.py index 412e84b3..4f9d0cf9 100644 --- a/dcargs/_fields.py +++ b/dcargs/_fields.py @@ -530,7 +530,7 @@ def _ensure_dataclass_instance_used_as_default_is_frozen( frozen.""" assert dataclasses.is_dataclass(default_instance) cls = type(default_instance) - if not cls.__dataclass_params__.frozen: + if not cls.__dataclass_params__.frozen: # type: ignore warnings.warn( f"Mutable type {cls} is used as a default value for `{field.name}`. This is" " dangerous! Consider using `dataclasses.field(default_factory=...)` or" @@ -566,7 +566,9 @@ def _get_dataclass_field_default( # Try grabbing default from dataclass field. if field.default not in MISSING_SINGLETONS: default = field.default - if dataclasses.is_dataclass(default): + # Note that dataclasses.is_dataclass() will also return true for dataclass + # _types_, not just instances. + if type(default) is not type and dataclasses.is_dataclass(default): _ensure_dataclass_instance_used_as_default_is_frozen(field, default) return default diff --git a/tests/test_dcargs.py b/tests/test_dcargs.py index e01c86b6..6c474064 100644 --- a/tests/test_dcargs.py +++ b/tests/test_dcargs.py @@ -468,6 +468,19 @@ def main(x: Callable[[int], int] = lambda x: x * 2) -> Callable[[int], int]: dcargs.cli(main, args=["--x", "something"]) +def test_fixed_dataclass_type(): + @dataclasses.dataclass + class Dummy: + pass + + def main(x: Callable = Dummy) -> Callable: + return x + + assert dcargs.cli(main, args=[]) is Dummy + with pytest.raises(SystemExit): + dcargs.cli(main, args=["--x", "something"]) + + def test_missing_singleton(): assert dcargs.MISSING is copy.deepcopy(dcargs.MISSING)