dropbox / sqlalchemy-stubs

Mypy plugin and stubs for SQLAlchemy
Apache License 2.0
570 stars 101 forks source link

Model instance attributes have correct types when accessed, but not when compared structurally to another class #134

Closed ckarnell closed 4 years ago

ckarnell commented 4 years ago

Currently when you access an attribute on a model, its type gets converted to the expected Python type. However, since this uses the plugin hook for attribute access, that means when structural typing is attempted, it doesn't match up.

Here's an example illustrating my point.

from typing_extensions import Protocol
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer

class UserStructure(Protocol):
    id: int

Base = declarative_base()

class User(Base):
    id = Column(Integer, primary_key=True)

user: UserStructure = User() # Incompatible types in assignment (expression has type "User", variable has type "UserStructure")  [assignment]
# Following member(s) of "User" have conflicts:
#    id: expected "int", got "Column[int]"

Even though reveal_type(user.id) shows int.

ilevkivskyi commented 4 years ago

This is actually caused by mypy issue https://github.com/python/mypy/issues/7724. But I will keep this open as an important example.

ilevkivskyi commented 4 years ago

Actually there is a dedicated issue already for this case https://github.com/python/mypy/issues/5481, so this can be closed as a duplicate.