8000 Numpy array alias as type regression between 2.9.2 and 2.10.0 (and later) · Issue #11000 · pydantic/pydantic · GitHub
[go: up one dir, main page]

Skip to content
Numpy array alias as type regression between 2.9.2 and 2.10.0 (and later) #11000
@DenSinH

Description

@DenSinH

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

Metadata

Metadata

Assignees

Labels

questiontopic-type assignabilityRelated to type assignability support (involves type variable bounds, etc)

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    0