Skip to content

Commit

Permalink
Support | operator (Union) in PydanticRecursiveRef (#7892)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexmojaki committed Oct 24, 2023
1 parent aaf552d commit 93e4d23
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 0 deletions.
7 changes: 7 additions & 0 deletions pydantic/_internal/_forward_ref.py
@@ -1,6 +1,7 @@
from __future__ import annotations as _annotations

from dataclasses import dataclass
from typing import Union


@dataclass
Expand All @@ -14,3 +15,9 @@ def __call__(self) -> None:
"""Defining __call__ is necessary for the `typing` module to let you use an instance of
this class as the result of resolving a standard ForwardRef.
"""

def __or__(self, other):
return Union[self, other] # type: ignore

def __ror__(self, other):
return Union[other, self] # type: ignore
25 changes: 25 additions & 0 deletions tests/test_forward_ref.py
Expand Up @@ -711,6 +711,31 @@ class Foobar(BaseModel):
assert f.y.model_fields_set == {'x'}


@pytest.mark.skipif(sys.version_info < (3, 10), reason='needs 3.10 or newer')
def test_recursive_models_union(create_module):
module = create_module(
# language=Python
"""
from __future__ import annotations
from pydantic import BaseModel
from typing import TypeVar, Generic
T = TypeVar("T")
class Foo(BaseModel):
bar: Bar[str] | None = None
bar2: int | Bar[float]
class Bar(BaseModel, Generic[T]):
foo: Foo
"""
)
assert module.Foo.model_fields['bar'].annotation == typing.Optional[module.Bar[str]]
assert module.Foo.model_fields['bar2'].annotation == typing.Union[int, module.Bar[float]]
assert module.Bar.model_fields['foo'].annotation == module.Foo


def test_force_rebuild():
class Foobar(BaseModel):
b: int
Expand Down

0 comments on commit 93e4d23

Please sign in to comment.