Fixed #13332 -- Corrected the cleanup code in the test client to avoid a refcounting problem with signal handlers. This is a fix for the benefit of PyPy's hybrid GC. Thanks to Alex Gaynor for the report and patch.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@12964 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
b7b38a41b0
commit
35f4150734
|
@ -221,53 +221,57 @@ class Client(object):
|
||||||
# callback function.
|
# callback function.
|
||||||
data = {}
|
data = {}
|
||||||
on_template_render = curry(store_rendered_templates, data)
|
on_template_render = curry(store_rendered_templates, data)
|
||||||
signals.template_rendered.connect(on_template_render)
|
signals.template_rendered.connect(on_template_render, dispatch_uid="template-render")
|
||||||
|
|
||||||
# Capture exceptions created by the handler.
|
# Capture exceptions created by the handler.
|
||||||
got_request_exception.connect(self.store_exc_info)
|
got_request_exception.connect(self.store_exc_info, dispatch_uid="request-exception")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = self.handler(environ)
|
|
||||||
except TemplateDoesNotExist, e:
|
|
||||||
# If the view raises an exception, Django will attempt to show
|
|
||||||
# the 500.html template. If that template is not available,
|
|
||||||
# we should ignore the error in favor of re-raising the
|
|
||||||
# underlying exception that caused the 500 error. Any other
|
|
||||||
# template found to be missing during view error handling
|
|
||||||
# should be reported as-is.
|
|
||||||
if e.args != ('500.html',):
|
|
||||||
raise
|
|
||||||
|
|
||||||
# Look for a signalled exception, clear the current context
|
try:
|
||||||
# exception data, then re-raise the signalled exception.
|
response = self.handler(environ)
|
||||||
# Also make sure that the signalled exception is cleared from
|
except TemplateDoesNotExist, e:
|
||||||
# the local cache!
|
# If the view raises an exception, Django will attempt to show
|
||||||
if self.exc_info:
|
# the 500.html template. If that template is not available,
|
||||||
exc_info = self.exc_info
|
# we should ignore the error in favor of re-raising the
|
||||||
self.exc_info = None
|
# underlying exception that caused the 500 error. Any other
|
||||||
raise exc_info[1], None, exc_info[2]
|
# template found to be missing during view error handling
|
||||||
|
# should be reported as-is.
|
||||||
|
if e.args != ('500.html',):
|
||||||
|
raise
|
||||||
|
|
||||||
# Save the client and request that stimulated the response.
|
# Look for a signalled exception, clear the current context
|
||||||
response.client = self
|
# exception data, then re-raise the signalled exception.
|
||||||
response.request = request
|
# Also make sure that the signalled exception is cleared from
|
||||||
|
# the local cache!
|
||||||
|
if self.exc_info:
|
||||||
|
exc_info = self.exc_info
|
||||||
|
self.exc_info = None
|
||||||
|
raise exc_info[1], None, exc_info[2]
|
||||||
|
|
||||||
# Add any rendered template detail to the response.
|
# Save the client and request that stimulated the response.
|
||||||
# If there was only one template rendered (the most likely case),
|
response.client = self
|
||||||
# flatten the list to a single element.
|
response.request = request
|
||||||
for detail in ('template', 'context'):
|
|
||||||
if data.get(detail):
|
# Add any rendered template detail to the response.
|
||||||
if len(data[detail]) == 1:
|
# If there was only one template rendered (the most likely case),
|
||||||
setattr(response, detail, data[detail][0]);
|
# flatten the list to a single element.
|
||||||
|
for detail in ('template', 'context'):
|
||||||
|
if data.get(detail):
|
||||||
|
if len(data[detail]) == 1:
|
||||||
|
setattr(response, detail, data[detail][0]);
|
||||||
|
else:
|
||||||
|
setattr(response, detail, data[detail])
|
||||||
else:
|
else:
|
||||||
setattr(response, detail, data[detail])
|
setattr(response, detail, None)
|
||||||
else:
|
|
||||||
setattr(response, detail, None)
|
|
||||||
|
|
||||||
# Update persistent cookie data.
|
# Update persistent cookie data.
|
||||||
if response.cookies:
|
if response.cookies:
|
||||||
self.cookies.update(response.cookies)
|
self.cookies.update(response.cookies)
|
||||||
|
|
||||||
|
return response
|
||||||
|
finally:
|
||||||
|
signals.template_rendered.disconnect(dispatch_uid="template-render")
|
||||||
|
got_request_exception.disconnect(dispatch_uid="request-exception")
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
def get(self, path, data={}, follow=False, **extra):
|
def get(self, path, data={}, follow=False, **extra):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue