Skip to content

TYP: ndarray.item never typechecks #27977

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jonathanberthias opened this issue Dec 11, 2024 · 2 comments
Closed

TYP: ndarray.item never typechecks #27977

jonathanberthias opened this issue Dec 11, 2024 · 2 comments

Comments

@jonathanberthias
Copy link

Describe the issue:

In version 2.2.0, I have been completely unable to type the return value of a call to ndarray.item() which does not fail type checking. I have tried both MyPy and Pyright.

Am I doing something wrong here? Or is it an issue with the type checker(s)? It seems they don't even see all the overloads:

numpy/numpy/__init__.pyi

Lines 2111 to 2122 in a2012ad

@overload # special casing for `StringDType`, which has no scalar type
def item(self: ndarray[Any, dtypes.StringDType], /) -> str: ...
@overload
def item(self: ndarray[Any, dtypes.StringDType], arg0: SupportsIndex | tuple[SupportsIndex, ...] = ..., /) -> str: ...
@overload
def item(self: ndarray[Any, dtypes.StringDType], /, *args: SupportsIndex) -> str: ...
@overload # use the same output type as that of the underlying `generic`
def item(self: _HasShapeAndDTypeWithItem[Any, _T], /) -> _T: ...
@overload
def item(self: _HasShapeAndDTypeWithItem[Any, _T], arg0: SupportsIndex | tuple[SupportsIndex, ...] = ..., /) -> _T: ...
@overload
def item(self: _HasShapeAndDTypeWithItem[Any, _T], /, *args: SupportsIndex) -> _T: ...

Reproduce the code example:

import numpy as np


def f(x: np.ndarray[tuple[int], np.double]) -> float:
    return x.item()


def g(x: np.ndarray[tuple[int], np.str_]) -> str:
    return x.item()

Error message:

/dev/np_typing.py
  /dev/np_typing.py:4:33 - error: Type "double" cannot be assigned to type variable "_DType_co@ndarray"
    Type "double" is not assignable to upper bound "dtype[Any]" for type variable "_DType_co@ndarray"
      "floating[_NBitDouble]" is not assignable to "dtype[Any]" (reportInvalidTypeArguments)
  /dev/np_typing.py:5:14 - error: Cannot access attribute "item" for class "ndarray[tuple[int], double]"
    Could not bind method "item" because "ndarray[tuple[int], double]" is not assignable to parameter "self"
      "ndarray[tuple[int], double]" is not assignable to "ndarray[Any, StringDType]"
        Type parameter "_DType_co@ndarray" is covariant, but "double" is not a subtype of "StringDType"
          "floating[_NBitDouble]" is not assignable to "StringDType"
    Could not bind method "item" because "ndarray[tuple[int], double]" is not assignable to parameter "self"
      "ndarray[tuple[int], double]" is not assignable to "ndarray[Any, StringDType]"
        Type parameter "_DType_co@ndarray" is covariant, but "double" is not a subtype of "StringDType"
          "floating[_NBitDouble]" is not assignable to "StringDType" (reportAttributeAccessIssue)
  /dev/np_typing.py:8:33 - error: Type "str_" cannot be assigned to type variable "_DType_co@ndarray"
    Type "str_" is not assignable to upper bound "dtype[Any]" for type variable "_DType_co@ndarray"
      "str_" is not assignable to "dtype[Any]" (reportInvalidTypeArguments)
  /dev/np_typing.py:9:14 - error: Cannot access attribute "item" for class "ndarray[tuple[int], str_]"
    Could not bind method "item" because "ndarray[tuple[int], str_]" is not assignable to parameter "self"
      "ndarray[tuple[int], str_]" is not assignable to "ndarray[Any, StringDType]"
        Type parameter "_DType_co@ndarray" is covariant, but "str_" is not a subtype of "StringDType"
          "str_" is not assignable to "StringDType"
    Could not bind method "item" because "ndarray[tuple[int], str_]" is not assignable to parameter "self"
      "ndarray[tuple[int], str_]" is not assignable to "ndarray[Any, StringDType]"
        Type parameter "_DType_co@ndarray" is covariant, but "str_" is not a subtype of "StringDType"
          "str_" is not assignable to "StringDType" (reportAttributeAccessIssue)
4 errors, 0 warnings, 0 informations

Python and NumPy Versions:

2.2.0
3.11.10 (main, Sep 7 2024, 01:03:31) [GCC 11.4.0]

Type-checker version and settings:

pyright 1.1.390 with default settings

Additional typing packages.

No response

@jonathanberthias jonathanberthias changed the title TYP: ndarray.item never matches TYP: ndarray.item never typechecks Dec 11, 2024
@jorenham
Copy link
Member

jorenham commented Dec 19, 2024

Reproduce the code example:

import numpy as np


def f(x: np.ndarray[tuple[int], np.double]) -> float:
    return x.item()


def g(x: np.ndarray[tuple[int], np.str_]) -> str:
    return x.item()

This is invalid: the 2nd type parameter of np.ndarray is bound to np.dtype, so it should instead be:

import numpy as np


def f(x: np.ndarray[tuple[int], np.dtype[np.double]]) -> float:
    return x.item()


def g(x: np.ndarray[tuple[int], np.dtype[np.str_]]) -> str:
    return x.item()

which is accepted by both mypy and pyright


Oh and quick tip, np.float64 is almost always the same as np.double, but np.float64 has better annotations, for instance it actually has float as a supertype, whereas np.double doesn't.

@jorenham jorenham added the 57 - Close? Issues which may be closable unless discussion continued label Dec 19, 2024
@jonathanberthias
Copy link
Author

Awesome thanks! I guess that I just tried to replace NDArray[np.str_] with ndarray[Shape, np.str_], and I didn't notice that NDArray also added the dtype for me. Thanks a lot for your help!

@jorenham jorenham removed the 57 - Close? Issues which may be closable unless discussion continued label Dec 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants