Closed jbcpollak closed 4 years ago
I would like to give a more realistic using:
@dataclass
class Circle:
type: Literal['circle'] = 'circle'
radius: float
@property
def area(self):
return math.pi*self.radius*self.radius
@dataclass
class Semicircle:
type: Literal['circle'] = 'semicircle'
radius: float
@property
def area(self):
return math.pi*self.radius*self.radius/2
This would be way clearer than:
@dataclass
class Circle_or_semicircle:
type: str
radius: float
@property
def area(self):
if self.type == 'circle':
return math.pi*self.radius*self.radius
elif self.type == 'semicircle':
return math.pi*self.radius*self.radius/2
else:
raise Error("neither circle nor semicircle")
It would be clearer in three ways:
isinstance()
, which is better for semantics;'circle'
nor 'semicircle'
, think about one day the server started to create arcs {"type": "arc", "radius": 0, "angle": 30}
, the error would be raised when dacite.from_dict
, at which time the error had been very clear.@jbcpollak thank you for reporting this issue.
Yes, it will be possible. I've just added Literal
support in https://github.com/konradhalas/dacite/commit/ce5d4039b888e5361f93dda3e194bab47e39ae5f and it should work with Union
as you described.
I will release new version soon.
@jbcpollak Deployed to PyPI 🎉
Fantastic, TY!
Hi @konradhalas - we just tried this and it turns out this doesn't work with Python 3.7.6. We aren't sure if we can upgrade to 3.8 or not (we are going to look into it), but I wanted to mention it.
I guess this is because in 3.7 Literal is in typing_extensions
and in 3.8 its been moved to typing
. I'm not sure if there is a good way around that.
Hi @jbcpollak - argh, you have right, I'm using typing
from 3.8. I would check if I can do something reasonable on my side, but TBH I don't want to add dependencies to dacite
.
Yeah - I think you'd have to add code to check for the Python version then programmatically choose which library to import from.
We can't upgrade to 3.8 yet, a library we depend on doesn't support it.
Guess I'm stuck with not being able to use it... I'm on 3.7. GCP Cloud Functions are still in beta for 3.8 so I have to use 3.7.6 for production. I'm using dacite with typing_extensions.
haha, the docs dont have it out of beta at least maybe I can get the project updated now. either way, it would be nice for 3.7 devs if @jbcpollak's suggestion about programmatic version checking was available.
@Gideon-Felt in the meantime you can use this in your requirements.txt file:
git+https://github.com/Pickle-Robot/dacite/@master#egg=dacite
We are still stuck on 3.7.6 as well and this works for us.
I'd like to be able to deserialize from_dict() a Union of overlapping types based on the Literal values. Is that possible?