1
0
mirror of https://github.com/django/django.git synced 2024-12-22 17:16:24 +00:00

Fixed #28837 -- Fixed test client crash if an exception with more than one arg is raised.

Also removed usage of the problematic pattern elsewhere.

Regression in 6e55e1d88a.
This commit is contained in:
Nicolas Delaby 2017-11-23 17:18:03 +01:00 committed by Tim Graham
parent 7a6fbf36b1
commit 746caf3ef8
6 changed files with 21 additions and 8 deletions

View File

@ -4,7 +4,6 @@ The main QuerySet implementation. This provides the public API for the ORM.
import copy import copy
import operator import operator
import sys
import warnings import warnings
from collections import OrderedDict, namedtuple from collections import OrderedDict, namedtuple
from functools import lru_cache from functools import lru_cache
@ -521,13 +520,12 @@ class QuerySet:
params = {k: v() if callable(v) else v for k, v in params.items()} params = {k: v() if callable(v) else v for k, v in params.items()}
obj = self.create(**params) obj = self.create(**params)
return obj, True return obj, True
except IntegrityError: except IntegrityError as e:
exc_info = sys.exc_info()
try: try:
return self.get(**lookup), False return self.get(**lookup), False
except self.model.DoesNotExist: except self.model.DoesNotExist:
pass pass
raise exc_info[0](exc_info[1]).with_traceback(exc_info[2]) raise e
def _extract_model_params(self, defaults, **kwargs): def _extract_model_params(self, defaults, **kwargs):
""" """

View File

@ -480,9 +480,9 @@ class Client(RequestFactory):
# Also make sure that the signalled exception is cleared from # Also make sure that the signalled exception is cleared from
# the local cache! # the local cache!
if self.exc_info: if self.exc_info:
exc_info = self.exc_info _, exc_value, _ = self.exc_info
self.exc_info = None self.exc_info = None
raise exc_info[0](exc_info[1]).with_traceback(exc_info[2]) raise exc_value
# Save the client and request that stimulated the response. # Save the client and request that stimulated the response.
response.client = self response.client = self

View File

@ -245,7 +245,7 @@ def check_errors(fn):
def raise_last_exception(): def raise_last_exception():
global _exception global _exception
if _exception is not None: if _exception is not None:
raise _exception[0](_exception[1]).with_traceback(_exception[2]) raise _exception[1]
def ensure_echo_on(): def ensure_echo_on():

View File

@ -29,7 +29,7 @@ from django.test import (
) )
from django.urls import reverse_lazy from django.urls import reverse_lazy
from .views import get_view, post_view, trace_view from .views import TwoArgException, get_view, post_view, trace_view
@override_settings(ROOT_URLCONF='test_client.urls') @override_settings(ROOT_URLCONF='test_client.urls')
@ -713,6 +713,11 @@ class ClientTest(TestCase):
with self.assertRaisesMessage(Exception, 'exception message'): with self.assertRaisesMessage(Exception, 'exception message'):
self.client.get('/nesting_exception_view/') self.client.get('/nesting_exception_view/')
def test_response_raises_multi_arg_exception(self):
"""A request may raise an exception with more than one required arg."""
with self.assertRaises(TwoArgException):
self.client.get('/two_arg_exception/')
def test_uploading_temp_file(self): def test_uploading_temp_file(self):
with tempfile.TemporaryFile() as test_file: with tempfile.TemporaryFile() as test_file:
response = self.client.post('/upload_view/', data={'temp_file': test_file}) response = self.client.post('/upload_view/', data={'temp_file': test_file})

View File

@ -34,6 +34,7 @@ urlpatterns = [
url(r'^mass_mail_sending_view/$', views.mass_mail_sending_view), url(r'^mass_mail_sending_view/$', views.mass_mail_sending_view),
url(r'^nesting_exception_view/$', views.nesting_exception_view), url(r'^nesting_exception_view/$', views.nesting_exception_view),
url(r'^django_project_redirect/$', views.django_project_redirect), url(r'^django_project_redirect/$', views.django_project_redirect),
url(r'^two_arg_exception/$', views.two_arg_exception),
url(r'^accounts/$', RedirectView.as_view(url='login/')), url(r'^accounts/$', RedirectView.as_view(url='login/')),
url(r'^accounts/no_trailing_slash$', RedirectView.as_view(url='login/')), url(r'^accounts/no_trailing_slash$', RedirectView.as_view(url='login/')),

View File

@ -331,3 +331,12 @@ def django_project_redirect(request):
def upload_view(request): def upload_view(request):
"""Prints keys of request.FILES to the response.""" """Prints keys of request.FILES to the response."""
return HttpResponse(', '.join(request.FILES)) return HttpResponse(', '.join(request.FILES))
class TwoArgException(Exception):
def __init__(self, one, two):
pass
def two_arg_exception(request):
raise TwoArgException('one', 'two')