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
compound type (Union) gets preferentially parsed as string #3321
Comments
I believe this is intended. From the Unions section of the docs, emphasis mine:
|
Thanks for the quick reply and explanation! I would suggest changing this behavior to simply not change any arguments that are already instances one of the allowed types in the union. The best argument I can think of for making this change is the following: The docs you linked above continue on to say:
However, it is not always clear what "the most specific type" is. In the example I gave above, we can see that using |
Awesome, that will solve it. Thank you! |
The ordering of unions is supposed to be ignored: https://github.com/python/cpython/blob/main/Lib/typing.py#L564 |
The ordering is ignored when a type checker is reading an annotation to determine what type a variable is. If we have But that's not what pydantic is doing. Pydantic is a parsing library, so when it sees that a value is supposed to be parsed into a Union, it has to decide which member to use. It can't parse something into a str and int simultaneously. It uses the order to make that decision in a predictable way. |
Regardless, though, looks like #2092 has landed! |
Yes, I eventually worked that out after hours of pulling my hair out. Unfortunately for someone who's very familiar with how mathematical unions are supposed to work, this behaviour was extremely surprising. |
Checks
Bug
Output of
python -c "import pydantic.utils; print(pydantic.utils.version_info())"
:output:
MyDataclass(c={'a': '1', 'b': 'True', 'c': 'd'})
expected output:
MyDataclass(c={'a': 1, 'b': True, 'c': 'd'})
As you can see from the repro above, it seems that the
str
component of theUnion
. If I change the order to[bool, int, str]
, the output becomes:MyDataclass(c={'a': True, 'b': True, 'c': 'd'})
. I'm not familiar at all with how the underlying code works, but my guess is that this is giving preference to types given their order in theUnion
. I find this behavior quite odd, especially considering that the objects in the input already conform to the types specified in the dataclass. Is this intended behavior?The text was updated successfully, but these errors were encountered: