Closed xbanke closed 3 years ago
Hey @xbanke -
This isn't the behavior I'm seeing:
>>> import typic, typing
...
...
... @typic.klass
... class Foo:
... a: typing.Union[float, int] = 5
...
...
>>> Foo(0.3)
Foo(a=0.3)
JFYI - this will result in every value becoming a float, since float(
You can see what the deserializer for a given Union will look like:
>>> import typic, typing
>>> proto = typic.protocol(typing.Union[float, int])
>>> print(proto.transmute.__raw__)
def deserializer__113127302304386461(val):
_, val = __eval(val) if isinstance(val, (str, bytes)) else (False, val)
vtype = val.__class__
try:
return float_des(val)
except (TypeError, ValueError, KeyError):
pass
try:
return int_des(val)
except (TypeError, ValueError, KeyError):
pass
raise ValueError(f"Value could not be deserialized into one of {names}: {val!r}")
If you're seeing all floats converted to ints, this is likely because you have a Union[int, float]
notated somewhere. As stated in the documentation, Union[int, float]
and Union[float, int]
have the same hash value, so will cause a hash collision.
Yes, @seandstewart , there really existes Union[int, float]
.
By the __raw__
function's defination, it tries to convert the given value sequentially, even if the value is just an instance of one of the union types but not the first one. I personally think this is not suitable. At least it should try to check the type firstly, and then try to convert one by one. The following code shows the weird behavior.
import typic, typing
@typic.klass
class Foo:
a: typing.Union[int, str] = 5
Foo('3.2') # Foo(a=3)
In order to support subclasses, it's better to use issubclass
.
def deserializer_5165268981554100199(val):
_, val = __eval(val) if isinstance(val, (str, bytes)) else (False, val)
vtype = val.__class__
if issubclass(vtype, types):
return val
try:
return int_des(val)
except (TypeError, ValueError, KeyError):
pass
try:
return float_des(val)
except (TypeError, ValueError, KeyError):
pass
raise ValueError(f"Value could not be deserialized into one of {names}: {val!r}")
Description