astroid icon indicating copy to clipboard operation
astroid copied to clipboard

false not-an-iterable for __truediv__ with @overload

Open davetapley opened this issue 1 year ago • 2 comments

Steps to reproduce

from dataclasses import dataclass
from typing import Any, Iterable, Iterator, overload


@dataclass
class MyIterable(Iterable[int]):

    def __iter__(self) -> Iterator[int]:
        for n in range(1, 10):
            yield n


@dataclass
class IterableMaker():
    @overload
    def __truediv__(self, right: bool) -> bool:
        ...

    @overload
    def __truediv__(self, right: str) -> MyIterable:
        ...

    def __truediv__(self, right: Any):
        if isinstance(right, bool):
            return right
        return MyIterable()


for sensor in IterableMaker() / 'thing':
    print(sensor)

Current behavior

E1133: Non-iterable value IterableMaker() / 'thing' is used in an iterating context (not-an-iterable)

Expected behavior

No error.

python -c "from astroid import __pkginfo__; print(__pkginfo__.version)" output

3.2.2

davetapley avatar May 21 '24 23:05 davetapley

I'd hoped this was fixed by https://github.com/pylint-dev/astroid/issues/1015, but alas no.

It is specific to __truediv__.

davetapley avatar May 21 '24 23:05 davetapley

I see something similar with:

from typing import overload, Iterator, Union


class Sequence:

    def __init__(self, data: list[str]) -> None:
        self._data = data

    @overload
    def __getitem__(self, idx: int) -> str:
        ...

    @overload
    def __getitem__(self, idx: slice) -> "Sequence":
        ...

    def __getitem__(self, idx: Union[int, slice]) -> Union[str, "Sequence"]:
        if isinstance(idx, slice):
            return self.__class__(*self._data[idx])
        else:
            return self._data[idx]


s = Sequence(["a", "b"])
print(s[0].upper())

where pylint complains: E1101: Instance of 'Sequence' has no 'upper' member (no-member)

For my real code (implementation, usage) this only started happening with pylint 3.2.1 and astroid 3.2.2 (but not 3.1.x). However, the minimal example seems to show the error even in older versions.

The-Compiler avatar May 24 '24 18:05 The-Compiler