mypy not'

发布于 2025-01-25 09:07:46 字数 1618 浏览 3 评论 0原文

我正在尝试将mypy与sqlalchemy一起使用。 为了验证/修改特定列值(在这种情况下为电子邮件), sqlalchemy官方文档提供hybrid_property decorator。

问题是,mypy不识别emailAddress类构造函数正确,它给出:

email_address.py:31: error: Unexpected keyword argument "email" for "EmailAddress"; did you mean "_email"?

我如何告诉mypy识别这些列?

from typing import TYPE_CHECKING

from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base

# I don't even like the following statements just for setter
if TYPE_CHECKING:
    hybrid_property = property
else:
    from sqlalchemy.ext.hybrid import hybrid_property

Base = declarative_base()


class EmailAddress(Base):
    __tablename__ = "email_address"

    id = Column(Integer, primary_key=True)

    _email = Column("email", String)

    @hybrid_property
    def email(self):
        return self._email

    @email.setter
    def email(self, email):
        self._email = email


EmailAddress(email="[email protected]")
# email_address.py:31: error: Unexpected keyword argument "email" for "EmailAddress"; did you mean "_email"?

我正在使用以下软件包:

SQLAlchemy==1.4.35
mypy==0.942
mypy-extensions==0.4.3
sqlalchemy2-stubs==0.0.2a22

I'm trying to use mypy with SQLAlchemy.
In order to validate/modify specific column value (email in this case), SQLAlchemy official document provides hybrid_property decorator.

The problem is, mypy doesn't recognize EmailAddress class constructor properly, it gives:

email_address.py:31: error: Unexpected keyword argument "email" for "EmailAddress"; did you mean "_email"?

How can I tell mypy to recognize these columns?

from typing import TYPE_CHECKING

from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base

# I don't even like the following statements just for setter
if TYPE_CHECKING:
    hybrid_property = property
else:
    from sqlalchemy.ext.hybrid import hybrid_property

Base = declarative_base()


class EmailAddress(Base):
    __tablename__ = "email_address"

    id = Column(Integer, primary_key=True)

    _email = Column("email", String)

    @hybrid_property
    def email(self):
        return self._email

    @email.setter
    def email(self, email):
        self._email = email


EmailAddress(email="[email protected]")
# email_address.py:31: error: Unexpected keyword argument "email" for "EmailAddress"; did you mean "_email"?

I'm using following packages:

SQLAlchemy==1.4.35
mypy==0.942
mypy-extensions==0.4.3
sqlalchemy2-stubs==0.0.2a22

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

悲歌长辞 2025-02-01 09:07:46

好的,似乎我终于找到了一种解决问题的方法。

这使我想起了 href =“ https://stackoverflow.com/quf =”中讨论的数据级/属性装饰器之间的不合作行为。

我最终将emailAddress类分为2:

  1. 使用@dataclass base类上的装饰器以指示构造函数选项。
  2. Override 电子邮件属性,以使Mypy不会抱怨Redef。
from dataclasses import dataclass
from typing import TYPE_CHECKING, Optional

from sqlalchemy import Column, Integer, String, Table
from sqlalchemy.orm import registry

mapper_registry: registry = registry()

# I don't even like the following statements just for setter
if TYPE_CHECKING:
    hybrid_property = property
else:
    from sqlalchemy.ext.hybrid import hybrid_property


@dataclass
@mapper_registry.mapped
class EmailAddressBase:
    __tablename__ = "email address"

    id: int = Column(Integer, primary_key=True)
    email: Optional[str] = None


class EmailAddress(EmailAddressBase):
    _email = Column("email", String)

    @hybrid_property
    def email(self):
        return self._email

    @email.setter
    def email(self, email):
        self._email = email


email = EmailAddress(email="[email protected]")
print(email.email)

OK, it seems like I finally found a way to solve the problem.

This reminds me of uncooperative behaviors between dataclass/property decorators discussed in here.

I end up with splitting EmailAddress class into 2:

  1. Use @dataclass decorator on base class in order to indicate constructor options.
  2. Override email property so that mypy doesn't complain redef.
from dataclasses import dataclass
from typing import TYPE_CHECKING, Optional

from sqlalchemy import Column, Integer, String, Table
from sqlalchemy.orm import registry

mapper_registry: registry = registry()

# I don't even like the following statements just for setter
if TYPE_CHECKING:
    hybrid_property = property
else:
    from sqlalchemy.ext.hybrid import hybrid_property


@dataclass
@mapper_registry.mapped
class EmailAddressBase:
    __tablename__ = "email address"

    id: int = Column(Integer, primary_key=True)
    email: Optional[str] = None


class EmailAddress(EmailAddressBase):
    _email = Column("email", String)

    @hybrid_property
    def email(self):
        return self._email

    @email.setter
    def email(self, email):
        self._email = email


email = EmailAddress(email="[email protected]")
print(email.email)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文