don't create _ListenerCollection objects if not needed?
Issue #2516
resolved
This would most ideally apply across the board. Here's a patch that does it in an awkward way just for schema events:
diff -r e15fc03a16a322298e27c416dce3f3fe869bdf1a lib/sqlalchemy/event.py
--- a/lib/sqlalchemy/event.py Mon Jun 18 10:06:49 2012 -0400
+++ b/lib/sqlalchemy/event.py Wed Jun 20 16:03:04 2012 -0400
@@ -115,6 +115,14 @@
def __reduce__(self):
return _UnpickleDispatch(), (self._parent_cls, )
+ def _has(self, name, cls):
+ cls_dispatch = getattr(self.__class__, name)
+ if cls in cls_dispatch._clslevel and \
+ cls_dispatch._clslevel[cls](cls):
+ return True
+ else:
+ return name in self.__dict__
+
def _update(self, other, only_propagate=True):
"""Populate from the listeners in another :class:`_Dispatch`
object."""
diff -r e15fc03a16a322298e27c416dce3f3fe869bdf1a lib/sqlalchemy/events.py
--- a/lib/sqlalchemy/events.py Mon Jun 18 10:06:49 2012 -0400
+++ b/lib/sqlalchemy/events.py Wed Jun 20 16:03:04 2012 -0400
@@ -230,9 +230,11 @@
raise NotImplementedError()
def _set_parent_with_dispatch(self, parent):
- self.dispatch.before_parent_attach(self, parent)
+ if self.dispatch._has('before_parent_attach', self.__class__):
+ self.dispatch.before_parent_attach(self, parent)
self._set_parent(parent)
- self.dispatch.after_parent_attach(self, parent)
+ if self.dispatch._has('after_parent_attach', self.__class__):
+ self.dispatch.after_parent_attach(self, parent)
class PoolEvents(event.Events):
"""Available events for :class:`.Pool`.
but perhaps we can alter _DispatchDescriptor.get to not actually generate a _ListnerCollection. _ListenerCollection can be created only when listen() is called and we can issue a separate codepath for that.
Comments (5)
-
reporter -
reporter this came out great, some modifications vs. the patch here. d25be81ba57766e9948eba408b1115a1570a7737 40098941007ff3aa1593e834915c4042c1668dc2
-
reporter - changed status to open
- removed status
major regression, not found by any existing tests....good thing I caught this
def test_bool_clslevel(self): def listen_one(x, y): pass event.listen(self.Target, "event_one", listen_one) t = self.Target() assert t.dispatch.event_one
-
reporter - changed status to resolved
-
reporter - removed milestone
Removing milestone: 0.7.9 (automated comment)
- Log in to comment
the attached patch will do it. here's a proof of concept: