diff options
Diffstat (limited to 'lib/sqlalchemy/event/base.py')
-rw-r--r-- | lib/sqlalchemy/event/base.py | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/lib/sqlalchemy/event/base.py b/lib/sqlalchemy/event/base.py index daa6f9aea..1ba88f3d2 100644 --- a/lib/sqlalchemy/event/base.py +++ b/lib/sqlalchemy/event/base.py @@ -195,7 +195,14 @@ def _create_dispatcher_class(cls, classname, bases, dict_): dispatch_cls._event_names.append(ls.name) if getattr(cls, "_dispatch_target", None): - cls._dispatch_target.dispatch = dispatcher(cls) + the_cls = cls._dispatch_target + if ( + hasattr(the_cls, "__slots__") + and "_slots_dispatch" in the_cls.__slots__ + ): + cls._dispatch_target.dispatch = slots_dispatcher(cls) + else: + cls._dispatch_target.dispatch = dispatcher(cls) def _remove_dispatcher(cls): @@ -304,5 +311,29 @@ class dispatcher(object): def __get__(self, obj, cls): if obj is None: return self.dispatch - obj.__dict__["dispatch"] = disp = self.dispatch._for_instance(obj) + + disp = self.dispatch._for_instance(obj) + try: + obj.__dict__["dispatch"] = disp + except AttributeError as ae: + util.raise_( + TypeError( + "target %r doesn't have __dict__, should it be " + "defining _slots_dispatch?" % (obj,) + ), + replace_context=ae, + ) + return disp + + +class slots_dispatcher(dispatcher): + def __get__(self, obj, cls): + if obj is None: + return self.dispatch + + if hasattr(obj, "_slots_dispatch"): + return obj._slots_dispatch + + disp = self.dispatch._for_instance(obj) + obj._slots_dispatch = disp return disp |