pylint giving not-callable error for object property that is callable
Asked Answered
A

2

7

Not sure if I am doing something wrong or if this is a problem with pylint. In the code below I get a linting error that self.type is not callable E1102.

Although I could just ignore it and keep working, seems like this kind of thing should be easy to fix... just can't figure out how to fix it.

from typing import Callable


class Thing:
    def __init__(self, thing_type: Callable):
        self._type = thing_type
        self._value = None

    @property
    def type(self) -> Callable:
        return self._type

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, value):
        self._value = self.type(value)

enter image description here

Aerobiology answered 3/12, 2018 at 16:59 Comment(0)
A
6

Will leave this answer unaccepted for awhile, but I did figure out that it has something to do with the use of the @property decorator. In the process of creating the new object property, the type hint information is lost to pylint, and VSCode intellisense doesn't seem to work. Using the old style property syntax I get proper linting and type hinting (see image below)

Seems a bit of a shame, but am hoping someone comes up with a better answer

enter image description here

Aerobiology answered 3/12, 2018 at 17:33 Comment(0)
M
3

If self._type is a class (instead of an instance), you might want to annotate it with type instead. type is the default metaclass in python.

pylint should handle that better - it knows that you can call a class to create an instance.

class Thing:
    def __init__(self, thing_type: type):
        self._type: type = thing_type
        self._value = None

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, value):
        self._value = self._type(value)

Note that I also included a variable annotation that requires python 3.6 in there.

Also note that if you do not include a type.setter anywhere, python will conclude on it's own that type cannot be set. If you then refer to _type in your constructor (which you're doing right now), then you already bypass it not being settable.

Edits: I changed the value.setter to use self._type instead. Since it's a private variable to the instance, this is perfectly fine to use. This stops the pylint E1102 from appearing.

Removing the type property will remove E0601. This is because your property is, in the class namespace, shadowing the global variable named type. If it is defined, pylint thinks you intend to use the property(which at that point, is an instance of the property class, instead of a property on a class).

Madaih answered 4/12, 2018 at 8:59 Comment(4)
not sure why but pylint now gives an error on line 5: E0601 variable type referenced before assignment. Also this does not solve the problem mentioned in the question (checked with 3.6 and 3.7), nor does setting a property setter with @type.setterAerobiology
Edited a bit regarding the E1102. As for the E0601, im gonna look around a bit and I'll get back to you. This seems like an error in pylint to me that it doesn't recognize type being used.Madaih
I'll see if I can file a bug report regarding pylint's strange behaviour in this cases. The message is should have emitted was one about shadowing a builtin.Madaih
github issue: github.com/PyCQA/pylint/issues/2633 . Note that you can also avoid this warning by enclosing the annotation in quotes, which in 3.7 should have the same effect according to python.org/dev/peps/pep-0563 , but that PEP also notes that it shouldn't be required.Madaih

© 2022 - 2024 — McMap. All rights reserved.