diff options
Diffstat (limited to 'lib/sqlalchemy/event.py')
| -rw-r--r-- | lib/sqlalchemy/event.py | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/lib/sqlalchemy/event.py b/lib/sqlalchemy/event.py index 6293572a3..f28f19ee9 100644 --- a/lib/sqlalchemy/event.py +++ b/lib/sqlalchemy/event.py @@ -8,6 +8,7 @@ from . import util, exc from itertools import chain +import weakref CANCEL = util.symbol('CANCEL') NO_RETVAL = util.symbol('NO_RETVAL') @@ -242,11 +243,12 @@ class _DispatchDescriptor(object): def __init__(self, fn): self.__name__ = fn.__name__ self.__doc__ = fn.__doc__ - self._clslevel = util.defaultdict(list) - self._empty_listeners = {} + self._clslevel = weakref.WeakKeyDictionary() + self._empty_listeners = weakref.WeakKeyDictionary() def _contains(self, cls, evt): - return evt in self._clslevel[cls] + return cls in self._clslevel and \ + evt in self._clslevel[cls] def insert(self, obj, target, propagate): assert isinstance(target, type), \ @@ -258,6 +260,8 @@ class _DispatchDescriptor(object): if cls is not target and cls not in self._clslevel: self.update_subclass(cls) else: + if cls not in self._clslevel: + self._clslevel[cls] = [] self._clslevel[cls].insert(0, obj) def append(self, obj, target, propagate): @@ -271,9 +275,13 @@ class _DispatchDescriptor(object): if cls is not target and cls not in self._clslevel: self.update_subclass(cls) else: + if cls not in self._clslevel: + self._clslevel[cls] = [] self._clslevel[cls].append(obj) def update_subclass(self, target): + if target not in self._clslevel: + self._clslevel[target] = [] clslevel = self._clslevel[target] for cls in target.__mro__[1:]: if cls in self._clslevel: @@ -288,7 +296,8 @@ class _DispatchDescriptor(object): while stack: cls = stack.pop(0) stack.extend(cls.__subclasses__()) - self._clslevel[cls].remove(obj) + if cls in self._clslevel: + self._clslevel[cls].remove(obj) def clear(self): """Clear all class level listeners""" |
