From: Mike Bayer Date: Sat, 6 Nov 2010 21:19:08 +0000 (-0400) Subject: a little cleanup, but we probably need a generalized "propagate" mechanism X-Git-Tag: rel_0_7b1~253^2~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1de6d22ace3a2d5a8ff23b2417f502cf2f4326fc;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git a little cleanup, but we probably need a generalized "propagate" mechanism --- diff --git a/lib/sqlalchemy/event.py b/lib/sqlalchemy/event.py index 379c3f1dd0..5f46a11537 100644 --- a/lib/sqlalchemy/event.py +++ b/lib/sqlalchemy/event.py @@ -69,11 +69,6 @@ class _Dispatch(object): for ls in other.descriptors: getattr(self, ls.name).update(ls) - #existing_listeners = getattr(self, ls.name).listeners - #existing_listener_set = set(existing_listeners) - #existing_listeners.extend([l for l - # in ls.listeners - # if l not in existing_listener_set]) class _EventMeta(type): """Intercept new Event subclasses and create diff --git a/lib/sqlalchemy/orm/events.py b/lib/sqlalchemy/orm/events.py index 5765b9ea8b..36c12cf8ae 100644 --- a/lib/sqlalchemy/orm/events.py +++ b/lib/sqlalchemy/orm/events.py @@ -59,7 +59,12 @@ class InstrumentationEvents(event.Events): """Called when an attribute is instrumented.""" class InstanceEvents(event.Events): + """Define events specific to object lifecycle. + Instance-level don't automatically propagate their associations + to subclasses. + + """ @classmethod def accept_with(cls, target): from sqlalchemy.orm.instrumentation import ClassManager, manager_of_class @@ -75,9 +80,12 @@ class InstanceEvents(event.Events): @classmethod def listen(cls, fn, identifier, target, raw=False): if not raw: - fn = _to_instance(fn) + orig_fn = fn + def wrap(state, *arg, **kw): + return orig_fn(state.obj(), *arg, **kw) + fn = wrap event.Events.listen(fn, identifier, target) - + @classmethod def remove(cls, fn, identifier, target): raise NotImplementedError("Removal of instance events not yet implemented") @@ -443,6 +451,9 @@ class AttributeEvents(event.Events): event.Events.listen(fn, identifier, target) if propagate: + + raise NotImplementedError() + # TODO: for removal, need to implement # packaging this info for operation in reverse. @@ -452,9 +463,6 @@ class AttributeEvents(event.Events): if impl is not target: event.Events.listen(fn, identifier, impl) - def configure_listener(class_, key, inst): - event.Events.listen(fn, identifier, inst) - event.listen(configure_listener, 'on_attribute_instrument', class_) @classmethod def remove(cls, fn, identifier, target): @@ -512,9 +520,3 @@ class AttributeEvents(event.Events): """ -@util.decorator -def _to_instance(fn, state, *arg, **kw): - """Marshall the :class:`.InstanceState` argument to an instance.""" - - return fn(state.obj(), *arg, **kw) - diff --git a/lib/sqlalchemy/orm/instrumentation.py b/lib/sqlalchemy/orm/instrumentation.py index 52c1c7213c..6e357e1579 100644 --- a/lib/sqlalchemy/orm/instrumentation.py +++ b/lib/sqlalchemy/orm/instrumentation.py @@ -211,8 +211,9 @@ class ClassManager(dict): if key in self.mutable_attributes: self.mutable_attributes.remove(key) for cls in self.class_.__subclasses__(): - manager = self._subclass_manager(cls) - manager.uninstrument_attribute(key, True) + manager = manager_of_class(cls) + if manager: + manager.uninstrument_attribute(key, True) def unregister(self): """remove all instrumentation established by this ClassManager.""" diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 03e313685e..7fdf21c6cb 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -405,7 +405,6 @@ class Mapper(object): return event.listen(_event_on_init, 'on_init', manager, raw=True) - event.listen(_event_on_init_failure, 'on_init_failure', manager, raw=True) event.listen(_event_on_resurrect, 'on_resurrect', manager, raw=True) for key, method in util.iterate_attributes(self.class_): @@ -2409,22 +2408,19 @@ def _event_on_load(state): def _event_on_init(state, args, kwargs): """Trigger mapper compilation and run init_instance hooks.""" - instrumenting_mapper = state.manager.info[_INSTRUMENTOR] - # compile() always compiles all mappers - instrumenting_mapper.compile() - -def _event_on_init_failure(state, args, kwargs): - """Run init_failed hooks.""" - - instrumenting_mapper = state.manager.info[_INSTRUMENTOR] + instrumenting_mapper = state.manager.info.get(_INSTRUMENTOR) + if instrumenting_mapper: + # compile() always compiles all mappers + instrumenting_mapper.compile() def _event_on_resurrect(state): # re-populate the primary key elements # of the dict based on the mapping. - instrumenting_mapper = state.manager.info[_INSTRUMENTOR] - for col, val in zip(instrumenting_mapper.primary_key, state.key[1]): - instrumenting_mapper._set_state_attr_by_column( - state, state.dict, col, val) + instrumenting_mapper = state.manager.info.get(_INSTRUMENTOR) + if instrumenting_mapper: + for col, val in zip(instrumenting_mapper.primary_key, state.key[1]): + instrumenting_mapper._set_state_attr_by_column( + state, state.dict, col, val) def _sort_states(states):