瀏覽代碼

Refs #32508 -- Raised ImproperlyConfigured/TypeError instead of using "assert" in various code.

Mateo Radman 3 年之前
父節點
當前提交
8a7ac78b70

+ 5 - 2
django/contrib/auth/views.py

@@ -12,7 +12,7 @@ from django.contrib.auth.forms import (
 )
 from django.contrib.auth.tokens import default_token_generator
 from django.contrib.sites.shortcuts import get_current_site
-from django.core.exceptions import ValidationError
+from django.core.exceptions import ImproperlyConfigured, ValidationError
 from django.http import HttpResponseRedirect, QueryDict
 from django.shortcuts import resolve_url
 from django.urls import reverse_lazy
@@ -261,7 +261,10 @@ class PasswordResetConfirmView(PasswordContextMixin, FormView):
     @method_decorator(sensitive_post_parameters())
     @method_decorator(never_cache)
     def dispatch(self, *args, **kwargs):
-        assert 'uidb64' in kwargs and 'token' in kwargs
+        if 'uidb64' not in kwargs or 'token' not in kwargs:
+            raise ImproperlyConfigured(
+                "The URL path must contain 'uidb64' and 'token' parameters."
+            )
 
         self.validlink = False
         self.user = self.get_user(kwargs['uidb64'])

+ 2 - 2
django/dispatch/dispatcher.py

@@ -80,8 +80,8 @@ class Signal:
 
         # If DEBUG is on, check that we got a good receiver
         if settings.configured and settings.DEBUG:
-            assert callable(receiver), "Signal receivers must be callable."
-
+            if not callable(receiver):
+                raise TypeError('Signal receivers must be callable.')
             # Check for **kwargs
             if not func_accepts_kwargs(receiver):
                 raise ValueError("Signal receivers must accept keyword arguments (**kwargs).")

+ 6 - 5
django/views/decorators/debug.py

@@ -77,11 +77,12 @@ def sensitive_post_parameters(*parameters):
     def decorator(view):
         @functools.wraps(view)
         def sensitive_post_parameters_wrapper(request, *args, **kwargs):
-            assert isinstance(request, HttpRequest), (
-                "sensitive_post_parameters didn't receive an HttpRequest. "
-                "If you are decorating a classmethod, be sure to use "
-                "@method_decorator."
-            )
+            if not isinstance(request, HttpRequest):
+                raise TypeError(
+                    "sensitive_post_parameters didn't receive an HttpRequest "
+                    "object. If you are decorating a classmethod, make sure "
+                    "to use @method_decorator."
+                )
             if parameters:
                 request.sensitive_post_parameters = parameters
             else:

+ 6 - 0
tests/auth_tests/test_views.py

@@ -23,6 +23,7 @@ from django.contrib.contenttypes.models import ContentType
 from django.contrib.sessions.middleware import SessionMiddleware
 from django.contrib.sites.requests import RequestSite
 from django.core import mail
+from django.core.exceptions import ImproperlyConfigured
 from django.db import connection
 from django.http import HttpRequest, HttpResponse
 from django.middleware.csrf import CsrfViewMiddleware, get_token
@@ -386,6 +387,11 @@ class PasswordResetTest(AuthViewsTestCase):
         response = Client().get('/reset/%s/set-password/' % uuidb64)
         self.assertContains(response, 'The password reset link was invalid')
 
+    def test_missing_kwargs(self):
+        msg = "The URL path must contain 'uidb64' and 'token' parameters."
+        with self.assertRaisesMessage(ImproperlyConfigured, msg):
+            self.client.get('/reset/missing_parameters/')
+
 
 @override_settings(AUTH_USER_MODEL='auth_tests.CustomUser')
 class CustomUserPasswordResetTest(AuthViewsTestCase):

+ 1 - 0
tests/auth_tests/urls.py

@@ -133,6 +133,7 @@ urlpatterns = auth_urlpatterns + [
             post_reset_login_backend='django.contrib.auth.backends.AllowAllUsersModelBackend',
         ),
     ),
+    path('reset/missing_parameters/', views.PasswordResetConfirmView.as_view()),
     path('password_change/custom/',
          views.PasswordChangeView.as_view(success_url='/custom/')),
     path('password_change/custom/named/',

+ 1 - 1
tests/dispatch/tests.py

@@ -58,7 +58,7 @@ class DispatcherTests(SimpleTestCase):
     @override_settings(DEBUG=True)
     def test_cannot_connect_non_callable(self):
         msg = 'Signal receivers must be callable.'
-        with self.assertRaisesMessage(AssertionError, msg):
+        with self.assertRaisesMessage(TypeError, msg):
             a_signal.connect(object())
         self.assertTestIsClean(a_signal)
 

+ 15 - 1
tests/view_tests/tests/test_debug.py

@@ -12,7 +12,7 @@ from unittest import mock
 from django.core import mail
 from django.core.files.uploadedfile import SimpleUploadedFile
 from django.db import DatabaseError, connection
-from django.http import Http404
+from django.http import Http404, HttpRequest, HttpResponse
 from django.shortcuts import render
 from django.template import TemplateDoesNotExist
 from django.test import RequestFactory, SimpleTestCase, override_settings
@@ -1635,3 +1635,17 @@ class DecoratorsTests(SimpleTestCase):
             @sensitive_post_parameters
             def test_func(request):
                 return index_page(request)
+
+    def test_sensitive_post_parameters_http_request(self):
+        class MyClass:
+            @sensitive_post_parameters()
+            def a_view(self, request):
+                return HttpResponse()
+
+        msg = (
+            "sensitive_post_parameters didn't receive an HttpRequest object. "
+            "If you are decorating a classmethod, make sure to use "
+            "@method_decorator."
+        )
+        with self.assertRaisesMessage(TypeError, msg):
+            MyClass().a_view(HttpRequest())