diff options
Diffstat (limited to 'lib/sqlalchemy')
| -rw-r--r-- | lib/sqlalchemy/ext/associationproxy.py | 45 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/collections.py | 55 |
2 files changed, 90 insertions, 10 deletions
diff --git a/lib/sqlalchemy/ext/associationproxy.py b/lib/sqlalchemy/ext/associationproxy.py index 472bd1b2c..c5a2b4d07 100644 --- a/lib/sqlalchemy/ext/associationproxy.py +++ b/lib/sqlalchemy/ext/associationproxy.py @@ -176,8 +176,9 @@ class AssociationProxy(object): self._scalar_set(target, values) else: proxy = self.__get__(obj, None) - proxy.clear() - self._set(proxy, values) + if proxy is not values: + proxy.clear() + self._set(proxy, values) def __delete__(self, obj): delattr(obj, self.key) @@ -653,7 +654,12 @@ class _AssociationSet(object): for value in other: self.add(value) - __ior__ = update + def __ior__(self, other): + if util.duck_type_collection(other) is not set: + return NotImplemented + for value in other: + self.add(value) + return self def _set(self): return util.Set(iter(self)) @@ -672,7 +678,12 @@ class _AssociationSet(object): for value in other: self.discard(value) - __isub__ = difference_update + def __isub__(self, other): + if util.duck_type_collection(other) is not set: + return NotImplemented + for value in other: + self.discard(value) + return self def intersection(self, other): return util.Set(self).intersection(other) @@ -689,7 +700,18 @@ class _AssociationSet(object): for value in add: self.add(value) - __iand__ = intersection_update + def __iand__(self, other): + if util.duck_type_collection(other) is not set: + return NotImplemented + want, have = self.intersection(other), util.Set(self) + + remove, add = have - want, want - have + + for value in remove: + self.remove(value) + for value in add: + self.add(value) + return self def symmetric_difference(self, other): return util.Set(self).symmetric_difference(other) @@ -706,7 +728,18 @@ class _AssociationSet(object): for value in add: self.add(value) - __ixor__ = symmetric_difference_update + def __ixor__(self, other): + if util.duck_type_collection(other) is not set: + return NotImplemented + want, have = self.symmetric_difference(other), util.Set(self) + + remove, add = have - want, want - have + + for value in remove: + self.remove(value) + for value in add: + self.add(value) + return self def issubset(self, other): return util.Set(self).issubset(other) diff --git a/lib/sqlalchemy/orm/collections.py b/lib/sqlalchemy/orm/collections.py index ddbf6f005..106601640 100644 --- a/lib/sqlalchemy/orm/collections.py +++ b/lib/sqlalchemy/orm/collections.py @@ -1138,7 +1138,17 @@ def _set_decorators(): self.add(item) _tidy(update) return update - __ior__ = update + + def __ior__(fn): + def __ior__(self, value): + if sautil.duck_type_collection(value) is not set: + return NotImplemented + for item in value: + if item not in self: + self.add(item) + return self + _tidy(__ior__) + return __ior__ def difference_update(fn): def difference_update(self, value): @@ -1146,7 +1156,16 @@ def _set_decorators(): self.discard(item) _tidy(difference_update) return difference_update - __isub__ = difference_update + + def __isub__(fn): + def __isub__(self, value): + if sautil.duck_type_collection(value) is not set: + return NotImplemented + for item in value: + self.discard(item) + return self + _tidy(__isub__) + return __isub__ def intersection_update(fn): def intersection_update(self, other): @@ -1159,7 +1178,21 @@ def _set_decorators(): self.add(item) _tidy(intersection_update) return intersection_update - __iand__ = intersection_update + + def __iand__(fn): + def __iand__(self, other): + if sautil.duck_type_collection(other) is not set: + return NotImplemented + want, have = self.intersection(other), sautil.Set(self) + remove, add = have - want, want - have + + for item in remove: + self.remove(item) + for item in add: + self.add(item) + return self + _tidy(__iand__) + return __iand__ def symmetric_difference_update(fn): def symmetric_difference_update(self, other): @@ -1172,7 +1205,21 @@ def _set_decorators(): self.add(item) _tidy(symmetric_difference_update) return symmetric_difference_update - __ixor__ = symmetric_difference_update + + def __ixor__(fn): + def __ixor__(self, other): + if sautil.duck_type_collection(other) is not set: + return NotImplemented + want, have = self.symmetric_difference(other), sautil.Set(self) + remove, add = have - want, want - have + + for item in remove: + self.remove(item) + for item in add: + self.add(item) + return self + _tidy(__ixor__) + return __ixor__ l = locals().copy() l.pop('_tidy') |
