lebrice / SimpleParsing

Simple, Elegant, Typed Argument Parsing with argparse
MIT License
384 stars 46 forks source link

Allow for None values in serialized namespaces #257

Closed LTluttmann closed 1 year ago

LTluttmann commented 1 year ago

Is your feature request related to a problem? Please describe. Currently, when reading a serialized dataclass which contains None values, an error occurs during decoding the serialized data.

To reproduce

from dataclasses import dataclass
from simple_parsing.helpers import Serializable
import tempfile

@dataclass
class A(Serializable):
    a: float = None

a = A()

with tempfile.NamedTemporaryFile("w+", suffix=".json") as fp:
    a.save(fp.name)
    b = A.load(fp.name)

This raises the following error: "float() argument must be a string or a real number, not 'NoneType'".

Describe the solution you'd like The error is raised in the decode_field function, here. One solution would be to insert an if-else statement like so:

if raw_value is None:
    field_value = None
else:
    field_value = decode_field(
        field, raw_value, containing_dataclass=cls, drop_extra_fields=drop_extra_fields
    )

However, I don't know if this might introduce problems elsewhere or with other edge cases. Tests are still working, though

Describe alternatives you've considered Maybe, there is also a workaround I'm not aware of

lebrice commented 1 year ago

Hey @LTluttmann , thanks for posting.

Hmm, the annotation says it's a float, so it's expected for the serialization to fail if the value is None. Perhaps you could try with float | None or Optional[float] as an annotation? (Those should work correctly)

LTluttmann commented 1 year ago

oh wow, thanks! Optional[float] is exactly what I was looking for and works just fine! I will close the issue then