Skip to content

TYP: compatibility with array API standard's typing #28665

@Saransh-cpp

Description

@Saransh-cpp

Describe the issue:

It looks like NumPy does not follow the array API standard's typing, or maybe I am doing something wrong here :(

For instance, the array.__add__ function should have the following type signature -

array.__add__(other: int | float | complex | array, /) → array

by mypy cannot find one in the overloads. See MWE below.

Reproduce the code example:

import numpy as np
import typing

Array = typing.TypeVar("Array", bound="SuperArray")

class SuperArray(typing.Protocol):
    def __add__(self: Array, other: int | float | complex | Array, /) -> Array: ...

def ident(array: SuperArray) -> SuperArray:
    return array

ident(np.eye(3))

Error message:

(.env) saransh@Saranshs-MacBook-Pro glass % python3 -m mypy test_mypy.py --show-error-end
test_mypy.py:12:7:12:15: error: Argument 1 to "ident" has incompatible type "ndarray[tuple[int, ...], dtype[float64]]"; expected "SuperArray"  [arg-type]
test_mypy.py:12:7:12:15: note: Following member(s) of "ndarray[tuple[int, ...], dtype[float64]]" have conflicts:
test_mypy.py:12:7:12:15: note:     Expected:
test_mypy.py:12:7:12:15: note:         def __add__(self, int | float | complex | ndarray[tuple[int, ...], dtype[float64]], /) -> ndarray[tuple[int, ...], dtype[float64]]
test_mypy.py:12:7:12:15: note:     Got:
test_mypy.py:12:7:12:15: note:         @overload
test_mypy.py:12:7:12:15: note:         def __add__(self, int | numpy.bool[builtins.bool], /) -> ndarray[tuple[int, ...], dtype[float64]]
test_mypy.py:12:7:12:15: note:         @overload
test_mypy.py:12:7:12:15: note:         def __add__(self, _SupportsArray[dtype[numpy.bool[builtins.bool]]] | _NestedSequence[_SupportsArray[dtype[numpy.bool[builtins.bool]]]] | builtins.bool | _NestedSequence[builtins.bool], /) -> ndarray[tuple[int, ...], dtype[float64]]
test_mypy.py:12:7:12:15: note:         @overload
test_mypy.py:12:7:12:15: note:         def __add__(self, _SupportsArray[dtype[floating[_64Bit] | floating[_32Bit] | floating[_16Bit] | integer[Any] | numpy.bool[builtins.bool]]] | _NestedSequence[_SupportsArray[dtype[floating[_64Bit] | floating[_32Bit] | floating[_16Bit] | integer[Any] | numpy.bool[builtins.bool]]]] | float | int | _NestedSequence[float | int], /) -> ndarray[tuple[int, ...], dtype[float64]]
test_mypy.py:12:7:12:15: note:         @overload
test_mypy.py:12:7:12:15: note:         def __add__(self, _SupportsArray[dtype[floating[_64Bit]]] | _NestedSequence[_SupportsArray[dtype[floating[_64Bit]]]], /) -> ndarray[tuple[int, ...], dtype[float64]]
test_mypy.py:12:7:12:15: note:         @overload
test_mypy.py:12:7:12:15: note:         def __add__(self, _SupportsArray[dtype[complexfloating[_64Bit, _64Bit]]] | _NestedSequence[_SupportsArray[dtype[complexfloating[_64Bit, _64Bit]]]], /) -> ndarray[tuple[int, ...], dtype[complex128]]
test_mypy.py:12:7:12:15: note:         @overload
test_mypy.py:12:7:12:15: note:         def __add__(self, _SupportsArray[dtype[numpy.bool[builtins.bool]] | dtype[integer[Any]] | dtype[floating[Any]]] | _NestedSequence[_SupportsArray[dtype[numpy.bool[builtins.bool]] | dtype[integer[Any]] | dtype[floating[Any]]]] | builtins.bool | int | float | _NestedSequence[builtins.bool | int | float], /) -> ndarray[tuple[int, ...], dtype[floating[Any]]]
test_mypy.py:12:7:12:15: note:         @overload
test_mypy.py:12:7:12:15: note:         def __add__(self, _SupportsArray[dtype[numpy.bool[builtins.bool]] | dtype[integer[Any]] | dtype[floating[Any]] | dtype[complexfloating[Any, Any]]] | _NestedSequence[_SupportsArray[dtype[numpy.bool[builtins.bool]] | dtype[integer[Any]] | dtype[floating[Any]] | dtype[complexfloating[Any, Any]]]] | builtins.bool | int | float | complex | _NestedSequence[builtins.bool | int | float | complex], /) -> ndarray[tuple[int, ...], dtype[complexfloating[Any, Any]]]
test_mypy.py:12:7:12:15: note:         @overload
test_mypy.py:12:7:12:15: note:         def __add__(self, _SupportsArray[dtype[numpy.bool[builtins.bool]] | dtype[number[Any, int | float | complex]]] | _NestedSequence[_SupportsArray[dtype[numpy.bool[builtins.bool]] | dtype[number[Any, int | float | complex]]]] | builtins.bool | int | float | complex | _NestedSequence[builtins.bool | int | float | complex], /) -> ndarray[tuple[int, ...], dtype[number[Any, int | float | complex]]]
test_mypy.py:12:7:12:15: note:         @overload
test_mypy.py:12:7:12:15: note:         def __add__(self, _SupportsArray[dtype[object_]] | _NestedSequence[_SupportsArray[dtype[object_]]], /) -> Any
Found 1 error in 1 file (checked 1 source file)

Python and NumPy Versions:

2.2.4
3.13.2 (main, Feb 4 2025, 14:51:09) [Clang 16.0.0 (clang-1600.0.26.6)]

Type-checker version and settings:

mypy 1.15.0 (compiled: yes)

Additional typing packages.

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions