Code: Select all
from typing import Protocol
from sqlalchemy import Integer
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class SpamProt(Protocol):
id: int
class Base(DeclarativeBase):
pass
class SpamModel(Base):
id: Mapped[int] = mapped_column(Integer())
def do_with_spam(d: SpamProt) -> None:
raise NotImplementedError()
if __name__ == "__main__":
spam = SpamModel(id=10)
do_with_spam(spam)
< /code>
mypy
Code: Select all
spam.py:24: error: Argument 1 to "do_with_spam" has incompatible type "SpamModel"; expected "SpamProt" [arg-type]
spam.py:24: note: Following member(s) of "SpamModel" have conflicts:
spam.py:24: note: id: expected "int", got "Mapped[int]"
Found 1 error in 1 file (checked 1 source file)
< /code>
As SQLAlchemy claims to have no fully compatible typing without any plugins, I don't understand why this simplest example doesn't work. It is not a result of invariance. It is not an effect of interference from old plugin (here's the whole environment):
╭───────────────────┬─────────┬──────────╮
│ name │ version │ location │
├───────────────────┼─────────┼──────────┤
│ greenlet │ 3.1.1 │ │
│ mypy │ 1.15.0 │ │
│ mypy-extensions │ 1.0.0 │ │
│ SQLAlchemy │ 2.0.39 │ │
│ typing_extensions │ 4.12.2 │ │
╰───────────────────┴─────────┴──────────╯
< /code>
do I fundamentally misunderstand how the Mapped