]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Consult is_attrbute flag to determine descriptor; enable for assoc proxy
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 15 Jun 2019 02:44:59 +0000 (22:44 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 15 Jun 2019 02:44:59 +0000 (22:44 -0400)
Fixed bug where the :attr:`.Mapper.all_orm_descriptors` accessor would
return an entry for the :class:`.Mapper` itself under the declarative
``__mapper___`` key, when this is not a descriptor.  The ``.is_attribute``
flag that's present on all :class:`.InspectionAttr` objects is now
consulted, which has also been modified to be ``True`` for an association
proxy, as it was erroneously set to False for this object.

Fixes: #4729
Change-Id: Ia02388cc25d004e32d337140b62a587f3e5a0b7b

doc/build/changelog/unreleased_13/4729.rst [new file with mode: 0644]
lib/sqlalchemy/ext/associationproxy.py
lib/sqlalchemy/orm/instrumentation.py
test/ext/declarative/test_basic.py
test/orm/test_inspect.py

diff --git a/doc/build/changelog/unreleased_13/4729.rst b/doc/build/changelog/unreleased_13/4729.rst
new file mode 100644 (file)
index 0000000..3fa55b6
--- /dev/null
@@ -0,0 +1,10 @@
+.. change::
+    :tags: bug, orm
+    :tickets: 4729
+
+    Fixed bug where the :attr:`.Mapper.all_orm_descriptors` accessor would
+    return an entry for the :class:`.Mapper` itself under the declarative
+    ``__mapper___`` key, when this is not a descriptor.  The ``.is_attribute``
+    flag that's present on all :class:`.InspectionAttr` objects is now
+    consulted, which has also been modified to be ``True`` for an association
+    proxy, as it was erroneously set to False for this object.
index 9a8294f3c776ff4116186320a505de182ed242da..32dee79c6926173caa690d5526c6ed7ec9f430a8 100644 (file)
@@ -93,7 +93,7 @@ ASSOCIATION_PROXY = util.symbol("ASSOCIATION_PROXY")
 class AssociationProxy(interfaces.InspectionAttrInfo):
     """A descriptor that presents a read/write view of an object attribute."""
 
-    is_attribute = False
+    is_attribute = True
     extension_type = ASSOCIATION_PROXY
 
     def __init__(
index 7cf46227f8839fc939cb226d9594c388a56032c3..ee0cc06006c715b48228579de0c5af03fff06eb1 100644 (file)
@@ -143,7 +143,10 @@ class ClassManager(dict):
             for key in set(supercls.__dict__).difference(exclude):
                 exclude.add(key)
                 val = supercls.__dict__[key]
-                if isinstance(val, interfaces.InspectionAttr):
+                if (
+                    isinstance(val, interfaces.InspectionAttr)
+                    and val.is_attribute
+                ):
                     yield key, val
 
     def _get_class_attr_mro(self, key, default=None):
index b6c911813b8b3f73f8831333d82daff6c4d991a6..935e6f43119036fe74b52f46094ebc21e146a8c0 100644 (file)
@@ -1337,6 +1337,15 @@ class DeclarativeTest(DeclarativeTestBase):
 
         eq_(Foo.__mapper__.CHECK, True)
 
+    def test_no_change_to_all_descriptors(self):
+        base = decl.declarative_base()
+
+        class Foo(base):
+            __tablename__ = "foo"
+            id = Column(Integer, primary_key=True)
+
+        eq_(Foo.__mapper__.all_orm_descriptors.keys(), ["id"])
+
     def test_oops(self):
 
         with testing.expect_warnings(
index 48d69b6edd8330950e9e7200a3a8a6c738b419fb..e99d46672840f72a754702b791dee2268b6520fe 100644 (file)
@@ -11,6 +11,7 @@ from sqlalchemy.orm import Session
 from sqlalchemy.orm import synonym
 from sqlalchemy.orm.attributes import instance_state
 from sqlalchemy.orm.attributes import NO_VALUE
+from sqlalchemy.orm.base import InspectionAttr
 from sqlalchemy.orm.util import identity_key
 from sqlalchemy.testing import assert_raises_message
 from sqlalchemy.testing import eq_
@@ -402,9 +403,13 @@ class TestORMInspection(_fixtures.FixtureTest):
         assert "name" in u1.__dict__
 
     def test_attrs_props_prop_added_after_configure(self):
-        class AnonClass(object):
+        class Thing(InspectionAttr):
             pass
 
+        class AnonClass(object):
+            __foo__ = "bar"
+            __bat__ = Thing()
+
         from sqlalchemy.orm import mapper, column_property
         from sqlalchemy.ext.hybrid import hybrid_property