-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Closed
Labels
questiontopic-type assignabilityRelated to type assignability support (involves type variable bounds, etc)Related to type assignability support (involves type variable bounds, etc)
Description
Initial Checks
- I confirm that I'm using Pydantic V2
Description
The below code builds (and correctly prints np.ndarray[100, np.uint8] as output) in version 2.9.2, but raises an exception in version 2.10.0 and later. Perhaps I should be using a different annotation for pytype, or there is an easier way of doing what I want to do (get the generic parameter at runtime), but this way of doing it used to work but fails now. Any suggestions of using a better method to do this are welcome of course.
Traceback (most recent call last):
File "C:\projects\playground\main.py", line 22, in <module>
x = BaseGeneric[np.ndarray[100, np.uint8]](name="x")
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\main.py", line 806, in __class_getitem__
submodel = _generics.create_generic_submodel(model_name, origin, args, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\_internal\_generics.py", line 137, in create_generic_submodel
created_model = meta(
^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\_internal\_model_construction.py", line 226, in __new__
complete_model_class(
File "C:\projects\playground\venv\Lib\site-packages\pydantic\_internal\_model_construction.py", line 658, in complete_model_class
schema = cls.__get_pydantic_core_schema__(cls, handler)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\main.py", line 697, in __get_pydantic_core_schema__
return handler(source)
^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\_internal\_schema_generation_shared.py", line 84, in __call__
schema = self._handler(source_type)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 612, in generate_schema
schema = self._generate_schema_inner(obj)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 881, in _generate_schema_inner
return self._model_schema(obj)
^^^^^^^^^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 693, in _model_schema
{k: self._generate_md_field_schema(k, v, decorators) for k, v in fields.items()},
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 1073, in _generate_md_field_schema
common_field = self._common_field_schema(name, field_info, decorators)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 1261, in _common_field_schema
schema = self._apply_annotations(
^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 2051, in _apply_annotations
schema = get_inner_schema(source_type)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\_internal\_schema_generation_shared.py", line 84, in __call__
schema = self._handler(source_type)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 2126, in new_handler
schema = metadata_get_schema(source, get_inner_schema)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\functional_validators.py", line 837, in __get_pydantic_core_schema__
original_schema = handler(source)
^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\_internal\_schema_generation_shared.py", line 84, in __call__
schema = self._handler(source_type)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 2032, in inner_handler
schema = self._generate_schema_inner(obj)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 886, in _generate_schema_inner
return self.match_type(obj)
^^^^^^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 988, in match_type
return self._match_generic_type(obj, origin)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 1030, in _match_generic_type
return self._subclass_schema(obj)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\projects\playground\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 1649, in _subclass_schema
raise TypeError(f'Expected a class, got {type_param!r}')
TypeError: Expected a class, got numpy.ndarray[100, numpy.uint8]
Example Code
from pydantic import BaseModel, SkipValidation, Field
import numpy as np
import typing
from typing import Generic, TypeVar, Annotated
import functools
_T = TypeVar("_T")
class BaseGeneric(BaseModel, Generic[_T]):
pytype: Annotated[type[_T], SkipValidation, Field(frozen=True, exclude=True)]
def __init__(self, **kwargs):
super().__init__(pytype=self._cls_get_pytype(), **kwargs)
@classmethod
@functools.cache
def _cls_get_pytype(cls) -> type[_T]:
return typing.get_args(cls.model_fields["pytype"].annotation)[0]
x = BaseGeneric[np.ndarray[100, np.uint8]](name="x")
print(x.pytype)
Python, Pydantic & OS Version
Works on: 2.9.2
Fails on: 2.10.0 and 2.10.2 that I tried
lewis-yeung
Metadata
Metadata
Assignees
Labels
questiontopic-type assignabilityRelated to type assignability support (involves type variable bounds, etc)Related to type assignability support (involves type variable bounds, etc)