Skip to content

Typing of nditer: __getattr__ is not sufficient to cover __enter__, __exit___ and __iter__ dunders #19551

@MatthieuDartiailh

Description

@MatthieuDartiailh

Trying to type check a program using np.nditer using mypy 0.812 and 0.910 and numpy 1.21.1 fails complaining about missing dunder methods. Looking at https://github.com/numpy/numpy/blob/main/numpy/__init__.pyi#L767 and https://github.com/numpy/numpy/blob/main/numpy/__init__.pyi#L633 I believe the issue stems from the fact that the presence of __getattr__ does not automatically cover all dunders.

Adding the following to nditer stub (below __getattr__) allow the code to type check properly. I can make a PR with those changes and any other deemed relevant to improve nditer typing.

    def __enter__(self) -> nditer: ...
    def __exit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc_value: Optional[BaseException],
        traceback: Optional[TracebackType]
    ) -> Optional[bool]: ...
    def __iter__(self) -> Any: ...

Reproducing code example:

import numpy as np

a = np.nditer(np.zeros((2, 2, 2)))
with a:
    for b in a:
        pass

Error message:

Mypy output:

test.py:4: error: "nditer" has no attribute "__enter__"
test.py:4: error: "nditer" has no attribute "__exit__"
test.py:5: error: "nditer" has no attribute "__iter__" (not iterable)
Found 3 errors in 1 file (checked 1 source file)

NumPy/Python version information:

Python 3.9.1, Numpy 1.21.1, Mypy 0.812 or 0.910 (only tested version)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions