diff options
author | pjenvey <devnull@localhost> | 2006-12-01 23:54:25 +0000 |
---|---|---|
committer | pjenvey <devnull@localhost> | 2006-12-01 23:54:25 +0000 |
commit | 4025ab928d8c3e5e0647c659413989e6d73975a5 (patch) | |
tree | 50db5658e5d9d5ea5f4c7bced89fec56b705655d /paste/registry.py | |
parent | 46343c9ca6e82d9623997077bb1c21aecb6e0b4e (diff) | |
download | paste-4025ab928d8c3e5e0647c659413989e6d73975a5.tar.gz |
StackedObjectRestorer tests. fixed a couple edge cases:
o get_saved_proxied_obj needed to delve down to allow access to older
(overlaid) RegistryManagers' objects (test_restorer_nested_middleman)
o save_registry_state needed to save all state, so restoration can get to every
overlaid RegistryManagers' objects
(test_restorer_middlemen_nested_evalexception). cleaned it up to do all the
saving at once, instead of piecemeal
Diffstat (limited to 'paste/registry.py')
-rw-r--r-- | paste/registry.py | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/paste/registry.py b/paste/registry.py index ffc853f..57bd0c4 100644 --- a/paste/registry.py +++ b/paste/registry.py @@ -374,42 +374,52 @@ class StackedObjectRestorer(object): self.evalcontext_id = threadinglocal.local() def save_registry_state(self, environ): - """Save the current state (top of the stack) of the registry to the - saved_registry_states dict, keyed by the request's unique identifier""" + """Save the state of this request's registry (if it hasn't already been + saved) to the saved_registry_states dict, keyed by the request's unique + identifier""" registry = environ.get('paste.registry') - if not registry: - return - if not len(registry.reglist): - # No state to save + if not registry or not len(registry.reglist) or \ + get_request_id(environ) in self.saved_registry_states: + # No Registry, no state to save, or this request's state has + # already been saved return - # The current level of the stack to be saved - saved_reglist = registry.reglist[-1] - for stacked, obj in saved_reglist.itervalues(): - # Tweak the StackedObjectProxies we want to save state for -- - # change the _current_obj stategy to search for the original - # proxied object when ran from EvalException - if '_current_obj' not in stacked.__dict__: - self.enable_restoration(stacked) + self.saved_registry_states[get_request_id(environ)] = \ + registry.reglist[:] - # prepend instead of append: we're gathering the Registry stack in the - # opposite direction - self.saved_registry_states.setdefault(get_request_id(environ), - []).insert(0, saved_reglist) + # Tweak the StackedObjectProxies we want to save state for -- change + # the _current_obj stategy to search for the original proxied object + # when ran from EvalException + for reglist in registry.reglist: + for stacked, obj in reglist.itervalues(): + self.enable_restoration(stacked) def get_saved_proxied_obj(self, stacked, request_id): """Retrieve the saved object proxied by the specified StackedObjectProxy for the request identified by request_id""" # All state for the request identifed by request_id reglists = self.saved_registry_states[request_id] + # The top of the stack was current when the exception occurred - top_reglist = reglists[-1] - return top_reglist[id(stacked)][1] + stack_level = -1 + reglist = reglists[stack_level] + stacked_id = id(stacked) + # The StackedObjectProxy may not have been registered by the + # RegistryManager that was active when the exception was raised. If it + # wasn't, continue searching down the stack until it's found + while stacked_id not in reglist and -stack_level <= len(reglists): + stack_level -= 1 + reglist = reglists[stack_level] + return reglist[id(stacked)][1] def enable_restoration(self, stacked): """Replace the specified StackedObjectProxy's _current_obj method with _current_obj_evalexception: forces recovery of the saved proxied object during EvalException's EvalContext call""" + if '_current_obj' in stacked.__dict__: + # Restoration already enabled + return + orig_current_obj = stacked._current_obj def _current_obj_evalexception(self): request_id = restorer.in_evalcontext() |