Mypy + FlaskSQLAlchemy + 模型多重继承=>没有属性

问题描述 投票:0回答:1

看起来

mypy
在考虑所有超类时遇到问题并报告缺少属性。这是一个简单的例子:

import uuid

from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import String
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import mapped_column, DeclarativeBase


db = SQLAlchemy()


class Base(DeclarativeBase):
    pass


class IdMixin:
    id = mapped_column(UUID(as_uuid=True), nullable=False, default=uuid.uuid4, primary_key=True)


class ImageMixin:
    image_name = mapped_column(String, default=None)
    image_uri = mapped_column(String, default=None)


class Model(IdMixin, Base):
    pass


class Post(Model, ImageMixin):
    content = mapped_column(String)


class Comment(Model, ImageMixin):
    text = mapped_column(String)


def generate_image_uri(image_name: str) -> str:
    return f"https://example.com/{image_name}"


models = [Comment, Post]
for model in models:
    entities = db.session.query(model).all()
    for entity in entities:
        entity.image_uri = generate_image_uri(image_name=entity.image_name) # Line 45

Mypy 报告:

mypy-warning.py:45: error: "Model" has no attribute "image_uri"  [attr-defined]
mypy-warning.py:45: error: "Model" has no attribute "image_name"  [attr-defined]

当我将

ImageMixin
移至
Model
类,然后仅在
Model
Post
类中子类
Comment
时,它工作得很好,但这不是我想要的,因为我不一定想要所有模型都可以混合图像功能。

python sqlalchemy flask-sqlalchemy mypy python-typing
1个回答
0
投票

Mypy 将包含

Post
Comment
的 List 的类型推断为:

builtins.list[def (**kw: Any) -> t.Model]

这是有道理的,因为

Post
Comment
都继承自
Model
(这也是当您将
ImageMixin
移动到
Model
类时Mypy不会抱怨的原因)。

用以下方式明确注释列表:

models: list[type[ImageMixin]] = [Comment, Post]

修复了错误,现在只允许在列表中使用继承自

ImageMixin
的类,从而确保在以下 for 循环中访问时可以访问
image_url
属性。

© www.soinside.com 2019 - 2024. All rights reserved.