我正在尝试定义使用协议键入的辅助函数,这些函数稍后将在 SQLAlchemy 2.0 映射类上使用。
就我而言,我需要将 SQLAlchemy 类(即列)的特定映射属性表示为协议本身。然而,通过查看它的源代码,我发现
Mapped
是不变的 - 因此,如果我理解正确的话,就会出现下面的错误。
知道是否有更好的方法可以输入提示我的类/函数以使其工作?
from typing import Protocol
from sqlalchemy.orm import DeclarativeBase, Mapped
# Protocols
class BarProtocol(Protocol):
bar: Mapped[int]
class FooProtocol(Protocol):
@property
def bar(self) -> Mapped[BarProtocol]:
...
def f(foo: FooProtocol) -> BarProtocol:
return foo.bar
# Implementations
class Base(DeclarativeBase):
pass
class Bar(Base):
bar: Mapped[int]
class Foo(Base):
bar: Mapped[Bar]
f(Foo()) # Doesn't type-check
Mypy 输出:
error: Argument 1 to "f" has incompatible type "Foo"; expected "FooProtocol" [arg-type]
note: Following member(s) of "Foo" have conflicts:
note: bar: expected "Mapped[BarProtocol]", got "Mapped[Bar]"
Found 1 error in 1 file (checked 1 source file)
Mapped
已在 2.0.21 中实现协变(请参阅发行说明)。