MCPcopy
hub / github.com/pydantic/pydantic / __class_getitem__

Method __class_getitem__

pydantic/main.py:904–969  ·  view source on GitHub ↗
(
        cls, typevar_values: type[Any] | tuple[type[Any], ...]
    )

Source from the content-addressed store, hash-verified

902 """
903
904 def __class_getitem__(
905 cls, typevar_values: type[Any] | tuple[type[Any], ...]
906 ) -> type[BaseModel] | _forward_ref.PydanticRecursiveRef:
907 cached = _generics.get_cached_generic_type_early(cls, typevar_values)
908 if cached is not None:
909 return cached
910
911 if cls is BaseModel:
912 raise TypeError('Type parameters should be placed on typing.Generic, not BaseModel')
913 if not hasattr(cls, '__parameters__'):
914 raise TypeError(f'{cls} cannot be parametrized because it does not inherit from typing.Generic')
915 if not cls.__pydantic_generic_metadata__['parameters'] and Generic not in cls.__bases__:
916 raise TypeError(f'{cls} is not a generic class')
917
918 if not isinstance(typevar_values, tuple):
919 typevar_values = (typevar_values,)
920
921 # For a model `class Model[T, U, V = int](BaseModel): ...` parametrized with `(str, bool)`,
922 # this gives us `{T: str, U: bool, V: int}`:
923 typevars_map = _generics.map_generic_model_arguments(cls, typevar_values)
924 # We also update the provided args to use defaults values (`(str, bool)` becomes `(str, bool, int)`):
925 typevar_values = tuple(v for v in typevars_map.values())
926
927 if _utils.all_identical(typevars_map.keys(), typevars_map.values()) and typevars_map:
928 submodel = cls # if arguments are equal to parameters it's the same object
929 _generics.set_cached_generic_type(cls, typevar_values, submodel)
930 else:
931 parent_args = cls.__pydantic_generic_metadata__['args']
932 if not parent_args:
933 args = typevar_values
934 else:
935 args = tuple(_generics.replace_types(arg, typevars_map) for arg in parent_args)
936
937 origin = cls.__pydantic_generic_metadata__['origin'] or cls
938 model_name = origin.model_parametrized_name(args)
939 params = tuple(
940 dict.fromkeys(_generics.iter_contained_typevars(typevars_map.values()))
941 ) # use dict as ordered set
942
943 with _generics.generic_recursion_self_type(origin, args) as maybe_self_type:
944 cached = _generics.get_cached_generic_type_late(cls, typevar_values, origin, args)
945 if cached is not None:
946 return cached
947
948 if maybe_self_type is not None:
949 return maybe_self_type
950
951 # Attempt to rebuild the origin in case new types have been defined
952 try:
953 # depth 2 gets you above this __class_getitem__ call.
954 # Note that we explicitly provide the parent ns, otherwise
955 # `model_rebuild` will use the parent ns no matter if it is the ns of a module.
956 # We don't want this here, as this has unexpected effects when a model
957 # is being parametrized during a forward annotation evaluation.
958 parent_ns = _typing_extra.parent_frame_namespace(parent_depth=2) or {}
959 origin.model_rebuild(_types_namespace=parent_ns)
960 except PydanticUndefinedAnnotation:
961 # It's okay if it fails, it just means there are still undefined types

Callers

nothing calls this directly

Calls 4

valuesMethod · 0.80
keysMethod · 0.80
model_rebuildMethod · 0.80

Tested by

no test coverage detected