I've made a classproperty
descriptor and whenever I use a function decorated with it, I get multiple pylint
inspection errors.
Here is a sample class with a sample decorated function:
class Bar:
"""
Bar documentation.
"""
# pylint: disable=no-method-argument
@classproperty
def foo():
"""
Retrieve foo.
"""
return "foo"
Thanks to the descriptor, I can call Bar.foo
and get the string foo returned.
Unfortunately, whenever I use functions like this with slightly more complex items (e.g. functions which return instances of objects), pylint
starts complaining about things such as no-member
or unexpected-keyword-arg
, simply because it thinks Bar.foo
is a method, rather than a wrapped classproperty
object.
I would like to disable warnings for any code that uses my function - I definitely can't allow having to write # pylint: disable
every single time I use the classproperty
-wrapped methods. How can I do it with pylint
? Or maybe I should switch to use a different linter instead?
Here is an example of a warning generated because of the reasons above:
class Bar:
"""
Bar documentation.
"""
# pylint: disable=no-method-argument
@classproperty
def foo():
"""
Retrieve an object.
"""
return NotImplementedError("Argument")
print(Bar.foo.args)
pylint
complains that E1101: Method 'foo' has no 'args' member (no-member)
(even though I know it definitely has), and I would like to completely disable some warnings for any module/class/function that uses Bar.foo.args
or similar.
For anyone interested, here is a minimal implementation of a classproperty
descriptor:
class classproperty:
"""
Minimal descriptor.
"""
# pylint: disable=invalid-name
def __init__(self, func):
self._func = func
def __get__(self, _obj, _type):
return self._func()
This may be done by adding # pylint: disable=some-message,another-one at the desired block level or at the end of the desired line of code.
you can ignore it by adding a comment in the format # pylint: disable=[problem-code] at the end of the line where [problem-code] is the value inside pylint(...) in the pylint message – for example, abstract-class-instantiated for the problem report listed above.
The solution was to include --disable=file-ignored in the Pylint command options.
that produces a pylint problem message like you can ignore it by adding a comment in the format # pylint: disable= [problem-code] at the end of the line where [problem-code] is the value inside pylint (...) in the pylint message – for example, abstract-class-instantiated for the problem report listed above. The modified line will look like this:
Luckily Pylint has some functionality that can help: you can configure it to only enable a limited list of lint checks. Generate an initial .pylintrc, for example by using pylint --generate-rcfile. Make a list of all the features you plausibly want to enable from the Pylint docs and configure .pylintrc to enable them. Comment them all out.
If you want to have a project specific pylintrc, make sure to name it pylintrc otherwise the location will need to be specifically stated. Starting from Pylint v. 0.25.3, you can use the symbolic names for disabling warnings instead of having to remember all those code numbers. E.g.:
But if you’re coding in a dynamic language like Python you’re on your own: you don’t have a compiler to catch bugs for you. The next best thing is a lint tool that uses heuristics to catch bugs in your code. One such tool is Pylint, and here’s how I started using it.
I have managed to create a dirty hack by type-hinting the items as None
:
class Bar:
"""
Bar documentation.
"""
# pylint: disable=no-method-argument,function-redefined,too-few-public-methods
foo: None
@classproperty
def foo():
"""
Retrieve an object.
"""
return NotImplementedError("Argument")
I would rather avoid having code like this because I can't actually import the items which should be type-hinted due to the circular imports issue (hence None
), but it tricks pylint
well.
As far as I know, it's not possible.
I haven't found a way to solve this in pylint's configuration. The closest I could find is the property-classes
option, but it only influences the invalid-name
checker, so not what we are looking for here:
:property-classes:
List of decorators that produce properties, such as abc.abstractproperty. Add
to this list to register other decorators that produce valid properties.
These decorators are taken in consideration only for invalid-name.
Default: ``abc.abstractproperty``
Maybe it's a question that is worth asking pylint's developers directly.
Seems to me like it's something that could be solved with a transform plugin (Maybe this for inspiration?). Pylint handles @property
decorators perfectly fine, so something like the @classproperty
suggested here, should be feasible as well.
Aside
(You might know those already)
For properties on classes:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With