from typing import Optional from sqlalchemy import Column from sqlalchemy import Integer from sqlalchemy import String from sqlalchemy.orm import column_property from sqlalchemy.orm import deferred from sqlalchemy.orm import registry from sqlalchemy.orm import Session from sqlalchemy.orm import synonym from sqlalchemy.sql.functions import func from sqlalchemy.sql.sqltypes import Text reg: registry = registry() @reg.mapped class User: __tablename__ = "user" id = Column(Integer(), primary_key=True) name = Column(String) # this gets inferred big_col = deferred(Column(Text)) # this gets inferred explicit_col = column_property(Column(Integer)) # EXPECTED: Can't infer type from ORM mapped expression assigned to attribute 'lower_name'; # noqa lower_name = column_property(func.lower(name)) # EXPECTED: Can't infer type from ORM mapped expression assigned to attribute 'syn_name'; # noqa syn_name = synonym("name") # this uses our type lower_name_exp: str = column_property(func.lower(name)) # this uses our type syn_name_exp: Optional[str] = synonym("name") s = Session() u1: Optional[User] = s.get(User, 5) assert u1 q1: Optional[str] = u1.big_col q2: Optional[int] = u1.explicit_col # EXPECTED_MYPY: Incompatible types in assignment (expression has type "str", variable has type "int") # noqa x: int = u1.lower_name_exp # EXPECTED_MYPY: Incompatible types in assignment (expression has type "Optional[str]", variable has type "int") # noqa y: int = u1.syn_name_exp