sqlalchemy / sqlalchemy2-stubs

PEP-484 typing stubs for SQLAlchemy 1.4
MIT License
157 stars 41 forks source link

Make Column and relationship inherit from Mapped #235

Open mehdigmira opened 1 year ago

mehdigmira commented 1 year ago

Is your feature request related to a problem? Please describe.

A typical typed SQLAlchemy model looks like this:

class Model(Base):
    name: Mapped[str] = Column(Unicode(100), nullable=True)

This works fine with mypy, but triggers the following error with Pylance/Pyright

Expression of type "Column[Unicode]" cannot be assigned to declared type "Mapped[str]"

Same for relationship

Describe the solution you'd like

Make Column and relationship inherit from Mapped

Additional context

I can make a PR if you're okay with this.

Have a nice day!

CaselIT commented 1 year ago

Thanks for reporting

Sadly this will not be fixed in 1.4. In version 2 it will be fixed

CaselIT commented 1 year ago

on second though, we can just lie to the type checker I guess, by making Column inherit Mapped only on the stubs.

Do you have any reservation with that @zzzeek ?

mehdigmira commented 1 year ago

Yes that what I meant. Mapped is used for typing essentially, So it's a bit weird that the recommended way of typing columns is wrong from a typing point of view.

mehdigmira commented 1 year ago

I think this is a problem in mypy also, but was only hidden by an import issue (https://github.com/sqlalchemy/sqlalchemy2-stubs/pull/237). Once the import issue fixed, mypy reports the same errors.

mehdigmira commented 1 year ago

I've dug into this a bit: Making Column inherit from Mapped causes some MRO problems, since Mapped and ColumnClause share some base classes. This doesn't prevent Pyright from working fine with this, but causes some problems for mypy which just forgets the whole class hierarchy (see https://github.com/python/mypy/issues/11427#issuecomment-956436379). For mypy, I guess we can use the customize_mro plugin hook to handle this (https://github.com/python/mypy/issues/4527). What do you think ?