Skip to content
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

Regression with not-callable #3595

Closed
dseomn opened this issue May 5, 2020 · 5 comments · Fixed by #4348
Closed

Regression with not-callable #3595

dseomn opened this issue May 5, 2020 · 5 comments · Fixed by #4348

Comments

@dseomn
Copy link

dseomn commented May 5, 2020

Steps to reproduce

  1. Run pylint 2.5.2 on https://github.com/dseomn/pepper-music-player/blob/d1920ec3b941b65fad630e8b067d35bde228be49/pepper_music_player/player/player_test.py.

Current behavior

pepper_music_player/player/player_test.py:283:8: E1102: self._player.next is not callable (not-callable)
pepper_music_player/player/player_test.py:292:8: E1102: self._player.next is not callable (not-callable)
pepper_music_player/player/player_test.py:301:8: E1102: self._player.next is not callable (not-callable)

Expected behavior

I don't see why those lines are not-callable. self._player.next() is defined as a regular method.

pylint --version output

pylint 2.5.2
astroid 2.4.1
Python 3.8.3rc1 (default, Apr 30 2020, 07:33:30) 
[GCC 9.3.0]
mlin added a commit to chanzuckerberg/miniwdl that referenced this issue May 30, 2020
@frenck
Copy link

frenck commented Jul 7, 2020

Experiencing the same issue on the Home Assistant project:

homeassistant/components/itunes/media_player.py:391:19: E1102: self.client.next is not callable (not-callable)

next() has been defined here: https://github.com/home-assistant/core/blob/dev/homeassistant/components/itunes/media_player.py#L141

@rukai
Copy link

rukai commented Jul 13, 2020

I hit this as well, issue only occurs when the method is named next.

@felipe3dfx
Copy link

Same issue with generator in class method

class PaginatedResponse(Response):
    """A paginated response returned by the API"""

    @property
    def results(self):
        return self.data['results']

    @property
    def total(self):
        return self.data['paging']['total']

    @property
    def limit(self):
        return self.data['paging']['limit']

    @property
    def offset(self) -> int:
        return self.data['paging']['offset']

    def has_next(self) -> bool:
        return self.offset + self.limit < self.total

    def has_prev(self) -> bool:
        return self.offset > 0

    def next(self):
        offset = min(self.offset + self.limit, self.total)
        return self._request_with_params(offset=offset)

    def prev(self):
        offset = max(0, self.offset - self.limit)
        return self._request_with_params(offset=offset)

    def _request_with_params(self, **params):
        url = urlparse(self.url)
        query = parse_qs(url.query)
        query.update(params)

        return self._client.get(url.path, params=query)

    def __iter__(self):
        return iter(self.results)

    def auto_paging_iter(self):
        req = self

        for result in req:
            yield result

        while req.has_next():
            req = req.next()  # noqa Wait for https://github.com/PyCQA/pylint/issues/3595
            for result in req:
                yield result

@SamyCookie
Copy link

same issue for me, here a reduced test case

import typing

class A:
    def next(self):
        pass
    def wait(self):
        self.next()

no error if module 'typing' is not imported, or if the next method is rename (like _next)

@brycepg
Copy link
Contributor

brycepg commented Jan 10, 2021

I can repro on master


It looks like this issue is only triggered in pylint:

Inference and astroid works here:

import astroid
ret = astroid.extract_node("""
import typing

class A:
    def next(self):
        return 1
    def wait(self):
        self.next() #@
""")
inferred = ret.func.inferred()
print("inferred", inferred)
print("callable", inferred[0].callable())
print("Instance", isinstance(inferred[0], astroid.Instance))
inferred [<BoundMethod next of .A at 0x126546186385440]
callable True
Instance False

But when calling your example with pylint. On line 1218 of pylint/checkers/typecheck.py:

called = safe_infer(node.func) when node.func is self.next is inferred as Const.NoneType(value=None) instead of a bound method.

strange

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants