summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/build/changelog/unreleased_13/5357.rst8
-rw-r--r--lib/sqlalchemy/ext/declarative/api.py2
-rw-r--r--test/ext/declarative/test_basic.py28
3 files changed, 37 insertions, 1 deletions
diff --git a/doc/build/changelog/unreleased_13/5357.rst b/doc/build/changelog/unreleased_13/5357.rst
new file mode 100644
index 000000000..4503b1386
--- /dev/null
+++ b/doc/build/changelog/unreleased_13/5357.rst
@@ -0,0 +1,8 @@
+.. change::
+ :tags: usecase, py3k
+ :tickets: #5357
+
+ Added a ``**kw`` argument to the :meth:`.DeclarativeMeta.__init__` method.
+ This allows a class to support the :pep:`487` metaclass hook
+ ``__init_subclass__``. Pull request courtesy Ewen Gillies.
+
diff --git a/lib/sqlalchemy/ext/declarative/api.py b/lib/sqlalchemy/ext/declarative/api.py
index 31b5e492c..cb3ec3cdb 100644
--- a/lib/sqlalchemy/ext/declarative/api.py
+++ b/lib/sqlalchemy/ext/declarative/api.py
@@ -69,7 +69,7 @@ def has_inherited_table(cls):
class DeclarativeMeta(type):
- def __init__(cls, classname, bases, dict_):
+ def __init__(cls, classname, bases, dict_, **kw):
if "_decl_class_registry" not in cls.__dict__:
_as_declarative(cls, classname, cls.__dict__)
type.__init__(cls, classname, bases, dict_)
diff --git a/test/ext/declarative/test_basic.py b/test/ext/declarative/test_basic.py
index 7dfcc70bb..1c03f7bd9 100644
--- a/test/ext/declarative/test_basic.py
+++ b/test/ext/declarative/test_basic.py
@@ -13,6 +13,7 @@ from sqlalchemy import testing
from sqlalchemy import UniqueConstraint
from sqlalchemy import util
from sqlalchemy.ext import declarative as decl
+from sqlalchemy.ext.declarative import DeclarativeMeta
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.ext.declarative import synonym_for
from sqlalchemy.ext.declarative.base import _DeferredMapperConfig
@@ -2131,6 +2132,33 @@ class DeclarativeTest(DeclarativeTestBase):
assert not hasattr(Foo, "data_hybrid")
+ @testing.requires.python3
+ def test_kw_support_in_declarative_meta_init(self):
+ # This will not fail if DeclarativeMeta __init__ supports **kw
+
+ class BaseUser(Base):
+ __tablename__ = "base"
+ id_ = Column(Integer, primary_key=True)
+
+ @classmethod
+ def __init_subclass__(cls, random_keyword=False, **kw):
+ super().__init_subclass__(**kw)
+ cls._set_random_keyword_used_here = random_keyword
+
+ class User(BaseUser):
+ __tablename__ = "user"
+ id_ = Column(Integer, ForeignKey("base.id_"), primary_key=True)
+
+ # Check the default option
+ eq_(User._set_random_keyword_used_here, False)
+
+ # Build the metaclass with a keyword!
+ bases = (BaseUser,)
+ UserType = DeclarativeMeta("UserType", bases, {}, random_keyword=True)
+
+ # Check to see if __init_subclass__ works in supported versions
+ eq_(UserType._set_random_keyword_used_here, True)
+
def _produce_test(inline, stringbased):
class ExplicitJoinTest(fixtures.MappedTest):