sqlalchemy-stubs
sqlalchemy-stubs copied to clipboard
Doesn't find column on child class
Here is a very simplified reproducer:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.schema import Column
from sqlalchemy.types import Integer
Base = declarative_base()
class BaseMixin(Base):
__abstract__ = True
field1 = Column(Integer)
@classmethod
def from_something(cls, something_complicated: int) -> 'BaseMixin':
# Real code tries to figure out which model to use
return MyModel(field1=something_complicated, field2=something_complicated)
class MyModel(BaseMixin):
__tablename__ = 'first-model'
field2 = Column(Integer)
With sqlalchemy-stubs from master, I get the following:
$ pipenv run mypy model.py
model.py:17: error: Unexpected column "field2" for model "MyModel"
But field2 exists on the model. :confused:
This seems to be due to the order of the code because if I add the following line at the end of the file, then Mypy doesn't report any error:
m = MyModel(field1=1, field2=2)
The problem seems to be due to https://github.com/dropbox/sqlalchemy-stubs/blob/f6c110547b6fd99261362fb53d961f580463cb18/sqlmypy.py#L214
When Python passes over that line for BaseMixin.field1, both conditions are True.
But when it passes over it for MyModel.field2, the second condition is False because sym.node.type is None.
As a result, field2 doesn't get added to expected_types, which leads to the error.
I'm not sure how/where sym.node.type is supposed to be computed, maybe this is a bug in mypy instead?
I think your diagnosis is correct, but this may be not easy to fix with the current state of mypy internals (we can't trigger a deferral from this point, because module top-levels can't be deferred).
Anyway, this is a known limitation in mypy, and it will likely be removed at some point soon.
Anyway, this is a known limitation in mypy
Do you happen to have a link to a mypy issue handy?
Here is the link https://github.com/python/mypy/issues/6356