(
cls, typevar_values: type[Any] | tuple[type[Any], ...]
)
| 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 |
nothing calls this directly
no test coverage detected