Clean up __before__ and __after__ handling and make it Python 3-compatible

--HG--
branch : py3k
master
Dustin C. Hatch 2012-11-30 14:37:02 -06:00
parent 232bb17d6f
commit 17cac57721
1 changed files with 27 additions and 30 deletions

View File

@ -90,40 +90,12 @@ class Application(object):
start_response_wrapper = StartResponseWrapper(start_response)
request.start_response = start_response_wrapper
try:
# If the callable has an __before__ attribute, call it
if hasattr(func, '__before__'):
func.__before__(request)
# If the callable is an instance method and its class has
# a __before__ method, call that
elif hasattr(func, 'im_self') and \
hasattr(func.im_self, '__before__'):
func.im_self.__before__(request)
# The callable might be a partial, so check the inner func
elif hasattr(func, 'func'):
if hasattr(func.func, '__before__'):
func.func.__before__(request)
elif hasattr(func.func, 'im_self') and \
hasattr(func.func.im_self, '__before__'):
func.func.im_self.__before__(request)
self._call_before(func)(request)
response = func(request)
except WSGIHTTPException as e:
return e(environ, start_response)
finally:
# If the callable has an __after__ method, call it
if hasattr(func, '__after__'):
func.__after__(request)
# If the callable is an instance method and its class has
# an __after__ method, call that
elif hasattr(func, 'im_self') and \
hasattr(func.im_self, '__after__'):
func.im_self.__after__(request)
# The callable might be a partial, so check the inner func
elif hasattr(func, 'func'):
if hasattr(func.func, '__after__'):
func.func.__after__(request)
elif hasattr(func.func, 'im_self') and \
hasattr(func.func.im_self, '__after__'):
func.func.im_self.__after__(request)
self._call_after(func)(request)
# The callable might have returned just a string, which is OK,
# but we need to wrap it in a Response object
@ -142,6 +114,31 @@ class Application(object):
if not environ['REQUEST_METHOD'] == 'HEAD':
return response.app_iter
def _call_after(self, func):
try:
return self._find_attr(func, '__after__')
except AttributeError:
return lambda r: None
def _call_before(self, func):
try:
return self._find_attr(func, '__before__')
except AttributeError:
return lambda r: None
def _find_attr(self, obj, attr):
try:
# Object has the specified attribute itself
return getattr(obj, attr)
except AttributeError:
# Object is a bound method; look for the attribute on the instance
if hasattr(obj, '__self__'):
return self._find_attr(obj.__self__, attr)
# Object is a partial; look for the attribute on the inner function
elif hasattr(obj, 'func'):
return self._find_attr(obj.func, attr)
raise
class StartResponseWrapper():
def __init__(self, start_response):