]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
accommodate no cls info found in _scan_declarative
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 21 Jun 2021 16:52:42 +0000 (12:52 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 21 Jun 2021 16:53:52 +0000 (12:53 -0400)
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

doc/build/changelog/unreleased_14/6476.rst [new file with mode: 0644]
lib/sqlalchemy/ext/mypy/decl_class.py
lib/sqlalchemy/ext/mypy/util.py
test/ext/mypy/incremental/ticket_6476/__init__.py [new file with mode: 0644]
test/ext/mypy/incremental/ticket_6476/base.py [new file with mode: 0644]
test/ext/mypy/incremental/ticket_6476/patch1.testpatch [new file with mode: 0644]
test/ext/mypy/incremental/ticket_6476/table.py [new file with mode: 0644]

diff --git a/doc/build/changelog/unreleased_14/6476.rst b/doc/build/changelog/unreleased_14/6476.rst
new file mode 100644 (file)
index 0000000..8f740f4
--- /dev/null
@@ -0,0 +1,7 @@
+.. 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.
index 2870eeb6fbdd2fe14ae7406502b1f905eec53edf..61737fd660adc8987a5e2282522096c5c5dce513 100644 (file)
@@ -50,7 +50,10 @@ def _scan_declarative_assignments_and_apply_types(
 
     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(
index 26bb0ac67aa6a4987dd10cc32f57de11e6ba8613..67c3fa209162e997b724ad0ecf30e30eef73506d 100644 (file)
@@ -208,6 +208,8 @@ def _info_for_cls(
 ) -> 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
 
diff --git a/test/ext/mypy/incremental/ticket_6476/__init__.py b/test/ext/mypy/incremental/ticket_6476/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/ext/mypy/incremental/ticket_6476/base.py b/test/ext/mypy/incremental/ticket_6476/base.py
new file mode 100644 (file)
index 0000000..fc14e47
--- /dev/null
@@ -0,0 +1,8 @@
+from sqlalchemy.ext.declarative import declarative_base
+
+
+class CustomBase:
+    x = 5
+
+
+sql_base = declarative_base(cls=CustomBase)
diff --git a/test/ext/mypy/incremental/ticket_6476/patch1.testpatch b/test/ext/mypy/incremental/ticket_6476/patch1.testpatch
new file mode 100644 (file)
index 0000000..75a66c7
--- /dev/null
@@ -0,0 +1,7 @@
+--- 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
diff --git a/test/ext/mypy/incremental/ticket_6476/table.py b/test/ext/mypy/incremental/ticket_6476/table.py
new file mode 100644 (file)
index 0000000..bf971db
--- /dev/null
@@ -0,0 +1,5 @@
+from .base import sql_base
+
+
+class Table(sql_base):
+    pass