pylint-dev / pylint

It's not just a linter that annoys you!
https://pylint.readthedocs.io/en/latest/
GNU General Public License v2.0
5.23k stars 1.11k forks source link

SQLAlchemy @hybrid_property.expression has "no-self-argument" #3804

Open huntfx opened 3 years ago

huntfx commented 3 years ago

I'm not sure if this would be within the scope of pylint features, but a similar question was looked at previously, so I may as well mention the problem.

The hybrid_property of SQLAlchemy has an expression method, which acts like a classmethod in that it takes cls as an argument, not self. Pylint doesn't like this, and comes up with the no-self-argument warning. The documentation for it is here.

Here's an example:

from sqlalchemy import Column, Integer, func
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.hybrid import hybrid_property

Base = declarative_base()

class Test(Base):
    __tablename__ = 'test'

    id = Column(Integer, primary_key=True)
    name = Column(String(64), nullable=False)

    @hybrid_property
    def name_lower(self):
        return self.name.lower()

    @name_lower.expression
    def name_lower(cls, value):     # this line has the issue
        return func.lower(cls.name)

From a look at the source code, there doesn't seem to be an obvious way to detecting that though, so it may need to be more of a hardcoded feature if implemented.

hippo91 commented 3 years ago

@Peter92 thanks for the report. This bug is probably linked to #3334 and #1061.

huntfx commented 3 years ago

Hey, I saw those two, they appear to be referencing a slightly different issue (specifically no-member) so I didn't want to overcomplicate things by bundling multiple issues into one.

However, upon saying that, I noticed that after #1061 was closed, @chaoflow did mention the exact same thing I was talking about, but he appears to have mostly been ignored (understandable as I assume issues aren't checked again after being closed).

fvital commented 6 months ago

In case anyone else stumbled on this issue. The docs for SQLAlchemy 2.0 say to use the @classmethod decorator to let typing tools know that cls is expected as an argument, instead of self. I don't know if older SQLAlchemy versions have issues with that decorator, but it worked fine here using SQLAlchemy 2.0.