Replies: 2 comments 6 replies
-
For what it is worth, I've been using this pattern extensively in Notional (specifically in the |
Beta Was this translation helpful? Give feedback.
-
Glad to hear you are enjoying pydantic! I'm struggling to follow the request here super closely, but my understanding is that you are looking for something that behaves like a discriminated union, but perhaps doesn't require a discriminator? And maybe is able to infer what the members of the discriminated union should be by registering subclasses during That said, I'll warn that this will probably break in at least some subtle ways in the soon-to-be-released v2 due to the way parsing has been moved into pydantic-core. BUT — in pydantic-core, we have much more general functionality for doing discriminated unions that goes beyond the presence of a single shared literal attribute. So, in principle in v2, it's possible to create a pydantic-core schema that will call a function on the input, and has a mapping of the return value of that function to the type it should be parsed as. We haven't exposed an easy way to define this quite yet, but I do think we can make this whole pattern more ergonomic if we do things right. You can see some more detail in the documentation of I'll also add that there was some discussion of adding a notion of "sealed" types in python at the bottom of PEP591, and I've seen this document proposing it in more depth, but I think it has been rejected (or at least deferred). I think that would make some of the implicit polymorphic stuff easier in common cases since it would be possible to know all the subclasses that should be considered without needing to manually create unions/etc. |
Beta Was this translation helpful? Give feedback.
-
Hi,
Just started using pydantic, and can't get over how good it is.
I've started using it to solve a problem that has often bugged me info python. And so, I have a question about the ability to do type-aware deserialisation of classes without the need to go via a container class and a discriminator.
I'm using pydantic 1.10 and python 3.10.
I started by shamelessly copying #3091 (h/t @PrettyWood & @jheddings) and then wondered if it was possible to pull out the logic into a general class.
So I tried (disclaimer - I'm bad at names):
Then the definition of
Animal
,Cat
, etc from the linked discussion becomes:And this seems to work. I can construct cat, dog, etc. explicitly, without needing to set type, and this round trips cleanly to/from json but keeping the specific
Cat
implementation as thepet
member rather than degrading to a generalAnimal
. e.g.:Question
Sorry it took a while to get to it, but my question is, "what am I missing?".
Or to put it another way, this seems like a useful pattern to have, is there a good reason why this pattern isn't more widely published (I mean, it wasn't hard but it took several goes before I found the right combination of keywords that threw up #3091), or even more ambitiously, why a base class like this doesn't ship as part of pydantic? I will be the first to admit, this back-of-the-napkin implementation is a bit unpolished (suggestions welcome!), and the repetition of the type property three times is annoying, but the behaviour seems sound, and it's not really any worse than the sort of thing I have to do to make this work in jackson for Java.
One thing I did do different to the linked discussion #3091 was to remove
As it didn't seem to do anything... Validation of the json still seemed to work (e.g. omitting
breed
from a Dog json still throws a missing value error). And in fact with this present, I couldn't even construct the Person object in code (theme = Person...
bit above); it would blow up in_convert_to_real_type
because thedata
object is no longer the deserializeddict
from the json, but is in fact the Cat class. So maybe this is why; is that validator bit really important?Anyhoo, would love to know if I'm missing something before I start using this everywhere and then come to regret it.
Thanks!
Beta Was this translation helpful? Give feedback.
All reactions