]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- attempting system of propagation. getting stuck on attempting to use instance...
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 6 Nov 2010 21:34:54 +0000 (17:34 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 6 Nov 2010 21:34:54 +0000 (17:34 -0400)
lib/sqlalchemy/event.py
lib/sqlalchemy/orm/deprecated_interfaces.py
test/base/test_events.py

index 5f46a115377ac725abb8ab8af16393181877dcaf..955c33797c0c63685f06930911c5ca8cd719b674 100644 (file)
@@ -18,6 +18,8 @@ def listen(fn, identifier, target, *args, **kw):
     for evt_cls in _registrars[identifier]:
         tgt = evt_cls.accept_with(target)
         if tgt is not None:
+            if kw.pop('propagate', False):
+                fn._sa_event_propagate = True
             tgt.dispatch.listen(fn, identifier, tgt, *args, **kw)
             return
     raise exc.InvalidRequestError("No such event %s for target %s" %
@@ -63,12 +65,12 @@ class _Dispatch(object):
     def descriptors(self):
         return (getattr(self, k) for k in dir(self) if k.startswith("on_"))
 
-    def update(self, other):
+    def update(self, other, only_propagate=True):
         """Populate from the listeners in another :class:`_Dispatch`
             object."""
 
         for ls in other.descriptors:
-            getattr(self, ls.name).update(ls)
+            getattr(self, ls.name).update(ls, only_propagate=only_propagate)
 
 class _EventMeta(type):
     """Intercept new Event subclasses and create 
@@ -195,7 +197,7 @@ class _ListenerCollection(object):
     def __nonzero__(self):
         return bool(self.listeners or self.parent_listeners)
     
-    def update(self, other):
+    def update(self, other, only_propagate=True):
         """Populate from the listeners in another :class:`_Dispatch`
             object."""
 
@@ -203,7 +205,9 @@ class _ListenerCollection(object):
         existing_listener_set = set(existing_listeners)
         existing_listeners.extend([l for l 
                                 in other.listeners 
-                                if l not in existing_listener_set])
+                                if l not in existing_listener_set
+                                and not only_propagate or getattr(l, '_sa_event_propagate', False)
+                                ])
 
     def append(self, obj, target):
         if obj not in self.listeners:
index 3817dc2eee3a6687130c6b357c76a4f3cca54e2c..76e023701ee7295ff0c5d628740bfe44deee6eec 100644 (file)
@@ -71,7 +71,7 @@ class MapperExtension(object):
                             ls_meth(self, instance)
                         return reconstruct
                     event.listen(go(ls_meth), 'on_load', 
-                                        self.class_manager, raw=False)
+                                        self.class_manager, raw=False, propagate=True)
                 elif meth == 'init_instance':
                     def go(ls_meth):
                         def init_instance(instance, args, kwargs):
@@ -80,7 +80,7 @@ class MapperExtension(object):
                                         instance, args, kwargs)
                         return init_instance
                     event.listen(go(ls_meth), 'on_init', 
-                                            self.class_manager, raw=False)
+                                            self.class_manager, raw=False, propagate=True)
                 elif meth == 'init_failed':
                     def go(ls_meth):
                         def init_failed(instance, args, kwargs):
@@ -90,10 +90,10 @@ class MapperExtension(object):
                             
                         return init_failed
                     event.listen(go(ls_meth), 'on_init_failure', 
-                                        self.class_manager, raw=False)
+                                        self.class_manager, raw=False, propagate=True)
                 else:
                     event.listen(ls_meth, "on_%s" % meth, self, 
-                                        raw=False, retval=True)
+                                        raw=False, retval=True, propagate=True)
 
 
     def instrument_class(self, mapper, class_):
index 9099619e5f0c2592afda5384e2a0b0de1203ebd5..995569c60ff2f9217d05ff98bd45c0ba7340cda0 100644 (file)
@@ -227,5 +227,52 @@ class TestListenOverride(TestBase):
             ]
         )
         
+class TestPropagate(TestBase):
+    def setUp(self):
+        global Target
+        
+        class TargetEvents(event.Events):
+            def on_event_one(self, arg):
+                pass
+            
+            def on_event_two(self, arg):
+                pass
+                
+        class Target(object):
+            dispatch = event.dispatcher(TargetEvents)
+            
+    
+    def test_propagate(self):
+        result = []
+        def listen_one(target, arg):
+            result.append((target, arg))
+
+        def listen_two(target, arg):
+            result.append((target, arg))
+        
+        t1 = Target()
         
+        event.listen(listen_one, "on_event_one", t1, propagate=True)
+        event.listen(listen_two, "on_event_two", t1)
+
+        t2 = Target()
+        
+        t2.dispatch.update(t1.dispatch)
+        
+        t2.dispatch.on_event_one(t2, 1)
+        t2.dispatch.on_event_two(t2, 2)
+        eq_(result, [(t2, 1)])
+        
+        
+        
+            
+        
+        
+        
+        
+        
+        
+        
+    
+    
         
\ No newline at end of file