python:S2325 False positive on @functools.cached_property

We want to take advantage of the new @ functools.cached_property in Python 3.8 and there are cases where the method does not make reference to self but the returned value is instance specific.

import time
import functools

class Unique:
    """Sample class using @functools.cached_property."""

    @functools.cached_property
    def started(self):
        return '%.2f' % (time.time(),)

The python:S2325 rule is flagging this as needing to be a static method but that’s incorrect in this case.

Hi @sodul,

Thank you for your feedback. This is indeed a False Positive. I looked rapidly at issues this rule raises on open source projects. It raises many False Positives (ex: on @property methods), which explains why it is not part of the “Sonar Way” quality profile.

We currently focus a lot of effort on python analysis. Part of this effort will be improving or removing old rules which don’t provide enough value or are too noisy. We’ll take your input into account when we decide what to do with this rule.

For now I would recommend to disable it if you see many false positives.

Don’t hesitate to share any other False Positive, or ideas to improve this rule.

Hi @Nicolas_Harraudeau,

Thanks for looking into it.

For the classic @property I don’t think I would be calling this a false positive since if there is no access to instance specific information and so a static method probably is more likely to be correct.

What is really special about @functools.cached_property is that it is instance specific and the code in my example is the equivalent of:

 import time

class Unique:
    """Sample class using @functools.cached_property."""

    def __init__(self):
        self._started = None

    @property
    def started(self):
        if self._started is None:
            self._started = '%.2f' % (time.time(),)
        return self._started

But with a lot less code and the first time a cached property is called the actually .started property is replaced with the returned value. So less code, faster on subsequent call and one less private property.