]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Add __class_getitem__ to the declarative Base class
authorKai Mueller <15907922+kasium@users.noreply.github.com>
Wed, 1 Dec 2021 15:58:40 +0000 (10:58 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 1 Dec 2021 18:22:46 +0000 (13:22 -0500)
Fixed issue where the :func:`_orm.as_declarative` decorator and similar
functions used to generate the declarative base class would not copy the
``__class_getitem__()`` method from a given superclass, which prevented the
use of pep-484 generics in conjunction with the ``Base`` class. Pull
request courtesy Kai Mueller.

Fixes: #7368
Closes: #7381
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/7381
Pull-request-sha: 7db7fd869a6bb617f767fad5b71ddf7cb5f14ff5

Change-Id: I495718c3082ad6dd2c83fdbf6feba7c529e351cb

doc/build/changelog/unreleased_14/7368.rst [new file with mode: 0644]
lib/sqlalchemy/orm/decl_api.py
test/orm/declarative/test_typing_py3k.py [new file with mode: 0644]

diff --git a/doc/build/changelog/unreleased_14/7368.rst b/doc/build/changelog/unreleased_14/7368.rst
new file mode 100644 (file)
index 0000000..d4415ff
--- /dev/null
@@ -0,0 +1,9 @@
+.. change::
+    :tags: bug, orm, mypy
+    :tickets: 7368
+
+    Fixed issue where the :func:`_orm.as_declarative` decorator and similar
+    functions used to generate the declarative base class would not copy the
+    ``__class_getitem__()`` method from a given superclass, which prevented the
+    use of pep-484 generics in conjunction with the ``Base`` class. Pull
+    request courtesy Kai Mueller.
index 6bc857094c82babdb9669045f70e1947ff2978a8..6951b3546ca07d8a5af156c2cf2b10ee34f69125 100644 (file)
@@ -807,6 +807,8 @@ class registry:
         class_dict["__abstract__"] = True
         if mapper:
             class_dict["__mapper_cls__"] = mapper
+        if hasattr(cls, "__class_getitem__"):
+            class_dict["__class_getitem__"] = cls.__class_getitem__
 
         return metaclass(name, bases, class_dict)
 
diff --git a/test/orm/declarative/test_typing_py3k.py b/test/orm/declarative/test_typing_py3k.py
new file mode 100644 (file)
index 0000000..823fe54
--- /dev/null
@@ -0,0 +1,25 @@
+from typing import Generic
+from typing import Type
+from typing import TypeVar
+
+from sqlalchemy import Column
+from sqlalchemy import Integer
+from sqlalchemy.orm import as_declarative
+from sqlalchemy.testing import fixtures
+
+
+class DeclarativeBaseTest(fixtures.TestBase):
+    def test_class_getitem(self):
+        T = TypeVar("T", bound="CommonBase")  # noqa
+
+        class CommonBase(Generic[T]):
+            @classmethod
+            def boring(cls: Type[T]) -> Type[T]:
+                return cls
+
+        @as_declarative()
+        class Base(CommonBase[T]):
+            pass
+
+        class Tab(Base["Tab"]):
+            a = Column(Integer, primary_key=True)