New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
First instantiation of generic Union model defines type coercion of models instantiated later #4474
Comments
Yep it's a bug. Since for python |
Good to hear!
What about nested models, say |
Is this new in v1.10? |
No, saw it first in 1.9.0 and then updated to check if it was still there in the newest version. It is probably as old as the current specification of the key in |
Humm, can't remember if that was new in 1.9 or 1.8. The question is whether we should fix this in a patch release of 1.10 or wait for V2? |
That’s obviously not for me to say, but personally I think it would have been nice with a patch of at least the basic (non-nested) case, as the bug is breaking several of my tests. |
This gets more complicated, as the more-or-less exact same issue is present in the from typing import get_args, List, Union
print(get_args(Union[int, float]))
print(get_args(Union[float, int]))
print(get_args(List[Union[float, int]]))
print(get_args(List[Union[int, float]])) Prints:
This is discussed in this CPython issue, which include comments by Guido, and which resulted in the following documentation change:
(from the current Python docs) This at least rules out a recursive solution using Thinking from the perspective of a downstream library depending on However, all of this does not disqualify the simple |
Confirmed, I think we should fix this in V1.10. PR welcome, it'll need to be pretty quick to make it into the next patch release #4472, but otherwise it can be included in the (inevitable) next patch release. |
I can give it a try. |
great, thanks. |
I'm getting the following mypy errors:
Which seems to be a bug in mypy: python/mypy#4625 Any thoughts on how to handle this? |
hard without seeing the change, create the PR so I can see it. |
Basically, the type of the Anyway, I'll add a test and submit the PR for you to see. |
I'd love to include this fix in v1.10.2, any chance you can submit the PR asap so I can review and merge it? |
Sorry for the delay. The mypy issue caused the commit to fail, so had to do some acrobatics to be able to create the PR |
just add |
Next time I'll do that... 😅 |
Initial Checks
Description
When pydantic generic models are instantiated with Unions, the order of a particular set of types are fixed by the first instantiation, e.g.:
prints
While changing the order of the instantiations changes type coercion of both models:
In pydantic, type coercion of Union models depends on the order of the types. However, as explained in the documentation on Unions:
I think this should be considered a bug in pydantic, even though the user is warned against 'unexpected behaviour' combined with other code that depend on Union type equality. The unexpected behaviour in this case is caused by pydantic itself, there is no "matching based on the Union type order inside other type definitions" in the example code, nor are any third-party code imported. It is not difficult to envision situations where this dependency could cause very hard-to-find bugs.
It seems the cause of the error is the
_generic_types_cache
ingenerics.py
, which caches the first Union model and uses this as the blueprint of later matching models (i.e. with the same set of types).Setting
smart_union
toTrue
has no impact.Related to #2835.
Example Code
No response
Python, Pydantic & OS Version
Affected Components
.dict()
and.json()
construct()
, pickling, private attributes, ORM modeThe text was updated successfully, but these errors were encountered: