]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Added support for the not-quite-yet-documented ``insert=True``
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 16 Mar 2014 18:50:55 +0000 (14:50 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 16 Mar 2014 18:50:55 +0000 (14:50 -0400)
flag for :func:`.event.listen` to work with mapper / instance events.

doc/build/changelog/changelog_09.rst
lib/sqlalchemy/orm/events.py
test/orm/test_events.py

index d082a29f656c68f3594448844dac416393776c3e..87606c8d83ad1351299481e75e618fb61eb3770c 100644 (file)
 .. changelog::
     :version: 0.9.4
 
+    .. change::
+        :tags: bug, orm
+
+        Added support for the not-quite-yet-documented ``insert=True``
+        flag for :func:`.event.listen` to work with mapper / instance events.
+
     .. change::
         :tags: feature, sql
 
index b6847523082b215d86e27d3ad7fcef59d757782e..078f4d12f12fc035a64aacf7a281a1325d408502 100644 (file)
@@ -58,7 +58,7 @@ class InstrumentationEvents(event.Events):
             return None
 
     @classmethod
-    def _listen(cls, event_key, propagate=True):
+    def _listen(cls, event_key, propagate=True, **kw):
         target, identifier, fn = \
             event_key.dispatch_target, event_key.identifier, event_key.fn
 
@@ -79,7 +79,7 @@ class InstrumentationEvents(event.Events):
 
         event_key.\
             with_dispatch_target(instrumentation._instrumentation_factory).\
-            with_wrapper(listen).base_listen()
+            with_wrapper(listen).base_listen(**kw)
 
     @classmethod
     def _clear(cls):
@@ -187,7 +187,7 @@ class InstanceEvents(event.Events):
         return None
 
     @classmethod
-    def _listen(cls, event_key, raw=False, propagate=False):
+    def _listen(cls, event_key, raw=False, propagate=False, **kw):
         target, identifier, fn = \
             event_key.dispatch_target, event_key.identifier, event_key.fn
 
@@ -196,7 +196,7 @@ class InstanceEvents(event.Events):
                 return fn(state.obj(), *arg, **kw)
             event_key = event_key.with_wrapper(wrap)
 
-        event_key.base_listen(propagate=propagate)
+        event_key.base_listen(propagate=propagate, **kw)
 
         if propagate:
             for mgr in target.subclass_managers(True):
@@ -347,7 +347,7 @@ class _EventsHold(event.RefCollection):
         _dispatch_target = None
 
         @classmethod
-        def _listen(cls, event_key, raw=False, propagate=False):
+        def _listen(cls, event_key, raw=False, propagate=False, **kw):
             target, identifier, fn = \
                 event_key.dispatch_target, event_key.identifier, event_key.fn
 
@@ -369,7 +369,7 @@ class _EventsHold(event.RefCollection):
                         # we are already going through __subclasses__()
                         # so leave generic propagate flag False
                         event_key.with_dispatch_target(subject).\
-                            listen(raw=raw, propagate=False)
+                            listen(raw=raw, propagate=False, **kw)
 
     def remove(self, event_key):
         target, identifier, fn = \
@@ -503,8 +503,7 @@ class MapperEvents(event.Events):
             return target
 
     @classmethod
-    def _listen(cls, event_key,
-                            raw=False, retval=False, propagate=False):
+    def _listen(cls, event_key, raw=False, retval=False, propagate=False, **kw):
         target, identifier, fn = \
             event_key.dispatch_target, event_key.identifier, event_key.fn
 
@@ -537,9 +536,10 @@ class MapperEvents(event.Events):
 
         if propagate:
             for mapper in target.self_and_descendants:
-                event_key.with_dispatch_target(mapper).base_listen(propagate=True)
+                event_key.with_dispatch_target(mapper).base_listen(
+                                                propagate=True, **kw)
         else:
-            event_key.base_listen()
+            event_key.base_listen(**kw)
 
     @classmethod
     def _clear(cls):
index 5260a724a7b08c19ae19b5f72e19c1af0e290365..9c9acc6eb409b44a0852f561c2bfd5e1e25d9e45 100644 (file)
@@ -6,7 +6,7 @@ from sqlalchemy.testing.schema import Table, Column
 from sqlalchemy.orm import mapper, relationship, \
     create_session, class_mapper, \
     Mapper, column_property, \
-    Session, sessionmaker, attributes
+    Session, sessionmaker, attributes, configure_mappers
 from sqlalchemy.orm.instrumentation import ClassManager
 from sqlalchemy.orm import instrumentation, events
 from sqlalchemy.testing import eq_
@@ -137,6 +137,58 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest):
              'before_update', 'after_update', 'before_delete',
              'after_delete'])
 
+    def test_insert_before_configured(self):
+        users, User = self.tables.users, self.classes.User
+
+        mapper(User, users)
+
+        canary = Mock()
+
+        event.listen(mapper, "before_configured", canary.listen1)
+        event.listen(mapper, "before_configured", canary.listen2, insert=True)
+        event.listen(mapper, "before_configured", canary.listen3)
+        event.listen(mapper, "before_configured", canary.listen4, insert=True)
+
+        configure_mappers()
+
+        eq_(
+            canary.mock_calls,
+            [call.listen4(), call.listen2(), call.listen1(), call.listen3()]
+        )
+
+    def test_insert_flags(self):
+        users, User = self.tables.users, self.classes.User
+
+        m = mapper(User, users)
+
+        canary = Mock()
+
+        arg = Mock()
+
+        event.listen(m, "before_insert", canary.listen1, )
+        event.listen(m, "before_insert", canary.listen2, insert=True)
+        event.listen(m, "before_insert", canary.listen3, propagate=True, insert=True)
+        event.listen(m, "load", canary.listen4)
+        event.listen(m, "load", canary.listen5, insert=True)
+        event.listen(m, "load", canary.listen6, propagate=True, insert=True)
+
+        u1 = User()
+        state = u1._sa_instance_state
+        m.dispatch.before_insert(arg, arg, arg)
+        m.class_manager.dispatch.load(arg, arg)
+        eq_(
+            canary.mock_calls,
+            [
+                call.listen3(arg, arg, arg.obj()),
+                call.listen2(arg, arg, arg.obj()),
+                call.listen1(arg, arg, arg.obj()),
+                call.listen6(arg.obj(), arg),
+                call.listen5(arg.obj(), arg),
+                call.listen4(arg.obj(), arg)
+            ]
+        )
+
+
     def test_merge(self):
         users, User = self.tables.users, self.classes.User