Coverage for /pythoncovmergedfiles/medio/medio/src/pydantic/pydantic/_internal/_forward_ref.py: 70%
43 statements
« prev ^ index » next coverage.py v7.2.3, created at 2023-04-27 07:38 +0000
« prev ^ index » next coverage.py v7.2.3, created at 2023-04-27 07:38 +0000
1from __future__ import annotations as _annotations
3from dataclasses import dataclass, replace
4from typing import Any, Union
6from pydantic_core import core_schema
7from typing_extensions import Literal, TypedDict
9from ._typing_extra import TypeVarType
12class DeferredClassGetitem(TypedDict):
13 kind: Literal['class_getitem']
14 item: Any
17class DeferredReplaceTypes(TypedDict):
18 kind: Literal['replace_types']
19 typevars_map: dict[TypeVarType, Any]
22DeferredAction = Union[DeferredClassGetitem, DeferredReplaceTypes]
25@dataclass
26class PydanticRecursiveRef:
27 type_ref: str
29 __name__ = 'PydanticRecursiveRef'
30 __hash__ = object.__hash__
32 def __call__(self) -> None:
33 """
34 Defining __call__ is necessary for the `typing` module to let you use an instance of
35 this class as the result of resolving a standard ForwardRef
36 """
39@dataclass
40class PydanticForwardRef:
41 """
42 No-op marker class for (recursive) type references.
44 Most of the logic here exists to handle recursive generics.
45 """
47 schema: core_schema.CoreSchema
48 model: type[Any]
49 deferred_actions: tuple[DeferredAction, ...] = ()
51 __name__ = 'PydanticForwardRef'
52 __hash__ = object.__hash__
54 def __call__(self) -> None:
55 """
56 Defining __call__ is necessary for the `typing` module to let you use an instance of
57 this class as the result of resolving a standard ForwardRef
58 """
60 def __getitem__(self, item: Any) -> PydanticForwardRef:
61 updated_actions = self.deferred_actions + ({'kind': 'class_getitem', 'item': item},)
62 return replace(self, deferred_actions=updated_actions)
64 def replace_types(self, typevars_map: Any) -> PydanticForwardRef:
65 updated_actions = self.deferred_actions + ({'kind': 'replace_types', 'typevars_map': typevars_map},)
66 return replace(self, deferred_actions=updated_actions)
68 def resolve_model(self) -> type[Any] | PydanticForwardRef:
69 from ._generics import replace_types
71 model: type[Any] | PydanticForwardRef = self.model
72 for action in self.deferred_actions:
73 if action['kind'] == 'replace_types':
74 model = replace_types(model, action['typevars_map'])
75 elif action['kind'] == 'class_getitem':
76 model = model[action['item']] # type: ignore[index]
77 else:
78 raise ValueError(f'Unexpected action: {action}')
79 return model