summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/ext/mutable.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2011-06-04 19:43:39 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2011-06-04 19:43:39 -0400
commit5cac2468b6ef9e7ab4c0f3400477b697cd2d4ec6 (patch)
tree8097715208803eba6d8baeddc5dfe50d3fd5bade /lib/sqlalchemy/ext/mutable.py
parentc25412d90a1ad13fd09618aa5f21a0d109251002 (diff)
downloadsqlalchemy-5cac2468b6ef9e7ab4c0f3400477b697cd2d4ec6.tar.gz
- Repaired new "mutable" extension to propagate
events to subclasses correctly; don't create multiple event listeners for subclasses either. [ticket:2180]
Diffstat (limited to 'lib/sqlalchemy/ext/mutable.py')
-rw-r--r--lib/sqlalchemy/ext/mutable.py21
1 files changed, 13 insertions, 8 deletions
diff --git a/lib/sqlalchemy/ext/mutable.py b/lib/sqlalchemy/ext/mutable.py
index 078f9f3a2..39204f59d 100644
--- a/lib/sqlalchemy/ext/mutable.py
+++ b/lib/sqlalchemy/ext/mutable.py
@@ -347,12 +347,16 @@ class MutableBase(object):
return weakref.WeakKeyDictionary()
@classmethod
- def _listen_on_attribute(cls, attribute, coerce):
+ def _listen_on_attribute(cls, attribute, coerce, parent_cls):
"""Establish this type as a mutation listener for the given
mapped descriptor.
"""
key = attribute.key
+ if parent_cls is not attribute.class_:
+ return
+
+ # rely on "propagate" here
parent_cls = attribute.class_
def load(state, *args):
@@ -398,11 +402,12 @@ class MutableBase(object):
for val in state_dict['ext.mutable.values']:
val._parents[state.obj()] = key
- event.listen(parent_cls, 'load', load, raw=True)
- event.listen(parent_cls, 'refresh', load, raw=True)
- event.listen(attribute, 'set', set, raw=True, retval=True)
- event.listen(parent_cls, 'pickle', pickle, raw=True)
- event.listen(parent_cls, 'unpickle', unpickle, raw=True)
+
+ event.listen(parent_cls, 'load', load, raw=True, propagate=True)
+ event.listen(parent_cls, 'refresh', load, raw=True, propagate=True)
+ event.listen(attribute, 'set', set, raw=True, retval=True, propagate=True)
+ event.listen(parent_cls, 'pickle', pickle, raw=True, propagate=True)
+ event.listen(parent_cls, 'unpickle', unpickle, raw=True, propagate=True)
class Mutable(MutableBase):
"""Mixin that defines transparent propagation of change
@@ -434,7 +439,7 @@ class Mutable(MutableBase):
mapped descriptor.
"""
- cls._listen_on_attribute(attribute, True)
+ cls._listen_on_attribute(attribute, True, attribute.class_)
@classmethod
def associate_with(cls, sqltype):
@@ -548,7 +553,7 @@ class MutableComposite(MutableBase):
def listen_for_type(mapper, class_):
for prop in mapper.iterate_properties:
if hasattr(prop, 'composite_class') and issubclass(prop.composite_class, cls):
- cls._listen_on_attribute(getattr(class_, prop.key), False)
+ cls._listen_on_attribute(getattr(class_, prop.key), False, class_)
event.listen(mapper, 'mapper_configured', listen_for_type)