]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
include declared_directive as a declared_attr
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 10 Apr 2023 14:28:44 +0000 (10:28 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 10 Apr 2023 14:33:09 +0000 (10:33 -0400)
Fixed issue where the :meth:`_orm.declared_attr.directive` modifier was not
correctly honored for subclasses when applied to the ``__mapper_args__``
special method name, as opposed to direct use of
:class:`_orm.declared_attr`. The two constructs should have identical
runtime behaviors.

Fixes: #9625
Change-Id: I0dfe9e73bb45f70dbebc8e94ce280ad3b52e867f

doc/build/changelog/unreleased_20/9625.rst [new file with mode: 0644]
lib/sqlalchemy/orm/decl_base.py
test/orm/declarative/test_inheritance.py

diff --git a/doc/build/changelog/unreleased_20/9625.rst b/doc/build/changelog/unreleased_20/9625.rst
new file mode 100644 (file)
index 0000000..edb4c0a
--- /dev/null
@@ -0,0 +1,9 @@
+.. change::
+    :tags: bug, orm
+    :tickets: 9625
+
+    Fixed issue where the :meth:`_orm.declared_attr.directive` modifier was not
+    correctly honored for subclasses when applied to the ``__mapper_args__``
+    special method name, as opposed to direct use of
+    :class:`_orm.declared_attr`. The two constructs should have identical
+    runtime behaviors.
index bd62c3c1b448f6160e82bb7fc7c430dba718f962..beede0ddbcc217cca03eb6c777de28f86c05feab 100644 (file)
@@ -260,9 +260,9 @@ def _mapper(
 
 @util.preload_module("sqlalchemy.orm.decl_api")
 def _is_declarative_props(obj: Any) -> bool:
-    declared_attr = util.preloaded.orm_decl_api.declared_attr
+    _declared_attr_common = util.preloaded.orm_decl_api._declared_attr_common
 
-    return isinstance(obj, (declared_attr, util.classproperty))
+    return isinstance(obj, (_declared_attr_common, util.classproperty))
 
 
 def _check_declared_props_nocascade(
index 4cc086be22858840d889c2c9f9a4df3b88559c9c..e8658926bc7509efb5f6390c068d598dab0ea559 100644 (file)
@@ -68,6 +68,47 @@ class DeclarativeInheritanceTest(
         assert class_mapper(Engineer).polymorphic_identity is None
         assert class_mapper(Engineer).polymorphic_on is Person.__table__.c.type
 
+    @testing.variation("directive", ["declared_attr", "da_directive"])
+    def test_declared_attr_mapped_args(self, directive):
+        class Employee(Base):
+            __tablename__ = "employee"
+
+            id: Mapped[int] = mapped_column(primary_key=True)
+            type: Mapped[str] = mapped_column(String(50))
+
+            if directive.declared_attr:
+
+                @declared_attr
+                def __mapper_args__(cls):
+                    if cls.__name__ == "Employee":
+                        return {
+                            "polymorphic_on": cls.type,
+                            "polymorphic_identity": "Employee",
+                        }
+                    else:
+                        return {"polymorphic_identity": cls.__name__}
+
+            elif directive.da_directive:
+
+                @declared_attr.directive
+                def __mapper_args__(cls):
+                    if cls.__name__ == "Employee":
+                        return {
+                            "polymorphic_on": cls.type,
+                            "polymorphic_identity": "Employee",
+                        }
+                    else:
+                        return {"polymorphic_identity": cls.__name__}
+
+            else:
+                directive.fail()
+
+        class Engineer(Employee):
+            pass
+
+        eq_(class_mapper(Engineer).polymorphic_identity, "Engineer")
+        eq_(class_mapper(Employee).polymorphic_identity, "Employee")
+
     def test_we_must_only_copy_column_mapper_args(self):
         class Person(Base):