Skip to content
New issue

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

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

Already on GitHub? # to your account

False positive not-callable on type-annotated post-initialized class member #2562

Closed
Strilanc opened this issue Oct 19, 2018 · 4 comments
Closed

Comments

@Strilanc
Copy link

Steps to reproduce

Insert the following python code into a file x.py

class C:
    X = None  # type: C
    def __call__(self, *args, **kwargs):
        return self
C.X = C()

_ = C.X(5)
  1. Run pylint with not-callable enabled

pylint --disable=all --enable=not-callable --score=no x.py

Current behavior

Pylint outputs an error

************* Module x
x.py:8:4: E1102: C.X is not callable (not-callable)

This is likely because pylint is looking at the temporary value None instead of trusting the type annotation type: C. (Note that mypy trusts the type annotation.)

Expected behavior

Consider not outputing an error in this case, in order to make it possible to work around the fact that it is not possible to initialize class variables of the same type as the enclosing class until after the class is initialized, so it is necessary to have some sort of placeholder of an incorrect type.

pylint --version output

pylint 2.1.1
astroid 2.1.0-dev
Python 3.5.3 (default, Jan 19 2017, 14:11:04) 
[GCC 6.3.0 20170118]

and separately

pylint 2.1.1
astroid 2.0.4
Python 3.5.3 (default, Jan 19 2017, 14:11:04) 
[GCC 6.3.0 20170118]
@Strilanc
Copy link
Author

Note that there is a workaround that works on both mypy and pylint (at least for now): before the class, declare a dummy method that returns the class type (specified as a string), and initialize the fields using the dummy method.

CirqBot pushed a commit to quantumlib/Cirq that referenced this issue Oct 19, 2018
- Work around 'not callable' false-positives by doing a better job of tricking the analysis into understanding class fields of the class type
- Disable 'too-many-function-args' check around a line that's failing due to mypy not understanding overloads well enough

Both false positives have been reported:
- pylint-dev/pylint#2561
- pylint-dev/pylint#2562
@PCManticore
Copy link
Contributor

pylint doesn't interpret type annotations at all, instead it relies on inference to figure out what the actual type of an object is. In this case, it might determine it's an union of NoneType and C which is why it would emit this error for you. That's definitely a bug, but it's also tripped by the fact that later on you reassign the X member to an actual callable.
Unfortunately until we'd change pylint to have type inference based from type annotations, there's not much we can do.

@uliantsev-a
Copy link

uliantsev-a commented Sep 23, 2021

@PCManticore, could we check condition of callable before checking to not-callable. For don't waite typing anotation in pylint. For pass of this example:

if callable(C.X):
    _ = C.X(5)

@Pierre-Sassoulas
Copy link
Member

The discussion about taking into account type annotations is in #4813. I don't think it would be wise to add small workaround before we resolve that bigger issue. The maintenance cost is just too high.

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

No branches or pull requests

4 participants