summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/event
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2013-08-14 19:58:34 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2013-08-14 19:58:34 -0400
commit59141d360e70d1a762719206e3cb0220b4c53fef (patch)
tree954d39dfa15a5c7b3970549dd77ec96a72444876 /lib/sqlalchemy/event
parent688d799814fff2642926d3bce93b45965cf262da (diff)
downloadsqlalchemy-59141d360e70d1a762719206e3cb0220b4c53fef.tar.gz
- apply an import refactoring to the ORM as well
- rework the event system so that event modules load after their targets, dependencies are reversed - create an improved strategy lookup system for the ORM - rework the ORM to have very few import cycles - move out "importlater" to just util.dependency - other tricks to cross-populate modules in as clear a way as possible
Diffstat (limited to 'lib/sqlalchemy/event')
-rw-r--r--lib/sqlalchemy/event/__init__.py4
-rw-r--r--lib/sqlalchemy/event/attr.py17
-rw-r--r--lib/sqlalchemy/event/base.py44
3 files changed, 44 insertions, 21 deletions
diff --git a/lib/sqlalchemy/event/__init__.py b/lib/sqlalchemy/event/__init__.py
index b996d0bbe..0a0131e23 100644
--- a/lib/sqlalchemy/event/__init__.py
+++ b/lib/sqlalchemy/event/__init__.py
@@ -5,6 +5,6 @@
# the MIT License: http://www.opensource.org/licenses/mit-license.php
from .api import CANCEL, NO_RETVAL, listen, listens_for, remove, contains
-from .base import Events
-from .attr import dispatcher, RefCollection
+from .base import Events, dispatcher
+from .attr import RefCollection
from .legacy import _legacy_signature
diff --git a/lib/sqlalchemy/event/attr.py b/lib/sqlalchemy/event/attr.py
index d667736a1..629ea5800 100644
--- a/lib/sqlalchemy/event/attr.py
+++ b/lib/sqlalchemy/event/attr.py
@@ -363,20 +363,3 @@ class _JoinedListener(_CompoundListener):
raise NotImplementedError()
-class dispatcher(object):
- """Descriptor used by target classes to
- deliver the _Dispatch class at the class level
- and produce new _Dispatch instances for target
- instances.
-
- """
- def __init__(self, events):
- self.dispatch_cls = events.dispatch
- self.events = events
-
- def __get__(self, obj, cls):
- if obj is None:
- return self.dispatch_cls
- obj.__dict__['dispatch'] = disp = self.dispatch_cls(cls)
- return disp
-
diff --git a/lib/sqlalchemy/event/base.py b/lib/sqlalchemy/event/base.py
index bb7b3b1b4..1d7bb9cd1 100644
--- a/lib/sqlalchemy/event/base.py
+++ b/lib/sqlalchemy/event/base.py
@@ -53,9 +53,17 @@ class _Dispatch(object):
"""
+ _events = None
+ """reference the :class:`.Events` class which this
+ :class:`._Dispatch` is created for."""
+
def __init__(self, _parent_cls):
self._parent_cls = _parent_cls
+ @util.classproperty
+ def _listen(cls):
+ return cls._events._listen
+
def _join(self, other):
"""Create a 'join' of this :class:`._Dispatch` and another.
@@ -115,15 +123,18 @@ def _create_dispatcher_class(cls, classname, bases, dict_):
# i.e. make a Dispatch class that shares the '_listen' method
# of the Event class, this is the straight monkeypatch.
dispatch_base = getattr(cls, 'dispatch', _Dispatch)
- cls.dispatch = dispatch_cls = type("%sDispatch" % classname,
+ dispatch_cls = type("%sDispatch" % classname,
(dispatch_base, ), {})
- dispatch_cls._listen = cls._listen
+ cls._set_dispatch(cls, dispatch_cls)
for k in dict_:
if _is_event_name(k):
setattr(dispatch_cls, k, _DispatchDescriptor(cls, dict_[k]))
_registrars[k].append(cls)
+ if getattr(cls, '_dispatch_target', None):
+ cls._dispatch_target.dispatch = dispatcher(cls)
+
def _remove_dispatcher(cls):
for k in dir(cls):
@@ -135,6 +146,17 @@ def _remove_dispatcher(cls):
class Events(util.with_metaclass(_EventMeta, object)):
"""Define event listening functions for a particular target type."""
+ @staticmethod
+ def _set_dispatch(cls, dispatch_cls):
+ # this allows an Events subclass to define additional utility
+ # methods made available to the target via
+ # "self.dispatch._events.<utilitymethod>"
+ # @staticemethod to allow easy "super" calls while in a metaclass
+ # constructor.
+ cls.dispatch = dispatch_cls
+ dispatch_cls._events = cls
+
+
@classmethod
def _accept_with(cls, target):
# Mapper, ClassManager, Session override this to
@@ -169,3 +191,21 @@ class _JoinedDispatcher(object):
self.parent = parent
self._parent_cls = local._parent_cls
+
+class dispatcher(object):
+ """Descriptor used by target classes to
+ deliver the _Dispatch class at the class level
+ and produce new _Dispatch instances for target
+ instances.
+
+ """
+ def __init__(self, events):
+ self.dispatch_cls = events.dispatch
+ self.events = events
+
+ def __get__(self, obj, cls):
+ if obj is None:
+ return self.dispatch_cls
+ obj.__dict__['dispatch'] = disp = self.dispatch_cls(cls)
+ return disp
+