Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get PyCharm to recognize a custom property decorator?

Let's consider the following example class:

class Foo:
    def __init__(self):
        self._bar = None

    @property
    def bar(self):
        if self._bar is None:
            self._bar = ...  # a long computation
        return self._bar

I created a cachedproperty decorator to implicitly take care of storing the computed result as a member of the class instance. Here is a simplified example of such decorator class:

class cachedproperty(property):
    def __init__(self, fget):
        @functools.wraps(fget)
        def cfget(obj):
            name = '_' + fget.__name__
            if not hasattr(obj, name):
                setattr(obj, name, fget(obj))
            return getattr(obj, name)
        super().__init__(cfget)

And now class Foo looks like this:

class Foo:
    @cachedproperty
    def bar(self):
        return ...  # a long computation

Even though it works, it is somewhat inconvenient that PyCharm now fails to treat bar as a property of Foo, and instead treats it as a method. This can be witnessed, for example, in the autocompletion dropdown:

Autocompletion for Foo.bar with @property decorator

Autocompletion for Foo.bar with @cachedproperty decorator

My question is: how can I force PyCharm to treat my custom property decorator as an actual property?

like image 884
Zohar Meir Avatar asked Oct 16 '18 10:10

Zohar Meir


People also ask

How do function decorators work in Python?

Decorators dynamically alter the functionality of a function, method, or class without having to directly use subclasses or change the source code of the function being decorated. Using decorators in Python also ensures that your code is DRY(Don't Repeat Yourself).

What is Property decorator in Python?

The @property is a built-in decorator for the property() function in Python. It is used to give "special" functionality to certain methods to make them act as getters, setters, or deleters when we define properties in a class.

What are function decorators?

By definition, a decorator is a function that takes another function and extends the behavior of the latter function without explicitly modifying it.

What is Python class decorator?

What Is a Python Class Decorator? A Python class decorator adds a class to a function, and it can be achieved without modifying the source code. For example, a function can be decorated with a class that can accept arguments or with a class that can accept no arguments.


1 Answers

It would appear that PyCharm makes this decision purely based on the name of the decorator. For example, renaming your cachedproperty decorator to cached_property (so that it matches Django's decorator of that name) works:

Pycharm dropdown with property marker

… whereas using the builtin property decorator with a different name doesn't:

Pycharm dropdown with property marker

like image 160
Zero Piraeus Avatar answered Nov 14 '22 23:11

Zero Piraeus