Coverage for pydantic/_internal/_schema_generation_shared.py: 88.89%

49 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-05-02 08:21 +0000

1"""Types and utility functions used by various other internal tools.""" 

2 

3from __future__ import annotations 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

4 

5from typing import TYPE_CHECKING, Any, Callable, Literal 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

6 

7from pydantic_core import core_schema 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

8 

9from ..annotated_handlers import GetCoreSchemaHandler, GetJsonSchemaHandler 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

10 

11if TYPE_CHECKING: 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

12 from ..json_schema import GenerateJsonSchema, JsonSchemaValue 

13 from ._core_utils import CoreSchemaOrField 

14 from ._generate_schema import GenerateSchema 

15 from ._namespace_utils import NamespacesTuple 

16 

17 GetJsonSchemaFunction = Callable[[CoreSchemaOrField, GetJsonSchemaHandler], JsonSchemaValue] 

18 HandlerOverride = Callable[[CoreSchemaOrField], JsonSchemaValue] 

19 

20 

21class GenerateJsonSchemaHandler(GetJsonSchemaHandler): 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

22 """JsonSchemaHandler implementation that doesn't do ref unwrapping by default. 

23 

24 This is used for any Annotated metadata so that we don't end up with conflicting 

25 modifications to the definition schema. 

26 

27 Used internally by Pydantic, please do not rely on this implementation. 

28 See `GetJsonSchemaHandler` for the handler API. 

29 """ 

30 

31 def __init__(self, generate_json_schema: GenerateJsonSchema, handler_override: HandlerOverride | None) -> None: 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

32 self.generate_json_schema = generate_json_schema 1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

33 self.handler = handler_override or generate_json_schema.generate_inner 1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

34 self.mode = generate_json_schema.mode 1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

35 

36 def __call__(self, core_schema: CoreSchemaOrField, /) -> JsonSchemaValue: 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

37 return self.handler(core_schema) 1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

38 

39 def resolve_ref_schema(self, maybe_ref_json_schema: JsonSchemaValue) -> JsonSchemaValue: 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

40 """Resolves `$ref` in the json schema. 

41 

42 This returns the input json schema if there is no `$ref` in json schema. 

43 

44 Args: 

45 maybe_ref_json_schema: The input json schema that may contains `$ref`. 

46 

47 Returns: 

48 Resolved json schema. 

49 

50 Raises: 

51 LookupError: If it can't find the definition for `$ref`. 

52 """ 

53 if '$ref' not in maybe_ref_json_schema: 1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

54 return maybe_ref_json_schema 1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

55 ref = maybe_ref_json_schema['$ref'] 1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

56 json_schema = self.generate_json_schema.get_schema_from_definitions(ref) 1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

57 if json_schema is None: 57 ↛ 58line 57 didn't jump to line 58 because the condition on line 57 was never true1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

58 raise LookupError( 

59 f'Could not find a ref for {ref}.' 

60 ' Maybe you tried to call resolve_ref_schema from within a recursive model?' 

61 ) 

62 return json_schema 1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

63 

64 

65class CallbackGetCoreSchemaHandler(GetCoreSchemaHandler): 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

66 """Wrapper to use an arbitrary function as a `GetCoreSchemaHandler`. 

67 

68 Used internally by Pydantic, please do not rely on this implementation. 

69 See `GetCoreSchemaHandler` for the handler API. 

70 """ 

71 

72 def __init__( 1abcdefghijklmnopqrstuvJKLMNOPwxyzABCDEFG

73 self, 

74 handler: Callable[[Any], core_schema.CoreSchema], 

75 generate_schema: GenerateSchema, 

76 ref_mode: Literal['to-def', 'unpack'] = 'to-def', 

77 ) -> None: 

78 self._handler = handler 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

79 self._generate_schema = generate_schema 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

80 self._ref_mode = ref_mode 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

81 

82 def __call__(self, source_type: Any, /) -> core_schema.CoreSchema: 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

83 schema = self._handler(source_type) 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

84 if self._ref_mode == 'to-def': 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

85 ref = schema.get('ref') 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

86 if ref is not None: 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

87 return self._generate_schema.defs.create_definition_reference_schema(schema) 1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

88 return schema 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

89 else: # ref_mode = 'unpack' 

90 return self.resolve_ref_schema(schema) 1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

91 

92 def _get_types_namespace(self) -> NamespacesTuple: 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

93 return self._generate_schema._types_namespace 1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

94 

95 def generate_schema(self, source_type: Any, /) -> core_schema.CoreSchema: 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

96 return self._generate_schema.generate_schema(source_type) 1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

97 

98 @property 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

99 def field_name(self) -> str | None: 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

100 return self._generate_schema.field_name_stack.get() 

101 

102 def resolve_ref_schema(self, maybe_ref_schema: core_schema.CoreSchema) -> core_schema.CoreSchema: 1abcdefghijkHIlmnopqrstuvJKLMNOPwxyzABCDEFG

103 """Resolves reference in the core schema. 

104 

105 Args: 

106 maybe_ref_schema: The input core schema that may contains reference. 

107 

108 Returns: 

109 Resolved core schema. 

110 

111 Raises: 

112 LookupError: If it can't find the definition for reference. 

113 """ 

114 if maybe_ref_schema['type'] == 'definition-ref': 1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

115 ref = maybe_ref_schema['schema_ref'] 1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

116 definition = self._generate_schema.defs.get_schema_from_ref(ref) 1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

117 if definition is None: 117 ↛ 118line 117 didn't jump to line 118 because the condition on line 117 was never true1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

118 raise LookupError( 

119 f'Could not find a ref for {ref}.' 

120 ' Maybe you tried to call resolve_ref_schema from within a recursive model?' 

121 ) 

122 return definition 1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

123 elif maybe_ref_schema['type'] == 'definitions': 123 ↛ 124line 123 didn't jump to line 124 because the condition on line 123 was never true1abcdefghijkHIlmnopqrstuvwxyzABCDEFG

124 return self.resolve_ref_schema(maybe_ref_schema['schema']) 

125 return maybe_ref_schema 1abcdefghijkHIlmnopqrstuvwxyzABCDEFG