Fixed issue in mypy plugin where class info for a custom declarative base
would not be handled correctly on a cached mypy pass, leading to an
AssertionError being raised.
Fixes: #6476
Change-Id: If78340673e6a4d16d8f7cf787ce3bdb02c8bd47b
--- /dev/null
+.. change::
+ :tags: bug, mypy
+ :tickets: 6476
+
+ Fixed issue in mypy plugin where class info for a custom declarative base
+ would not be handled correctly on a cached mypy pass, leading to an
+ AssertionError being raised.
info = util._info_for_cls(cls, api)
- if cls.fullname.startswith("builtins"):
+ if info is None:
+ # this can occur during cached passes
+ return None
+ elif cls.fullname.startswith("builtins"):
return None
elif "_sa_decl_class_applied" in info.metadata:
cls_metadata = util.DeclClassApplied.deserialize(
) -> TypeInfo:
if cls.info is CLASSDEF_NO_INFO:
sym = api.lookup_qualified(cls.name, cls)
+ if sym is None:
+ return None
assert sym and isinstance(sym.node, TypeInfo)
return sym.node
--- /dev/null
+from sqlalchemy.ext.declarative import declarative_base
+
+
+class CustomBase:
+ x = 5
+
+
+sql_base = declarative_base(cls=CustomBase)
--- /dev/null
+--- a/table.py 2021-06-21 12:16:35.418148313 -0400
++++ b/table.py 2021-06-21 12:16:31.204108368 -0400
+@@ -3,3 +3,4 @@
+ class Table(sql_base):
+ pass
+
++x = Table.x
--- /dev/null
+from .base import sql_base
+
+
+class Table(sql_base):
+ pass