Run pylint on this code
cfg = [
{'v': [0, 1], 'f': None},
{'v': [1, 2], 'f': sum}
]
if __name__ == '__main__':
for c in cfg:
if c['f'] is not None:
c['f'](c['v'])
Error on the last line:
test.py:9: [E1102(not-callable), ] c['f'] is not callable
Only the first item of the list is test to figure out if it is callable or not. If cfg is changed to
cfg = [
{'v': [1, 2], 'f': sum},
{'v': [0, 1], 'f': None}
]
then there is no error.
No error
pylint 1.7.1,
astroid 1.5.2
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609]
Another similar use case.
class Test:
# Override in child class
_func = None
def test(self):
if self._func is not None:
return self._func()
pylint could avoid this kind of false positives thanks to the is not None test but what if we know for sure that self._func has been replaced and we don't test?
Even with the if callable(f) test it still produces the same error. My use case with instance attributes:
# -*- coding: utf-8 -*
"""
Demo for false positive pylint E1102 error
"""
class Foo:
"""
A class whose instance have a possibly callable
attributes `func` and `func2`
"""
def __init__(self):
self.func = None
self.func2 = None
def run_func(self):
"""
This function is ok if we define the `self.func`
at least in one of the instances (see the main below)
"""
if self.func and callable(self.func):
return self.func()
def run_func2(self):
"""
This function will give us a E1102
even when no its calls found!
"""
if self.func2 and callable(self.func2):
return self.func2() # <-- E1102: 31,19: self.func2 is not callable (not-callable)
def main():
"""Entry point"""
foo_obj = Foo()
foo_obj.func = lambda: 42
print(foo_obj.run_func())
# even when the `func is None` on another instance
# this code is still ok because of previous `func` assignment
foo_obj2 = Foo()
print(foo_obj2.run_func())
if __name__ == '__main__':
main()
just adding my example here, for my future reference
import inspect
import typing
class Task:
my_a: typing.Union[None, typing.Type["Task"]] = None
def __init__(self,) -> None:
if self.my_a is not None:
assert inspect.isclass(self.my_a)
assert issubclass(self.my_a, Task)
assert callable(self.my_a)
self.a = self.my_a()
self.a.hello()
def hello(self):
print("hello")
class A(Task):
my_a = Task
a: Task = A()
python cool.py
hello
mypy --show-column-numbers -p cli -p cool # passes OK
pylint --enable=E --disable=W,R,C cool.py`
cool.py:13:21: E1102: self.my_a is not callable (not-callable)
I am seeing this problem with pylint 2.4.4 on
lol = getattr('abc', 'nonexistent_attribute', None)
lolol = 3 if lol is None else lol()
.
Seeing this with astroid 2.5, Python 3.0, pylint 2.7.1, on code using progress module not substantially different from test code, though test code passes.
Most helpful comment
Even with the
if callable(f)test it still produces the same error. My use case with instance attributes: