I installed the the type stubs and configured the mypy plugin as directed in the documentation
My database is defined like this:
@as_declarative()
class Base:
def __repr__(self):
name = self.__class__.__name__
attrs = (
"%s=%r" % (attr, getattr(self, attr))
for attr in self._sa_class_manager.keys()
if not (attr[-2:] == "id" or isinstance(getattr(self, attr), list))
)
return name + "(%s)" % ", ".join(attrs)
class Source(Base):
__tablename__ = "sources"
id = sa.Column(sa.Integer, primary_key=True)
address = sa.Column(sa.String, index=True)
match_id = sa.Column(sa.Integer, sa.ForeignKey("matches.id"))
match = relationship("Match", back_populates="sources")
class Match(Base):
__tablename__ = "matches"
id = sa.Column(sa.Integer, primary_key=True)
original_id = sa.Column(sa.Integer, sa.ForeignKey("original.id"))
romanized_id = sa.Column(sa.Integer, sa.ForeignKey("romanized.id"))
count = sa.Column(sa.Integer)
original = relationship("Original", back_populates="matches")
romanized = relationship("Romanized", back_populates="matches")
sources = relationship("Source", back_populates="match")
sa.Index("matches_idx", Match.original_id, Match.romanized_id, unique=True)
class Standard(Base):
__tablename__ = "standards"
id = sa.Column(sa.Integer, primary_key=True)
st = sa.Column(sa.String, index=True, unique=True)
class Original(Base):
__tablename__ = "original"
id = sa.Column(sa.Integer, primary_key=True)
form = sa.Column(sa.String, index=True, unique=True)
matches = relationship("Match", back_populates="original")
class Romanized(Base):
__tablename__ = "romanized"
id = sa.Column(sa.Integer, primary_key=True)
form = sa.Column(sa.String, index=True)
standard_id = sa.Column(sa.Integer, sa.ForeignKey("standards.id"))
standard = relationship(Standard)
matches = relationship("Match", back_populates="romanized")
sa.Index("standard_form", Romanized.form, Romanized.standard_id, unique=True)
When I run mypy, I get these errors:
$ mypy deromanize
deromanize/cacheutils.py:201: error: Need type annotation for 'match'
deromanize/cacheutils.py:211: error: Need type annotation for 'original'
deromanize/cacheutils.py:212: error: Need type annotation for 'romanized'
deromanize/cacheutils.py:213: error: Need type annotation for 'sources'
deromanize/cacheutils.py:230: error: Need type annotation for 'matches'
deromanize/cacheutils.py:239: error: Need type annotation for 'standard'
deromanize/cacheutils.py:240: error: Need type annotation for 'matches'
Found 7 errors in 1 file (checked 6 source files)
This does not match the documented error message:
test3.py:22: error: [SQLAlchemy Mypy plugin] Can't infer scalar or
collection for ORM mapped expression assigned to attribute 'user'
if both 'uselist' and 'collection_class' arguments are absent from the
relationship(); please specify a type annotation on the left hand side.
Found 1 error in 1 file (checked 1 source file)
Furthermore, when I attempt to add annotations, that doesn't work either:
class Source(Base):
__tablename__ = "sources"
id = sa.Column(sa.Integer, primary_key=True)
address = sa.Column(sa.String, index=True)
match_id = sa.Column(sa.Integer, sa.ForeignKey("matches.id"))
match: 'Match' = relationship("Match", back_populates="sources")
deromanize/cacheutils.py:201: error: Incompatible types in assignment (expression has type "RelationshipProperty[<nothing>]", variable has type "Match")
Am I doing something wrong or is this a bug?
bug