summaryrefslogtreecommitdiff
path: root/paste/registry.py
diff options
context:
space:
mode:
authorpjenvey <devnull@localhost>2006-12-01 23:54:25 +0000
committerpjenvey <devnull@localhost>2006-12-01 23:54:25 +0000
commit4025ab928d8c3e5e0647c659413989e6d73975a5 (patch)
tree50db5658e5d9d5ea5f4c7bced89fec56b705655d /paste/registry.py
parent46343c9ca6e82d9623997077bb1c21aecb6e0b4e (diff)
downloadpaste-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.py50
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()