.. changelog::
:version: 1.2.0b1
+ .. change:: 3853
+ :tags: bug, ext
+ :tickets: 3853
+
+ Implemented in-place mutation operators ``__ior__``, ``__iand__``,
+ ``__ixor__`` and ``__isub__`` for :class:`.mutable.MutableSet`
+ and ``__iadd__`` for :class:`.mutable.MutableList` so that change
+ events are fired off when these mutator methods are used to alter the
+ collection.
+
+ .. seealso::
+
+ :ref:`change_3853`
+
.. change:: 4003
:tags: feature, oracle
:ticket:`3991`
+.. _change_3853:
+
+In-place mutation operators work for MutableSet, MutableList
+------------------------------------------------------------
+
+Implemented the in-place mutation operators ``__ior__``, ``__iand__``,
+``__ixor__`` and ``__isub__`` for :class:`.mutable.MutableSet` and ``__iadd__``
+for :class:`.mutable.MutableList`. While these
+methods would successfully update the collection previously, they would
+not correctly fire off change events. The operators mutate the collection
+as before but additionally emit the correct change event so that the change
+becomes part of the next flush process::
+
+ model = session.query(MyModel).first()
+ model.json_set &= {1, 3}
+
+
+:ticket:`3853`
+
New Features and Improvements - Core
====================================
list.extend(self, x)
self.changed()
+ def __iadd__(self, x):
+ self.extend(x)
+ return self
+
def insert(self, i, x):
list.insert(self, i, x)
self.changed()
set.symmetric_difference_update(self, *arg)
self.changed()
+ def __ior__(self, other):
+ self.update(other)
+ return self
+
+ def __iand__(self, other):
+ self.intersection_update(other)
+ return self
+
+ def __ixor__(self, other):
+ self.symmetric_difference_update(other)
+ return self
+
+ def __isub__(self, other):
+ self.difference_update(other)
+ return self
+
def add(self, elem):
set.add(self, elem)
self.changed()
eq_(f1.data, [1, 2, 5])
+ def test_operator_extend(self):
+ sess = Session()
+
+ f1 = Foo(data=[1, 2])
+ sess.add(f1)
+ sess.commit()
+
+ f1.data += [5]
+ sess.commit()
+
+ eq_(f1.data, [1, 2, 5])
+
def test_insert(self):
sess = Session()
eq_(f1.data, set([1, 2, 5]))
+ def test_binary_update(self):
+ sess = Session()
+
+ f1 = Foo(data=set([1, 2]))
+ sess.add(f1)
+ sess.commit()
+
+ f1.data |= set([2, 5])
+ sess.commit()
+
+ eq_(f1.data, set([1, 2, 5]))
+
def test_intersection_update(self):
sess = Session()
eq_(f1.data, set([2]))
+ def test_binary_intersection_update(self):
+ sess = Session()
+
+ f1 = Foo(data=set([1, 2]))
+ sess.add(f1)
+ sess.commit()
+
+ f1.data &= set([2, 5])
+ sess.commit()
+
+ eq_(f1.data, set([2]))
+
def test_difference_update(self):
sess = Session()
eq_(f1.data, set([1]))
+ def test_operator_difference_update(self):
+ sess = Session()
+
+ f1 = Foo(data=set([1, 2]))
+ sess.add(f1)
+ sess.commit()
+
+ f1.data -= set([2, 5])
+ sess.commit()
+
+ eq_(f1.data, set([1]))
+
def test_symmetric_difference_update(self):
sess = Session()
eq_(f1.data, set([1, 5]))
+ def test_binary_symmetric_difference_update(self):
+ sess = Session()
+
+ f1 = Foo(data=set([1, 2]))
+ sess.add(f1)
+ sess.commit()
+
+ f1.data ^= set([2, 5])
+ sess.commit()
+
+ eq_(f1.data, set([1, 5]))
+
def test_remove(self):
sess = Session()