SimpleParsing icon indicating copy to clipboard operation
SimpleParsing copied to clipboard

Unintuitive inconsistent behavior for `Optional` between builtin classes and `dataclass`es

Open anivegesana opened this issue 2 years ago • 1 comments

Describe the bug Builtin classes and enums are able to be set as default values in optional fields. dataclasses are not and the default value is replaced with a None.

To Reproduce

from simple_parsing import parse, field
from simple_parsing.helpers.serialization.serializable import to_dict
from enum import Enum
from dataclasses import dataclass
from typing import Optional

class E(Enum):
    E1 = 1
    E2 = 2


@dataclass
class A:
    a: int = 0


@dataclass
class Test:
    b: Optional[bool] = True
    i: Optional[int] = 1
    s: Optional[str] = "string"
    e: Optional[E] = E.E1
    a: Optional[A] = field(default_factory=A)


test = parse(Test)
print(to_dict(test))

Expected behavior I would expect a in this example to be nonnull since it has a default value.

$ python issue.py
{'b': True, 'i': 1, 's': 'string', 'a': A(a=0), 'e': 'E1'}

Actual behavior Instead the a field is None.

$ python issue.py
{'b': True, 'i': 1, 's': 'string', 'a': None, 'e': 'E1'}

Desktop:

  • Version: 0.1.4
  • Python version: 3.11.4

Additional context In addition, there is no way to toggle the optional fields to None if None isn't already the default. BooleanOptionalAction only sets the flag to False, but some classes like lightning.pytorch.callbacks.DeviceStatsMonitor have three modes (None/False/True) and that isn't that clearly representable yet. I think this will be easier though. The dataclass default issue seems more challenging.

anivegesana avatar Aug 14 '23 19:08 anivegesana

Hey there @anivegesana , sorry I somehow missed this. This is a good bug, thanks for highlighting it. I'll double-check that it hasnt been fixed since you posted this, and I'll hopefully get back to you.

lebrice avatar May 21 '25 22:05 lebrice