Coverage for pydantic/_internal/_core_metadata.py: 100.00%

34 statements  

« prev     ^ index     » next       coverage.py v7.5.4, created at 2024-07-03 19:29 +0000

1from __future__ import annotations as _annotations 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

2 

3import typing 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

4from typing import Any 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

5 

6import typing_extensions 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

7 

8if typing.TYPE_CHECKING: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

9 from ._schema_generation_shared import ( 

10 CoreSchemaOrField as CoreSchemaOrField, 

11 ) 

12 from ._schema_generation_shared import ( 

13 GetJsonSchemaFunction, 

14 ) 

15 

16 

17class CoreMetadata(typing_extensions.TypedDict, total=False): 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

18 """A `TypedDict` for holding the metadata dict of the schema. 

19 

20 Attributes: 

21 pydantic_js_functions: List of JSON schema functions. 

22 pydantic_js_prefer_positional_arguments: Whether JSON schema generator will 

23 prefer positional over keyword arguments for an 'arguments' schema. 

24 """ 

25 

26 pydantic_js_functions: list[GetJsonSchemaFunction] 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

27 pydantic_js_annotation_functions: list[GetJsonSchemaFunction] 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

28 

29 # If `pydantic_js_prefer_positional_arguments` is True, the JSON schema generator will 

30 # prefer positional over keyword arguments for an 'arguments' schema. 

31 pydantic_js_prefer_positional_arguments: bool | None 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

32 

33 pydantic_typed_dict_cls: type[Any] | None # TODO: Consider moving this into the pydantic-core TypedDictSchema 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

34 

35 

36class CoreMetadataHandler: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

37 """Because the metadata field in pydantic_core is of type `Any`, we can't assume much about its contents. 

38 

39 This class is used to interact with the metadata field on a CoreSchema object in a consistent 

40 way throughout pydantic. 

41 """ 

42 

43 __slots__ = ('_schema',) 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

44 

45 def __init__(self, schema: CoreSchemaOrField): 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

46 self._schema = schema 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

47 

48 metadata = schema.get('metadata') 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

49 if metadata is None: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

50 schema['metadata'] = CoreMetadata() 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL

51 elif not isinstance(metadata, dict): 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

52 raise TypeError(f'CoreSchema metadata should be a dict; got {metadata!r}.') 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL

53 

54 @property 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

55 def metadata(self) -> CoreMetadata: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

56 """Retrieves the metadata dict from the schema, initializing it to a dict if it is None 

57 and raises an error if it is not a dict. 

58 """ 

59 metadata = self._schema.get('metadata') 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

60 if metadata is None: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

61 self._schema['metadata'] = metadata = CoreMetadata() 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL

62 if not isinstance(metadata, dict): 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

63 raise TypeError(f'CoreSchema metadata should be a dict; got {metadata!r}.') 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL

64 return metadata 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

65 

66 

67def build_metadata_dict( 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

68 *, # force keyword arguments to make it easier to modify this signature in a backwards-compatible way 

69 js_functions: list[GetJsonSchemaFunction] | None = None, 

70 js_annotation_functions: list[GetJsonSchemaFunction] | None = None, 

71 js_prefer_positional_arguments: bool | None = None, 

72 typed_dict_cls: type[Any] | None = None, 

73 initial_metadata: Any | None = None, 

74) -> Any: 

75 """Builds a dict to use as the metadata field of a CoreSchema object in a manner that is consistent 

76 with the CoreMetadataHandler class. 

77 """ 

78 if initial_metadata is not None and not isinstance(initial_metadata, dict): 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

79 raise TypeError(f'CoreSchema metadata should be a dict; got {initial_metadata!r}.') 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL

80 

81 metadata = CoreMetadata( 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

82 pydantic_js_functions=js_functions or [], 

83 pydantic_js_annotation_functions=js_annotation_functions or [], 

84 pydantic_js_prefer_positional_arguments=js_prefer_positional_arguments, 

85 pydantic_typed_dict_cls=typed_dict_cls, 

86 ) 

87 metadata = {k: v for k, v in metadata.items() if v is not None} 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

88 

89 if initial_metadata is not None: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

90 metadata = {**initial_metadata, **metadata} 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL

91 

92 return metadata 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL