[2.0.x] 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.

Backport of 746caf3ef8 from master
This commit is contained in:
Nicolas Delaby 2017-11-23 17:18:03 +01:00 committed by Tim Graham
parent aba31aa86b
commit ae4132a940
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 operator
import sys
import warnings
from collections import OrderedDict, namedtuple
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()}
obj = self.create(**params)
return obj, True
except IntegrityError:
exc_info = sys.exc_info()
except IntegrityError as e:
try:
return self.get(**lookup), False
except self.model.DoesNotExist:
pass
raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
raise e
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
# the local cache!
if self.exc_info:
exc_info = self.exc_info
_, exc_value, _ = self.exc_info
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.
response.client = self

View File

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

View File

@ -29,7 +29,7 @@ from django.test import (
)
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')
@ -713,6 +713,11 @@ class ClientTest(TestCase):
with self.assertRaisesMessage(Exception, 'exception message'):
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):
with tempfile.TemporaryFile() as 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'^nesting_exception_view/$', views.nesting_exception_view),
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/no_trailing_slash$', RedirectView.as_view(url='login/')),

View File

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