possible approach to the "append/set/clear/remove" attribute event issue

Issue #2789 resolved
Mike Bayer repo owner created an issue
diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py
index 13c2cf2..166a467 100644
--- a/lib/sqlalchemy/orm/attributes.py
+++ b/lib/sqlalchemy/orm/attributes.py
@@ -960,8 +960,6 @@ class CollectionAttributeImpl(AttributeImpl):
             collection.append_with_event(value, initiator)

     def remove(self, state, dict_, value, initiator, passive=PASSIVE_OFF):
-        if initiator and initiator.parent_token is self.parent_token:
-            return

         collection = self.get_collection(state, state.dict, passive=passive)
         if collection is PASSIVE_NO_RESULT:
diff --git a/lib/sqlalchemy/orm/collections.py b/lib/sqlalchemy/orm/collections.py
index 03917d1..a48369d 100644
--- a/lib/sqlalchemy/orm/collections.py
+++ b/lib/sqlalchemy/orm/collections.py
@@ -666,7 +666,6 @@ class CollectionAdapter(object):

     def append_with_event(self, item, initiator=None):
         """Add an entity to the collection, firing mutation events."""
-
         getattr(self._data(), '_sa_appender')(item, _sa_initiator=initiator)

     def append_without_event(self, item):
diff --git a/test/orm/test_attributes.py b/test/orm/test_attributes.py
index 4bcecb7..539dff1 100644
--- a/test/orm/test_attributes.py
+++ b/test/orm/test_attributes.py
@@ -1167,7 +1167,7 @@ class BackrefTest(fixtures.ORMTest):
         # one level deep.  without the parent_token,
         # it keeps going until a ValueError is raised
         # and this condition changes.
-        assert c1 in p1.children
+        assert c1 not in p1.children

 class CyclicBackrefAssertionTest(fixtures.TestBase):
     """test that infinite recursion due to incorrect backref assignments
diff --git a/test/orm/test_backref_mutations.py b/test/orm/test_backref_mutations.py
index 925eedf..74accf5 100644
--- a/test/orm/test_backref_mutations.py
+++ b/test/orm/test_backref_mutations.py
@@ -78,7 +78,7 @@ class O2MCollectionTest(_fixtures.FixtureTest):
         # doesn't extend to the previous collection tho,
         # which was already loaded.
         # flushing at this point means its anyone's guess.
-        assert a1 in u1.addresses
+        assert a1 not in u1.addresses
         assert a1 in u2.addresses

     def test_collection_move_notloaded(self):
@@ -699,9 +699,7 @@ class O2MStaleBackrefTest(_fixtures.FixtureTest):
         u1.addresses.append(a1)
         u2.addresses.append(a1)

-        # events haven't updated
-        # u1.addresses here.
-        u1.addresses.remove(a1)
+        assert a1 not in u1.addresses

         assert a1.user is u2
         assert a1 in u2.addresses

Comments (2)

  1. Mike Bayer reporter

    I made much more of a change here, including coming up with a more informative event token without sacrificing performance, and also moving all the "halt event" logic into backref handlers, where it can be managed more effectively and also should save on method call overhead. 550141b14c8e165.

  2. Log in to comment