Skip to content
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

Add support for typing.Self (fix #5992) #9023

Merged
merged 10 commits into from Mar 25, 2024
2 changes: 0 additions & 2 deletions pydantic/_internal/_generate_schema.py
Expand Up @@ -859,8 +859,6 @@ def match_type(self, obj: Any) -> core_schema.CoreSchema: # noqa: C901

if _typing_extra.is_dataclass(obj):
return self._dataclass_schema(obj, None)
# if _typing_extra.is_self(obj):
# pass
res = self._get_prepare_pydantic_annotations_for_known_type(obj, ())
if res is not None:
source_type, annotations = res
Expand Down
37 changes: 36 additions & 1 deletion tests/test_types_self.py
Expand Up @@ -37,4 +37,39 @@ class SelfRef(BaseModel):
ValidationError,
match=r'ref\.ref\s+Input should be a valid dictionary or instance of SelfRef \[type=model_type,',
):
SelfRef(data=1, ref={'data': 2, 'ref': 3}).model_dump() == {'data': 1, 'ref': {'data': 2, 'ref': None}}
SelfRef(data=1, ref={'data': 2, 'ref': 3}).model_dump()


def test_recursive_model_with_subclass(Self):
"""
Youssefares marked this conversation as resolved.
Show resolved Hide resolved
Self refs should be valid in covariant direction
"""

class SelfRef(BaseModel):
data: int
ref: Self | None = None

class SubSelfRef(SelfRef):
pass
sydney-runkle marked this conversation as resolved.
Show resolved Hide resolved

assert SubSelfRef(data=1, ref=SubSelfRef(data=2)).model_dump() == {'data': 1, 'ref': {'data': 2, 'ref': None}}
assert SelfRef(data=1, ref=SubSelfRef(data=2)).model_dump() == {'data': 1, 'ref': {'data': 2, 'ref': None}}


def test_recursive_model_with_subclass_invalid(Self):
"""
Self refs are invalid in contravariant direction
"""

class SelfRef(BaseModel):
data: int
ref: Self | None = None

class SubSelfRef(SelfRef):
pass

with pytest.raises(
ValidationError,
match=r'ref\s+Input should be a valid dictionary or instance of SubSelfRef \[type=model_type,',
):
SubSelfRef(data=1, ref=SelfRef(data=2)).model_dump()