Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Mypy issue 'name <func> already defined' when using hybrid property and expression of sqlalchemy

Is the a way to solve the issue with mypy and sqlalchemy when defining the expresison of a hybrid property, it triggered name <func> already defined

class User(Base):
    first_name: Mapped[str] = mapped_column(String(100), nullable=False)
    last_name: Mapped[str] = mapped_column(String(100), nullable=False)

    @hybrid_property
    def name(self) -> str:
        return f"{self.first_name} {self.last_name}"

    @full_name.expression
    def name(cls) -> str:
        return cls.first_name + " " + cls.last_name

I don’t want to install external stubs package or ignore it with # type : ignore.
Is there a way to rename the expression or something else ?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

I’ve faced a similar issue with mypy when using SQLAlchemy’s hybrid_property. The problem arises because you’re defining the method name twice: once as an instance method and once as a class method for the expression, which causes mypy to report a duplicate definition error.

To resolve this without installing external stubs or using # type: ignore, you can rename the expression method and explicitly assign it to the hybrid_property. Here’s how you can modify your code:

from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column

class Base(DeclarativeBase):
    pass

class User(Base):
    __tablename__ = 'user'

    id: Mapped[int] = mapped_column(primary_key=True)
    first_name: Mapped[str] = mapped_column(String(100), nullable=False)
    last_name: Mapped[str] = mapped_column(String(100), nullable=False)

    def _get_name(self) -> str:
        return f"{self.first_name} {self.last_name}"

    @classmethod
    def _name_expr(cls):
        return cls.first_name + " " + cls.last_name

    name = hybrid_property(fget=_get_name, expr=_name_expr)

By defining _get_name and _name_expr with different names, you avoid redefining name, and mypy won’t complain about duplicate definitions. Then, you assign them to the hybrid_property named name.

This approach keeps your code clean and type-safe without suppressing type checking or adding external packages.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading