SimpleParsing icon indicating copy to clipboard operation
SimpleParsing copied to clipboard

Serialization of Union[float, bool] fields

Open halirutan opened this issue 1 year ago • 1 comments

I'm "enhancing" existing code and have to work with some of the more questionable choices when it comes to types. In this particular case, a field can be either bool or float. When using serialization, it revealed a deficiency that I try to understand.

To Reproduce

from dataclasses import dataclass
from typing import Union
from simple_parsing import Serializable


@dataclass
class MyOptions(Serializable):
    value: Union[float, bool] = False


opt1 = MyOptions()
opt1.save("/tmp/opt1.json")
opt1_loaded = MyOptions.load("/tmp/opt1.json")
print(opt1_loaded)

When executing this, the value is deserialized as 0.0 and I also get a warning that this might happen. What I don't understand is that a custom decoding function is absolutely straightforward and does the trick. Why is the default behavior not able to handle such cases?

Here is what I used as decoding function

from simple_parsing.helpers.serialization import register_decoding_fn

def decode_boolean_float(raw_value):
    if isinstance(raw_value, float):
        return raw_value
    elif isinstance(raw_value, bool):
        return raw_value
    else:
        raise RuntimeError(f"Could not decode JSON value {raw_value}")

register_decoding_fn(Union[float, bool], decode_boolean_float)

Desktop macOS:

  • Version 0.1.3
  • Python 3.9.16

halirutan avatar Jun 13 '23 12:06 halirutan

Hi @halirutan , thanks for posting!

This is a nice bug. Indeed, I'd expect this to work as expected out-of-the-box. Good catch!

lebrice avatar Jun 19 '23 19:06 lebrice