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
X | Y union syntax breaks GenericModel #4146
Comments
Same thing with subscriptable types, with somehow simpler example: # 1.py
from __future__ import annotations
from pydantic import BaseModel
class Model(BaseModel):
foo: list[str]
Obviously, python3.8 cannot evaluate |
While i believe #4146 (comment) is answered in #2314 (comment), I'd love to bump the original issue with a slightly reduced example. Output of
from typing import Generic, TypeVar
import pydantic
from pydantic import generics
DataT = TypeVar("DataT")
class MyGenericModel(generics.GenericModel, Generic[DataT]):
generic: list[DataT] | None
class A(pydantic.BaseModel):
wrapper: MyGenericModel[int] results in
The same with Union from typing import Generic, TypeVar, Union
import pydantic
from pydantic import generics
DataT = TypeVar("DataT")
class MyGenericModel(generics.GenericModel, Generic[DataT]):
generic: Union[list[DataT], None]
class A(pydantic.BaseModel):
wrapper: MyGenericModel[int] seems to be working without the issue. |
A slightly more reduced example would be: from pydantic import generics
generics.replace_types(list[str] | None, {str: int}) I guess the problem is that |
For what it's worth, on the #4970 PR, I checked that the following code runs without issue (on Python 3.11 anyway): from typing import Generic, TypeVar
import pydantic
DataT = TypeVar("DataT")
class MyGenericModel(pydantic.BaseModel, Generic[DataT]):
generic: list[DataT] | None
class A(pydantic.BaseModel):
wrapper: MyGenericModel[int]
m = MyGenericModel[int](generic=None)
print(A(wrapper=m))
# wrapper=MyGenericModel[int](generic=None) |
* Fix X | Y union syntax breaks GenericModel (#4146) * Update changes/4146-thenx.md Co-authored-by: ⬢ Samuel Colvin <s@muelcolvin.com> * Improve tests * Recreate newstyle union via typing._UnionGenericAlias * Add basic pep-604 union args order caching detection test --------- Co-authored-by: ⬢ Samuel Colvin <s@muelcolvin.com>
weird pydantic bug? issue: pydantic/pydantic#4146
Since this is working on V2, I'll be closing this issue. 🙏 |
I can reproduce it on Mac and windows with Python 3.9 pydantic.version.VERSION =2.2.1 from __future__ import annotations
from pydantic import BaseModel
class Model(BaseModel):
foo: list[str]
boo: int | str TypeError: unsupported operand type(s) for |: 'type' and 'type'
|
PEP604-syntax requires python>=3.10 |
With Maybe catch this error and return a more meaningful message? |
Bug
Output of
python -c "import pydantic.utils; print(pydantic.utils.version_info())"
:Python 3.10 incorporated PEP 604, which added syntax for writing Unions as
X | Y
, instead oftyping.Union[X, Y]
. It seems that when this syntax is used in combination with TypeVars as part of aGenericModel
, the binding of TypeVars to their types fails.Below is first a working example using
typing.Union
, followed by a non-working example using|
syntax, with the stack trace. The example seeks to construct aRelationship
GenericModel, and aBidirectionalMultiRelationship
model which contains a list of eitherRelationship[A, B]
orRelationship[B, A]
models:On inspection I found that at the point that the exception is thrown,
origin_type
istypes.UnionType
, where it should beRelationship
.Apologies if I missed an existing issue for this. I couldn't find anything in my search.
The text was updated successfully, but these errors were encountered: