diff options
author | django-bot <ops@djangoproject.com> | 2022-02-03 20:24:19 +0100 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2022-02-07 20:37:05 +0100 |
commit | 9c19aff7c7561e3a82978a272ecdaad40dda5c00 (patch) | |
tree | f0506b668a013d0063e5fba3dbf4863b466713ba /tests/urlpatterns_reverse | |
parent | f68fa8b45dfac545cfc4111d4e52804c86db68d3 (diff) | |
download | django-9c19aff7c7561e3a82978a272ecdaad40dda5c00.tar.gz |
Refs #33476 -- Reformatted code with Black.
Diffstat (limited to 'tests/urlpatterns_reverse')
26 files changed, 1256 insertions, 734 deletions
diff --git a/tests/urlpatterns_reverse/erroneous_urls.py b/tests/urlpatterns_reverse/erroneous_urls.py index d8ccf2fc61..24c39a47dc 100644 --- a/tests/urlpatterns_reverse/erroneous_urls.py +++ b/tests/urlpatterns_reverse/erroneous_urls.py @@ -3,5 +3,5 @@ from django.urls import re_path from . import views urlpatterns = [ - re_path(r'(regex_error/$', views.empty_view), + re_path(r"(regex_error/$", views.empty_view), ] diff --git a/tests/urlpatterns_reverse/extra_urls.py b/tests/urlpatterns_reverse/extra_urls.py index dac9a87fd2..c356273f7b 100644 --- a/tests/urlpatterns_reverse/extra_urls.py +++ b/tests/urlpatterns_reverse/extra_urls.py @@ -7,8 +7,8 @@ from django.urls import include, path, re_path from .views import empty_view urlpatterns = [ - re_path('^e-places/([0-9]+)/$', empty_view, name='extra-places'), - re_path(r'^e-people/(?P<name>\w+)/$', empty_view, name='extra-people'), - path('', include('urlpatterns_reverse.included_urls2')), - re_path(r'^prefix/(?P<prefix>\w+)/', include('urlpatterns_reverse.included_urls2')), + re_path("^e-places/([0-9]+)/$", empty_view, name="extra-places"), + re_path(r"^e-people/(?P<name>\w+)/$", empty_view, name="extra-people"), + path("", include("urlpatterns_reverse.included_urls2")), + re_path(r"^prefix/(?P<prefix>\w+)/", include("urlpatterns_reverse.included_urls2")), ] diff --git a/tests/urlpatterns_reverse/included_app_urls.py b/tests/urlpatterns_reverse/included_app_urls.py index e8c0469143..e41007f472 100644 --- a/tests/urlpatterns_reverse/included_app_urls.py +++ b/tests/urlpatterns_reverse/included_app_urls.py @@ -2,15 +2,24 @@ from django.urls import path, re_path from . import views -app_name = 'inc-app' +app_name = "inc-app" urlpatterns = [ - path('normal/', views.empty_view, name='inc-normal-view'), - re_path('^normal/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.empty_view, name='inc-normal-view'), - - re_path(r'^\+\\\$\*/$', views.empty_view, name='inc-special-view'), - - re_path('^mixed_args/([0-9]+)/(?P<arg2>[0-9]+)/$', views.empty_view, name='inc-mixed-args'), - re_path('^no_kwargs/([0-9]+)/([0-9]+)/$', views.empty_view, name='inc-no-kwargs'), - - re_path('^view_class/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.view_class_instance, name='inc-view-class'), + path("normal/", views.empty_view, name="inc-normal-view"), + re_path( + "^normal/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$", + views.empty_view, + name="inc-normal-view", + ), + re_path(r"^\+\\\$\*/$", views.empty_view, name="inc-special-view"), + re_path( + "^mixed_args/([0-9]+)/(?P<arg2>[0-9]+)/$", + views.empty_view, + name="inc-mixed-args", + ), + re_path("^no_kwargs/([0-9]+)/([0-9]+)/$", views.empty_view, name="inc-no-kwargs"), + re_path( + "^view_class/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$", + views.view_class_instance, + name="inc-view-class", + ), ] diff --git a/tests/urlpatterns_reverse/included_named_urls.py b/tests/urlpatterns_reverse/included_named_urls.py index e0b00dd4ed..e9fd7b9742 100644 --- a/tests/urlpatterns_reverse/included_named_urls.py +++ b/tests/urlpatterns_reverse/included_named_urls.py @@ -3,8 +3,8 @@ from django.urls import include, path, re_path from .views import empty_view urlpatterns = [ - path('', empty_view, name="named-url3"), - re_path(r'^extra/(?P<extra>\w+)/$', empty_view, name="named-url4"), - re_path(r'^(?P<one>[0-9]+)|(?P<two>[0-9]+)/$', empty_view), - path('included/', include('urlpatterns_reverse.included_named_urls2')), + path("", empty_view, name="named-url3"), + re_path(r"^extra/(?P<extra>\w+)/$", empty_view, name="named-url4"), + re_path(r"^(?P<one>[0-9]+)|(?P<two>[0-9]+)/$", empty_view), + path("included/", include("urlpatterns_reverse.included_named_urls2")), ] diff --git a/tests/urlpatterns_reverse/included_named_urls2.py b/tests/urlpatterns_reverse/included_named_urls2.py index d8103eae04..c5e002c67a 100644 --- a/tests/urlpatterns_reverse/included_named_urls2.py +++ b/tests/urlpatterns_reverse/included_named_urls2.py @@ -3,7 +3,7 @@ from django.urls import path, re_path from .views import empty_view urlpatterns = [ - path('', empty_view, name="named-url5"), - re_path(r'^extra/(?P<extra>\w+)/$', empty_view, name="named-url6"), - re_path(r'^(?P<one>[0-9]+)|(?P<two>[0-9]+)/$', empty_view), + path("", empty_view, name="named-url5"), + re_path(r"^extra/(?P<extra>\w+)/$", empty_view, name="named-url6"), + re_path(r"^(?P<one>[0-9]+)|(?P<two>[0-9]+)/$", empty_view), ] diff --git a/tests/urlpatterns_reverse/included_namespace_urls.py b/tests/urlpatterns_reverse/included_namespace_urls.py index 0b3b2b5a19..a120cde188 100644 --- a/tests/urlpatterns_reverse/included_namespace_urls.py +++ b/tests/urlpatterns_reverse/included_namespace_urls.py @@ -3,23 +3,37 @@ from django.urls import include, path, re_path from .utils import URLObject from .views import empty_view, view_class_instance -testobj3 = URLObject('testapp', 'test-ns3') -testobj4 = URLObject('testapp', 'test-ns4') +testobj3 = URLObject("testapp", "test-ns3") +testobj4 = URLObject("testapp", "test-ns4") -app_name = 'included_namespace_urls' +app_name = "included_namespace_urls" urlpatterns = [ - path('normal/', empty_view, name='inc-normal-view'), - re_path('^normal/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', empty_view, name='inc-normal-view'), - - re_path(r'^\+\\\$\*/$', empty_view, name='inc-special-view'), - - re_path('^mixed_args/([0-9]+)/(?P<arg2>[0-9]+)/$', empty_view, name='inc-mixed-args'), - re_path('^no_kwargs/([0-9]+)/([0-9]+)/$', empty_view, name='inc-no-kwargs'), - - re_path('^view_class/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', view_class_instance, name='inc-view-class'), - - path('test3/', include(*testobj3.urls)), - path('test4/', include(*testobj4.urls)), - path('ns-included3/', include(('urlpatterns_reverse.included_urls', 'included_urls'), namespace='inc-ns3')), - path('ns-included4/', include('urlpatterns_reverse.namespace_urls', namespace='inc-ns4')), + path("normal/", empty_view, name="inc-normal-view"), + re_path( + "^normal/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$", + empty_view, + name="inc-normal-view", + ), + re_path(r"^\+\\\$\*/$", empty_view, name="inc-special-view"), + re_path( + "^mixed_args/([0-9]+)/(?P<arg2>[0-9]+)/$", empty_view, name="inc-mixed-args" + ), + re_path("^no_kwargs/([0-9]+)/([0-9]+)/$", empty_view, name="inc-no-kwargs"), + re_path( + "^view_class/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$", + view_class_instance, + name="inc-view-class", + ), + path("test3/", include(*testobj3.urls)), + path("test4/", include(*testobj4.urls)), + path( + "ns-included3/", + include( + ("urlpatterns_reverse.included_urls", "included_urls"), namespace="inc-ns3" + ), + ), + path( + "ns-included4/", + include("urlpatterns_reverse.namespace_urls", namespace="inc-ns4"), + ), ] diff --git a/tests/urlpatterns_reverse/included_no_kwargs_urls.py b/tests/urlpatterns_reverse/included_no_kwargs_urls.py index aa1a1a51a7..b51b600fe8 100644 --- a/tests/urlpatterns_reverse/included_no_kwargs_urls.py +++ b/tests/urlpatterns_reverse/included_no_kwargs_urls.py @@ -3,5 +3,5 @@ from django.urls import re_path from .views import empty_view urlpatterns = [ - re_path('^inner-no-kwargs/([0-9]+)/$', empty_view, name="inner-no-kwargs") + re_path("^inner-no-kwargs/([0-9]+)/$", empty_view, name="inner-no-kwargs") ] diff --git a/tests/urlpatterns_reverse/included_urls.py b/tests/urlpatterns_reverse/included_urls.py index f34010b28f..9e80cf5952 100644 --- a/tests/urlpatterns_reverse/included_urls.py +++ b/tests/urlpatterns_reverse/included_urls.py @@ -3,7 +3,7 @@ from django.urls import path, re_path from .views import empty_view urlpatterns = [ - path('', empty_view, name='inner-nothing'), - re_path(r'extra/(?P<extra>\w+)/$', empty_view, name='inner-extra'), - re_path(r'(?P<one>[0-9]+)|(?P<two>[0-9]+)/$', empty_view, name='inner-disjunction'), + path("", empty_view, name="inner-nothing"), + re_path(r"extra/(?P<extra>\w+)/$", empty_view, name="inner-extra"), + re_path(r"(?P<one>[0-9]+)|(?P<two>[0-9]+)/$", empty_view, name="inner-disjunction"), ] diff --git a/tests/urlpatterns_reverse/included_urls2.py b/tests/urlpatterns_reverse/included_urls2.py index ec61aecce1..5d502383c2 100644 --- a/tests/urlpatterns_reverse/included_urls2.py +++ b/tests/urlpatterns_reverse/included_urls2.py @@ -10,6 +10,6 @@ from django.urls import re_path from .views import empty_view urlpatterns = [ - re_path(r'^part/(?P<value>\w+)/$', empty_view, name='part'), - re_path(r'^part2/(?:(?P<value>\w+)/)?$', empty_view, name='part2'), + re_path(r"^part/(?P<value>\w+)/$", empty_view, name="part"), + re_path(r"^part2/(?:(?P<value>\w+)/)?$", empty_view, name="part2"), ] diff --git a/tests/urlpatterns_reverse/method_view_urls.py b/tests/urlpatterns_reverse/method_view_urls.py index 39c53433c8..076748f75b 100644 --- a/tests/urlpatterns_reverse/method_view_urls.py +++ b/tests/urlpatterns_reverse/method_view_urls.py @@ -14,6 +14,6 @@ view_container = ViewContainer() urlpatterns = [ - path('', view_container.method_view, name='instance-method-url'), - path('', ViewContainer.classmethod_view, name='instance-method-url'), + path("", view_container.method_view, name="instance-method-url"), + path("", ViewContainer.classmethod_view, name="instance-method-url"), ] diff --git a/tests/urlpatterns_reverse/middleware.py b/tests/urlpatterns_reverse/middleware.py index 8c40125f10..5fc0405629 100644 --- a/tests/urlpatterns_reverse/middleware.py +++ b/tests/urlpatterns_reverse/middleware.py @@ -17,23 +17,25 @@ class NullChangeURLconfMiddleware(MiddlewareMixin): class ReverseInnerInResponseMiddleware(MiddlewareMixin): def process_response(self, *args, **kwargs): - return HttpResponse(reverse('inner')) + return HttpResponse(reverse("inner")) class ReverseOuterInResponseMiddleware(MiddlewareMixin): def process_response(self, *args, **kwargs): - return HttpResponse(reverse('outer')) + return HttpResponse(reverse("outer")) class ReverseInnerInStreaming(MiddlewareMixin): def process_view(self, *args, **kwargs): def stream(): - yield reverse('inner') + yield reverse("inner") + return StreamingHttpResponse(stream()) class ReverseOuterInStreaming(MiddlewareMixin): def process_view(self, *args, **kwargs): def stream(): - yield reverse('outer') + yield reverse("outer") + return StreamingHttpResponse(stream()) diff --git a/tests/urlpatterns_reverse/named_urls.py b/tests/urlpatterns_reverse/named_urls.py index 06bb834dc7..af0d69dbab 100644 --- a/tests/urlpatterns_reverse/named_urls.py +++ b/tests/urlpatterns_reverse/named_urls.py @@ -3,8 +3,8 @@ from django.urls import include, path, re_path from .views import empty_view urlpatterns = [ - path('', empty_view, name='named-url1'), - re_path(r'^extra/(?P<extra>\w+)/$', empty_view, name='named-url2'), - re_path(r'^(?P<one>[0-9]+)|(?P<two>[0-9]+)/$', empty_view), - path('included/', include('urlpatterns_reverse.included_named_urls')), + path("", empty_view, name="named-url1"), + re_path(r"^extra/(?P<extra>\w+)/$", empty_view, name="named-url2"), + re_path(r"^(?P<one>[0-9]+)|(?P<two>[0-9]+)/$", empty_view), + path("included/", include("urlpatterns_reverse.included_named_urls")), ] diff --git a/tests/urlpatterns_reverse/named_urls_conflict.py b/tests/urlpatterns_reverse/named_urls_conflict.py index b1f883271f..982dd4f157 100644 --- a/tests/urlpatterns_reverse/named_urls_conflict.py +++ b/tests/urlpatterns_reverse/named_urls_conflict.py @@ -4,14 +4,22 @@ from .views import empty_view urlpatterns = [ # No kwargs - path('conflict/cannot-go-here/', empty_view, name='name-conflict'), - path('conflict/', empty_view, name='name-conflict'), + path("conflict/cannot-go-here/", empty_view, name="name-conflict"), + path("conflict/", empty_view, name="name-conflict"), # One kwarg - re_path(r'^conflict-first/(?P<first>\w+)/$', empty_view, name='name-conflict'), - re_path(r'^conflict-cannot-go-here/(?P<middle>\w+)/$', empty_view, name='name-conflict'), - re_path(r'^conflict-middle/(?P<middle>\w+)/$', empty_view, name='name-conflict'), - re_path(r'^conflict-last/(?P<last>\w+)/$', empty_view, name='name-conflict'), + re_path(r"^conflict-first/(?P<first>\w+)/$", empty_view, name="name-conflict"), + re_path( + r"^conflict-cannot-go-here/(?P<middle>\w+)/$", empty_view, name="name-conflict" + ), + re_path(r"^conflict-middle/(?P<middle>\w+)/$", empty_view, name="name-conflict"), + re_path(r"^conflict-last/(?P<last>\w+)/$", empty_view, name="name-conflict"), # Two kwargs - re_path(r'^conflict/(?P<another>\w+)/(?P<extra>\w+)/cannot-go-here/$', empty_view, name='name-conflict'), - re_path(r'^conflict/(?P<extra>\w+)/(?P<another>\w+)/$', empty_view, name='name-conflict'), + re_path( + r"^conflict/(?P<another>\w+)/(?P<extra>\w+)/cannot-go-here/$", + empty_view, + name="name-conflict", + ), + re_path( + r"^conflict/(?P<extra>\w+)/(?P<another>\w+)/$", empty_view, name="name-conflict" + ), ] diff --git a/tests/urlpatterns_reverse/namespace_urls.py b/tests/urlpatterns_reverse/namespace_urls.py index a8fd7bb878..2e3db3ecc3 100644 --- a/tests/urlpatterns_reverse/namespace_urls.py +++ b/tests/urlpatterns_reverse/namespace_urls.py @@ -3,59 +3,82 @@ from django.urls import include, path, re_path from . import views from .utils import URLObject -testobj1 = URLObject('testapp', 'test-ns1') -testobj2 = URLObject('testapp', 'test-ns2') -default_testobj = URLObject('testapp', 'testapp') +testobj1 = URLObject("testapp", "test-ns1") +testobj2 = URLObject("testapp", "test-ns2") +default_testobj = URLObject("testapp", "testapp") -otherobj1 = URLObject('nodefault', 'other-ns1') -otherobj2 = URLObject('nodefault', 'other-ns2') +otherobj1 = URLObject("nodefault", "other-ns1") +otherobj2 = URLObject("nodefault", "other-ns2") -newappobj1 = URLObject('newapp') +newappobj1 = URLObject("newapp") -app_name = 'namespace_urls' +app_name = "namespace_urls" urlpatterns = [ - path('normal/', views.empty_view, name='normal-view'), - re_path(r'^normal/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.empty_view, name='normal-view'), - path('resolver_match/', views.pass_resolver_match_view, name='test-resolver-match'), - - re_path(r'^\+\\\$\*/$', views.empty_view, name='special-view'), - - re_path(r'^mixed_args/([0-9]+)/(?P<arg2>[0-9]+)/$', views.empty_view, name='mixed-args'), - re_path(r'^no_kwargs/([0-9]+)/([0-9]+)/$', views.empty_view, name='no-kwargs'), - - re_path(r'^view_class/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.view_class_instance, name='view-class'), - - re_path(r'^unnamed/normal/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.empty_view), - re_path(r'^unnamed/view_class/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.view_class_instance), - - path('test1/', include(*testobj1.urls)), - path('test2/', include(*testobj2.urls)), - path('default/', include(*default_testobj.urls)), - - path('other1/', include(*otherobj1.urls)), - re_path(r'^other[246]/', include(*otherobj2.urls)), - - path('newapp1/', include(newappobj1.app_urls, 'new-ns1')), - path('new-default/', include(newappobj1.app_urls)), - - re_path(r'^app-included[135]/', include('urlpatterns_reverse.included_app_urls', namespace='app-ns1')), - path('app-included2/', include('urlpatterns_reverse.included_app_urls', namespace='app-ns2')), - - re_path(r'^ns-included[135]/', include('urlpatterns_reverse.included_namespace_urls', namespace='inc-ns1')), - path('ns-included2/', include('urlpatterns_reverse.included_namespace_urls', namespace='inc-ns2')), - - path('app-included/', include('urlpatterns_reverse.included_namespace_urls', 'inc-app')), - - path('included/', include('urlpatterns_reverse.included_namespace_urls')), + path("normal/", views.empty_view, name="normal-view"), re_path( - r'^inc(?P<outer>[0-9]+)/', include(('urlpatterns_reverse.included_urls', 'included_urls'), namespace='inc-ns5') + r"^normal/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$", + views.empty_view, + name="normal-view", ), - re_path(r'^included/([0-9]+)/', include('urlpatterns_reverse.included_namespace_urls')), - + path("resolver_match/", views.pass_resolver_match_view, name="test-resolver-match"), + re_path(r"^\+\\\$\*/$", views.empty_view, name="special-view"), re_path( - r'^ns-outer/(?P<outer>[0-9]+)/', - include('urlpatterns_reverse.included_namespace_urls', namespace='inc-outer') + r"^mixed_args/([0-9]+)/(?P<arg2>[0-9]+)/$", views.empty_view, name="mixed-args" + ), + re_path(r"^no_kwargs/([0-9]+)/([0-9]+)/$", views.empty_view, name="no-kwargs"), + re_path( + r"^view_class/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$", + views.view_class_instance, + name="view-class", + ), + re_path(r"^unnamed/normal/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$", views.empty_view), + re_path( + r"^unnamed/view_class/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$", + views.view_class_instance, + ), + path("test1/", include(*testobj1.urls)), + path("test2/", include(*testobj2.urls)), + path("default/", include(*default_testobj.urls)), + path("other1/", include(*otherobj1.urls)), + re_path(r"^other[246]/", include(*otherobj2.urls)), + path("newapp1/", include(newappobj1.app_urls, "new-ns1")), + path("new-default/", include(newappobj1.app_urls)), + re_path( + r"^app-included[135]/", + include("urlpatterns_reverse.included_app_urls", namespace="app-ns1"), + ), + path( + "app-included2/", + include("urlpatterns_reverse.included_app_urls", namespace="app-ns2"), + ), + re_path( + r"^ns-included[135]/", + include("urlpatterns_reverse.included_namespace_urls", namespace="inc-ns1"), + ), + path( + "ns-included2/", + include("urlpatterns_reverse.included_namespace_urls", namespace="inc-ns2"), + ), + path( + "app-included/", + include("urlpatterns_reverse.included_namespace_urls", "inc-app"), + ), + path("included/", include("urlpatterns_reverse.included_namespace_urls")), + re_path( + r"^inc(?P<outer>[0-9]+)/", + include( + ("urlpatterns_reverse.included_urls", "included_urls"), namespace="inc-ns5" + ), + ), + re_path( + r"^included/([0-9]+)/", include("urlpatterns_reverse.included_namespace_urls") + ), + re_path( + r"^ns-outer/(?P<outer>[0-9]+)/", + include("urlpatterns_reverse.included_namespace_urls", namespace="inc-outer"), + ), + re_path( + r"^\+\\\$\*/", + include("urlpatterns_reverse.namespace_urls", namespace="special"), ), - - re_path(r'^\+\\\$\*/', include('urlpatterns_reverse.namespace_urls', namespace='special')), ] diff --git a/tests/urlpatterns_reverse/nested_urls.py b/tests/urlpatterns_reverse/nested_urls.py index d5af7d0d02..0986759a68 100644 --- a/tests/urlpatterns_reverse/nested_urls.py +++ b/tests/urlpatterns_reverse/nested_urls.py @@ -14,12 +14,15 @@ class View3(View): pass -nested = ([ - path('view1/', view1, name='view1'), - path('view3/', View3.as_view(), name='view3'), -], 'backend') +nested = ( + [ + path("view1/", view1, name="view1"), + path("view3/", View3.as_view(), name="view3"), + ], + "backend", +) urlpatterns = [ - path('some/path/', include(nested, namespace='nested')), - path('view2/', view2, name='view2'), + path("some/path/", include(nested, namespace="nested")), + path("view2/", view2, name="view2"), ] diff --git a/tests/urlpatterns_reverse/reverse_lazy_urls.py b/tests/urlpatterns_reverse/reverse_lazy_urls.py index 1cbda44fe9..049c2e3ee8 100644 --- a/tests/urlpatterns_reverse/reverse_lazy_urls.py +++ b/tests/urlpatterns_reverse/reverse_lazy_urls.py @@ -3,8 +3,8 @@ from django.urls import path from .views import LazyRedirectView, empty_view, login_required_view urlpatterns = [ - path('redirected_to/', empty_view, name='named-lazy-url-redirected-to'), - path('login/', empty_view, name='some-login-page'), - path('login_required_view/', login_required_view), - path('redirect/', LazyRedirectView.as_view()), + path("redirected_to/", empty_view, name="named-lazy-url-redirected-to"), + path("login/", empty_view, name="some-login-page"), + path("login_required_view/", login_required_view), + path("redirect/", LazyRedirectView.as_view()), ] diff --git a/tests/urlpatterns_reverse/test_localeregexdescriptor.py b/tests/urlpatterns_reverse/test_localeregexdescriptor.py index 32e36569f0..3246329432 100644 --- a/tests/urlpatterns_reverse/test_localeregexdescriptor.py +++ b/tests/urlpatterns_reverse/test_localeregexdescriptor.py @@ -10,7 +10,7 @@ from django.utils import translation here = os.path.dirname(os.path.abspath(__file__)) -@override_settings(LOCALE_PATHS=[os.path.join(here, 'translations', 'locale')]) +@override_settings(LOCALE_PATHS=[os.path.join(here, "translations", "locale")]) class LocaleRegexDescriptorTests(SimpleTestCase): def setUp(self): translation.trans_real._translations = {} @@ -19,34 +19,36 @@ class LocaleRegexDescriptorTests(SimpleTestCase): translation.trans_real._translations = {} def test_translated_regex_compiled_per_language(self): - provider = RegexPattern(translation.gettext_lazy('^foo/$')) - with translation.override('de'): + provider = RegexPattern(translation.gettext_lazy("^foo/$")) + with translation.override("de"): de_compiled = provider.regex # compiled only once per language - error = AssertionError('tried to compile url regex twice for the same language') - with mock.patch('django.urls.resolvers.re.compile', side_effect=error): + error = AssertionError( + "tried to compile url regex twice for the same language" + ) + with mock.patch("django.urls.resolvers.re.compile", side_effect=error): de_compiled_2 = provider.regex - with translation.override('fr'): + with translation.override("fr"): fr_compiled = provider.regex - self.assertEqual(fr_compiled.pattern, '^foo-fr/$') - self.assertEqual(de_compiled.pattern, '^foo-de/$') + self.assertEqual(fr_compiled.pattern, "^foo-fr/$") + self.assertEqual(de_compiled.pattern, "^foo-de/$") self.assertEqual(de_compiled, de_compiled_2) def test_nontranslated_regex_compiled_once(self): - provider = RegexPattern('^foo/$') - with translation.override('de'): + provider = RegexPattern("^foo/$") + with translation.override("de"): de_compiled = provider.regex - with translation.override('fr'): + with translation.override("fr"): # compiled only once, regardless of language - error = AssertionError('tried to compile non-translated url regex twice') - with mock.patch('django.urls.resolvers.re.compile', side_effect=error): + error = AssertionError("tried to compile non-translated url regex twice") + with mock.patch("django.urls.resolvers.re.compile", side_effect=error): fr_compiled = provider.regex - self.assertEqual(de_compiled.pattern, '^foo/$') - self.assertEqual(fr_compiled.pattern, '^foo/$') + self.assertEqual(de_compiled.pattern, "^foo/$") + self.assertEqual(fr_compiled.pattern, "^foo/$") def test_regex_compile_error(self): """Regex errors are re-raised as ImproperlyConfigured.""" - provider = RegexPattern('*') + provider = RegexPattern("*") msg = '"*" is not a valid regular expression: nothing to repeat' with self.assertRaisesMessage(ImproperlyConfigured, msg): provider.regex @@ -55,6 +57,6 @@ class LocaleRegexDescriptorTests(SimpleTestCase): self.assertIsInstance(RegexPattern.regex, LocaleRegexDescriptor) -@override_settings(LOCALE_PATHS=[Path(here) / 'translations' / 'locale']) +@override_settings(LOCALE_PATHS=[Path(here) / "translations" / "locale"]) class LocaleRegexDescriptorPathLibTests(LocaleRegexDescriptorTests): pass diff --git a/tests/urlpatterns_reverse/tests.py b/tests/urlpatterns_reverse/tests.py index 5ee4c7a52b..e293f3c505 100644 --- a/tests/urlpatterns_reverse/tests.py +++ b/tests/urlpatterns_reverse/tests.py @@ -10,18 +10,25 @@ from admin_scripts.tests import AdminScriptTestCase from django.conf import settings from django.contrib.auth.models import User from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist -from django.http import ( - HttpRequest, HttpResponsePermanentRedirect, HttpResponseRedirect, -) +from django.http import HttpRequest, HttpResponsePermanentRedirect, HttpResponseRedirect from django.shortcuts import redirect -from django.test import ( - RequestFactory, SimpleTestCase, TestCase, override_settings, -) +from django.test import RequestFactory, SimpleTestCase, TestCase, override_settings from django.test.utils import override_script_prefix from django.urls import ( - NoReverseMatch, Resolver404, ResolverMatch, URLPattern, URLResolver, - get_callable, get_resolver, get_urlconf, include, path, re_path, resolve, - reverse, reverse_lazy, + NoReverseMatch, + Resolver404, + ResolverMatch, + URLPattern, + URLResolver, + get_callable, + get_resolver, + get_urlconf, + include, + path, + re_path, + resolve, + reverse, + reverse_lazy, ) from django.urls.resolvers import RegexPattern @@ -32,256 +39,394 @@ from .views import empty_view resolve_test_data = ( # These entries are in the format: (path, url_name, app_name, namespace, view_name, func, args, kwargs) # Simple case - ('/normal/42/37/', 'normal-view', '', '', 'normal-view', views.empty_view, (), {'arg1': '42', 'arg2': '37'}), ( - '/view_class/42/37/', 'view-class', '', '', 'view-class', views.view_class_instance, (), - {'arg1': '42', 'arg2': '37'} + "/normal/42/37/", + "normal-view", + "", + "", + "normal-view", + views.empty_view, + (), + {"arg1": "42", "arg2": "37"}, ), ( - '/included/normal/42/37/', 'inc-normal-view', 'included_namespace_urls', - 'included_namespace_urls', 'included_namespace_urls:inc-normal-view', - views.empty_view, (), {'arg1': '42', 'arg2': '37'} + "/view_class/42/37/", + "view-class", + "", + "", + "view-class", + views.view_class_instance, + (), + {"arg1": "42", "arg2": "37"}, ), ( - '/included/view_class/42/37/', 'inc-view-class', 'included_namespace_urls', - 'included_namespace_urls', 'included_namespace_urls:inc-view-class', - views.view_class_instance, (), {'arg1': '42', 'arg2': '37'} + "/included/normal/42/37/", + "inc-normal-view", + "included_namespace_urls", + "included_namespace_urls", + "included_namespace_urls:inc-normal-view", + views.empty_view, + (), + {"arg1": "42", "arg2": "37"}, + ), + ( + "/included/view_class/42/37/", + "inc-view-class", + "included_namespace_urls", + "included_namespace_urls", + "included_namespace_urls:inc-view-class", + views.view_class_instance, + (), + {"arg1": "42", "arg2": "37"}, ), - # Unnamed args are dropped if you have *any* kwargs in a pattern - ('/mixed_args/42/37/', 'mixed-args', '', '', 'mixed-args', views.empty_view, (), {'arg2': '37'}), ( - '/included/mixed_args/42/37/', 'inc-mixed-args', 'included_namespace_urls', - 'included_namespace_urls', 'included_namespace_urls:inc-mixed-args', - views.empty_view, (), {'arg2': '37'} + "/mixed_args/42/37/", + "mixed-args", + "", + "", + "mixed-args", + views.empty_view, + (), + {"arg2": "37"}, ), ( - '/included/12/mixed_args/42/37/', 'inc-mixed-args', 'included_namespace_urls', - 'included_namespace_urls', 'included_namespace_urls:inc-mixed-args', - views.empty_view, (), {'arg2': '37'} + "/included/mixed_args/42/37/", + "inc-mixed-args", + "included_namespace_urls", + "included_namespace_urls", + "included_namespace_urls:inc-mixed-args", + views.empty_view, + (), + {"arg2": "37"}, + ), + ( + "/included/12/mixed_args/42/37/", + "inc-mixed-args", + "included_namespace_urls", + "included_namespace_urls", + "included_namespace_urls:inc-mixed-args", + views.empty_view, + (), + {"arg2": "37"}, ), - # Unnamed views should have None as the url_name. Regression data for #21157. ( - '/unnamed/normal/42/37/', None, '', '', 'urlpatterns_reverse.views.empty_view', views.empty_view, (), - {'arg1': '42', 'arg2': '37'} + "/unnamed/normal/42/37/", + None, + "", + "", + "urlpatterns_reverse.views.empty_view", + views.empty_view, + (), + {"arg1": "42", "arg2": "37"}, ), ( - '/unnamed/view_class/42/37/', None, '', '', 'urlpatterns_reverse.views.ViewClass', views.view_class_instance, - (), {'arg1': '42', 'arg2': '37'} + "/unnamed/view_class/42/37/", + None, + "", + "", + "urlpatterns_reverse.views.ViewClass", + views.view_class_instance, + (), + {"arg1": "42", "arg2": "37"}, ), - # If you have no kwargs, you get an args list. - ('/no_kwargs/42/37/', 'no-kwargs', '', '', 'no-kwargs', views.empty_view, ('42', '37'), {}), ( - '/included/no_kwargs/42/37/', 'inc-no-kwargs', 'included_namespace_urls', - 'included_namespace_urls', 'included_namespace_urls:inc-no-kwargs', - views.empty_view, ('42', '37'), {} + "/no_kwargs/42/37/", + "no-kwargs", + "", + "", + "no-kwargs", + views.empty_view, + ("42", "37"), + {}, ), ( - '/included/12/no_kwargs/42/37/', 'inc-no-kwargs', 'included_namespace_urls', - 'included_namespace_urls', 'included_namespace_urls:inc-no-kwargs', - views.empty_view, ('12', '42', '37'), {} + "/included/no_kwargs/42/37/", + "inc-no-kwargs", + "included_namespace_urls", + "included_namespace_urls", + "included_namespace_urls:inc-no-kwargs", + views.empty_view, + ("42", "37"), + {}, + ), + ( + "/included/12/no_kwargs/42/37/", + "inc-no-kwargs", + "included_namespace_urls", + "included_namespace_urls", + "included_namespace_urls:inc-no-kwargs", + views.empty_view, + ("12", "42", "37"), + {}, ), - # Namespaces ( - '/test1/inner/42/37/', 'urlobject-view', 'testapp', 'test-ns1', 'test-ns1:urlobject-view', - views.empty_view, (), {'arg1': '42', 'arg2': '37'} + "/test1/inner/42/37/", + "urlobject-view", + "testapp", + "test-ns1", + "test-ns1:urlobject-view", + views.empty_view, + (), + {"arg1": "42", "arg2": "37"}, ), ( - '/included/test3/inner/42/37/', 'urlobject-view', 'included_namespace_urls:testapp', - 'included_namespace_urls:test-ns3', 'included_namespace_urls:test-ns3:urlobject-view', - views.empty_view, (), {'arg1': '42', 'arg2': '37'} + "/included/test3/inner/42/37/", + "urlobject-view", + "included_namespace_urls:testapp", + "included_namespace_urls:test-ns3", + "included_namespace_urls:test-ns3:urlobject-view", + views.empty_view, + (), + {"arg1": "42", "arg2": "37"}, ), ( - '/ns-included1/normal/42/37/', 'inc-normal-view', 'included_namespace_urls', - 'inc-ns1', 'inc-ns1:inc-normal-view', - views.empty_view, (), {'arg1': '42', 'arg2': '37'} + "/ns-included1/normal/42/37/", + "inc-normal-view", + "included_namespace_urls", + "inc-ns1", + "inc-ns1:inc-normal-view", + views.empty_view, + (), + {"arg1": "42", "arg2": "37"}, ), ( - '/included/test3/inner/42/37/', 'urlobject-view', 'included_namespace_urls:testapp', - 'included_namespace_urls:test-ns3', 'included_namespace_urls:test-ns3:urlobject-view', - views.empty_view, (), {'arg1': '42', 'arg2': '37'} + "/included/test3/inner/42/37/", + "urlobject-view", + "included_namespace_urls:testapp", + "included_namespace_urls:test-ns3", + "included_namespace_urls:test-ns3:urlobject-view", + views.empty_view, + (), + {"arg1": "42", "arg2": "37"}, ), ( - '/default/inner/42/37/', 'urlobject-view', 'testapp', 'testapp', 'testapp:urlobject-view', - views.empty_view, (), {'arg1': '42', 'arg2': '37'} + "/default/inner/42/37/", + "urlobject-view", + "testapp", + "testapp", + "testapp:urlobject-view", + views.empty_view, + (), + {"arg1": "42", "arg2": "37"}, ), ( - '/other2/inner/42/37/', 'urlobject-view', 'nodefault', 'other-ns2', 'other-ns2:urlobject-view', - views.empty_view, (), {'arg1': '42', 'arg2': '37'} + "/other2/inner/42/37/", + "urlobject-view", + "nodefault", + "other-ns2", + "other-ns2:urlobject-view", + views.empty_view, + (), + {"arg1": "42", "arg2": "37"}, ), ( - '/other1/inner/42/37/', 'urlobject-view', 'nodefault', 'other-ns1', 'other-ns1:urlobject-view', - views.empty_view, (), {'arg1': '42', 'arg2': '37'} + "/other1/inner/42/37/", + "urlobject-view", + "nodefault", + "other-ns1", + "other-ns1:urlobject-view", + views.empty_view, + (), + {"arg1": "42", "arg2": "37"}, ), - # Nested namespaces ( - '/ns-included1/test3/inner/42/37/', 'urlobject-view', 'included_namespace_urls:testapp', - 'inc-ns1:test-ns3', 'inc-ns1:test-ns3:urlobject-view', - views.empty_view, (), {'arg1': '42', 'arg2': '37'} + "/ns-included1/test3/inner/42/37/", + "urlobject-view", + "included_namespace_urls:testapp", + "inc-ns1:test-ns3", + "inc-ns1:test-ns3:urlobject-view", + views.empty_view, + (), + {"arg1": "42", "arg2": "37"}, ), ( - '/ns-included1/ns-included4/ns-included2/test3/inner/42/37/', 'urlobject-view', - 'included_namespace_urls:namespace_urls:included_namespace_urls:testapp', - 'inc-ns1:inc-ns4:inc-ns2:test-ns3', - 'inc-ns1:inc-ns4:inc-ns2:test-ns3:urlobject-view', - views.empty_view, (), {'arg1': '42', 'arg2': '37'} + "/ns-included1/ns-included4/ns-included2/test3/inner/42/37/", + "urlobject-view", + "included_namespace_urls:namespace_urls:included_namespace_urls:testapp", + "inc-ns1:inc-ns4:inc-ns2:test-ns3", + "inc-ns1:inc-ns4:inc-ns2:test-ns3:urlobject-view", + views.empty_view, + (), + {"arg1": "42", "arg2": "37"}, ), ( - '/app-included/test3/inner/42/37/', 'urlobject-view', 'included_namespace_urls:testapp', 'inc-app:test-ns3', - 'inc-app:test-ns3:urlobject-view', views.empty_view, (), {'arg1': '42', 'arg2': '37'} + "/app-included/test3/inner/42/37/", + "urlobject-view", + "included_namespace_urls:testapp", + "inc-app:test-ns3", + "inc-app:test-ns3:urlobject-view", + views.empty_view, + (), + {"arg1": "42", "arg2": "37"}, ), ( - '/app-included/ns-included4/ns-included2/test3/inner/42/37/', 'urlobject-view', - 'included_namespace_urls:namespace_urls:included_namespace_urls:testapp', - 'inc-app:inc-ns4:inc-ns2:test-ns3', - 'inc-app:inc-ns4:inc-ns2:test-ns3:urlobject-view', - views.empty_view, (), {'arg1': '42', 'arg2': '37'} + "/app-included/ns-included4/ns-included2/test3/inner/42/37/", + "urlobject-view", + "included_namespace_urls:namespace_urls:included_namespace_urls:testapp", + "inc-app:inc-ns4:inc-ns2:test-ns3", + "inc-app:inc-ns4:inc-ns2:test-ns3:urlobject-view", + views.empty_view, + (), + {"arg1": "42", "arg2": "37"}, ), - # Namespaces capturing variables ( - '/inc70/', 'inner-nothing', 'included_urls', 'inc-ns5', 'inc-ns5:inner-nothing', - views.empty_view, (), {'outer': '70'} + "/inc70/", + "inner-nothing", + "included_urls", + "inc-ns5", + "inc-ns5:inner-nothing", + views.empty_view, + (), + {"outer": "70"}, ), ( - '/inc78/extra/foobar/', 'inner-extra', 'included_urls', 'inc-ns5', 'inc-ns5:inner-extra', - views.empty_view, (), {'outer': '78', 'extra': 'foobar'} + "/inc78/extra/foobar/", + "inner-extra", + "included_urls", + "inc-ns5", + "inc-ns5:inner-extra", + views.empty_view, + (), + {"outer": "78", "extra": "foobar"}, ), ) test_data = ( - ('places', '/places/3/', [3], {}), - ('places', '/places/3/', ['3'], {}), - ('places', NoReverseMatch, ['a'], {}), - ('places', NoReverseMatch, [], {}), - ('places?', '/place/', [], {}), - ('places+', '/places/', [], {}), - ('places*', '/place/', [], {}), - ('places2?', '/', [], {}), - ('places2+', '/places/', [], {}), - ('places2*', '/', [], {}), - ('places3', '/places/4/', [4], {}), - ('places3', '/places/harlem/', ['harlem'], {}), - ('places3', NoReverseMatch, ['harlem64'], {}), - ('places4', '/places/3/', [], {'id': 3}), - ('people', NoReverseMatch, [], {}), - ('people', '/people/adrian/', ['adrian'], {}), - ('people', '/people/adrian/', [], {'name': 'adrian'}), - ('people', NoReverseMatch, ['name with spaces'], {}), - ('people', NoReverseMatch, [], {'name': 'name with spaces'}), - ('people2', '/people/name/', [], {}), - ('people2a', '/people/name/fred/', ['fred'], {}), - ('people_backref', '/people/nate-nate/', ['nate'], {}), - ('people_backref', '/people/nate-nate/', [], {'name': 'nate'}), - ('optional', '/optional/fred/', [], {'name': 'fred'}), - ('optional', '/optional/fred/', ['fred'], {}), - ('named_optional', '/optional/1/', [1], {}), - ('named_optional', '/optional/1/', [], {'arg1': 1}), - ('named_optional', '/optional/1/2/', [1, 2], {}), - ('named_optional', '/optional/1/2/', [], {'arg1': 1, 'arg2': 2}), - ('named_optional_terminated', '/optional/1/', [1], {}), - ('named_optional_terminated', '/optional/1/', [], {'arg1': 1}), - ('named_optional_terminated', '/optional/1/2/', [1, 2], {}), - ('named_optional_terminated', '/optional/1/2/', [], {'arg1': 1, 'arg2': 2}), - ('hardcoded', '/hardcoded/', [], {}), - ('hardcoded2', '/hardcoded/doc.pdf', [], {}), - ('people3', '/people/il/adrian/', [], {'state': 'il', 'name': 'adrian'}), - ('people3', NoReverseMatch, [], {'state': 'il'}), - ('people3', NoReverseMatch, [], {'name': 'adrian'}), - ('people4', NoReverseMatch, [], {'state': 'il', 'name': 'adrian'}), - ('people6', '/people/il/test/adrian/', ['il/test', 'adrian'], {}), - ('people6', '/people//adrian/', ['adrian'], {}), - ('range', '/character_set/a/', [], {}), - ('range2', '/character_set/x/', [], {}), - ('price', '/price/$10/', ['10'], {}), - ('price2', '/price/$10/', ['10'], {}), - ('price3', '/price/$10/', ['10'], {}), - ('product', '/product/chocolate+($2.00)/', [], {'price': '2.00', 'product': 'chocolate'}), - ('headlines', '/headlines/2007.5.21/', [], {'year': 2007, 'month': 5, 'day': 21}), + ("places", "/places/3/", [3], {}), + ("places", "/places/3/", ["3"], {}), + ("places", NoReverseMatch, ["a"], {}), + ("places", NoReverseMatch, [], {}), + ("places?", "/place/", [], {}), + ("places+", "/places/", [], {}), + ("places*", "/place/", [], {}), + ("places2?", "/", [], {}), + ("places2+", "/places/", [], {}), + ("places2*", "/", [], {}), + ("places3", "/places/4/", [4], {}), + ("places3", "/places/harlem/", ["harlem"], {}), + ("places3", NoReverseMatch, ["harlem64"], {}), + ("places4", "/places/3/", [], {"id": 3}), + ("people", NoReverseMatch, [], {}), + ("people", "/people/adrian/", ["adrian"], {}), + ("people", "/people/adrian/", [], {"name": "adrian"}), + ("people", NoReverseMatch, ["name with spaces"], {}), + ("people", NoReverseMatch, [], {"name": "name with spaces"}), + ("people2", "/people/name/", [], {}), + ("people2a", "/people/name/fred/", ["fred"], {}), + ("people_backref", "/people/nate-nate/", ["nate"], {}), + ("people_backref", "/people/nate-nate/", [], {"name": "nate"}), + ("optional", "/optional/fred/", [], {"name": "fred"}), + ("optional", "/optional/fred/", ["fred"], {}), + ("named_optional", "/optional/1/", [1], {}), + ("named_optional", "/optional/1/", [], {"arg1": 1}), + ("named_optional", "/optional/1/2/", [1, 2], {}), + ("named_optional", "/optional/1/2/", [], {"arg1": 1, "arg2": 2}), + ("named_optional_terminated", "/optional/1/", [1], {}), + ("named_optional_terminated", "/optional/1/", [], {"arg1": 1}), + ("named_optional_terminated", "/optional/1/2/", [1, 2], {}), + ("named_optional_terminated", "/optional/1/2/", [], {"arg1": 1, "arg2": 2}), + ("hardcoded", "/hardcoded/", [], {}), + ("hardcoded2", "/hardcoded/doc.pdf", [], {}), + ("people3", "/people/il/adrian/", [], {"state": "il", "name": "adrian"}), + ("people3", NoReverseMatch, [], {"state": "il"}), + ("people3", NoReverseMatch, [], {"name": "adrian"}), + ("people4", NoReverseMatch, [], {"state": "il", "name": "adrian"}), + ("people6", "/people/il/test/adrian/", ["il/test", "adrian"], {}), + ("people6", "/people//adrian/", ["adrian"], {}), + ("range", "/character_set/a/", [], {}), + ("range2", "/character_set/x/", [], {}), + ("price", "/price/$10/", ["10"], {}), + ("price2", "/price/$10/", ["10"], {}), + ("price3", "/price/$10/", ["10"], {}), ( - 'windows', r'/windows_path/C:%5CDocuments%20and%20Settings%5Cspam/', [], - {'drive_name': 'C', 'path': r'Documents and Settings\spam'} + "product", + "/product/chocolate+($2.00)/", + [], + {"price": "2.00", "product": "chocolate"}, ), - ('special', r'/special_chars/~@+%5C$*%7C/', [r'~@+\$*|'], {}), - ('special', r'/special_chars/some%20resource/', [r'some resource'], {}), - ('special', r'/special_chars/10%25%20complete/', [r'10% complete'], {}), - ('special', r'/special_chars/some%20resource/', [], {'chars': r'some resource'}), - ('special', r'/special_chars/10%25%20complete/', [], {'chars': r'10% complete'}), - ('special', NoReverseMatch, [''], {}), - ('mixed', '/john/0/', [], {'name': 'john'}), - ('repeats', '/repeats/a/', [], {}), - ('repeats2', '/repeats/aa/', [], {}), - ('repeats3', '/repeats/aa/', [], {}), - ('test', '/test/1', [], {}), - ('inner-nothing', '/outer/42/', [], {'outer': '42'}), - ('inner-nothing', '/outer/42/', ['42'], {}), - ('inner-nothing', NoReverseMatch, ['foo'], {}), - ('inner-extra', '/outer/42/extra/inner/', [], {'extra': 'inner', 'outer': '42'}), - ('inner-extra', '/outer/42/extra/inner/', ['42', 'inner'], {}), - ('inner-extra', NoReverseMatch, ['fred', 'inner'], {}), - ('inner-no-kwargs', '/outer-no-kwargs/42/inner-no-kwargs/1/', ['42', '1'], {}), - ('disjunction', NoReverseMatch, ['foo'], {}), - ('inner-disjunction', NoReverseMatch, ['10', '11'], {}), - ('extra-places', '/e-places/10/', ['10'], {}), - ('extra-people', '/e-people/fred/', ['fred'], {}), - ('extra-people', '/e-people/fred/', [], {'name': 'fred'}), - ('part', '/part/one/', [], {'value': 'one'}), - ('part', '/prefix/xx/part/one/', [], {'value': 'one', 'prefix': 'xx'}), - ('part2', '/part2/one/', [], {'value': 'one'}), - ('part2', '/part2/', [], {}), - ('part2', '/prefix/xx/part2/one/', [], {'value': 'one', 'prefix': 'xx'}), - ('part2', '/prefix/xx/part2/', [], {'prefix': 'xx'}), - + ("headlines", "/headlines/2007.5.21/", [], {"year": 2007, "month": 5, "day": 21}), + ( + "windows", + r"/windows_path/C:%5CDocuments%20and%20Settings%5Cspam/", + [], + {"drive_name": "C", "path": r"Documents and Settings\spam"}, + ), + ("special", r"/special_chars/~@+%5C$*%7C/", [r"~@+\$*|"], {}), + ("special", r"/special_chars/some%20resource/", [r"some resource"], {}), + ("special", r"/special_chars/10%25%20complete/", [r"10% complete"], {}), + ("special", r"/special_chars/some%20resource/", [], {"chars": r"some resource"}), + ("special", r"/special_chars/10%25%20complete/", [], {"chars": r"10% complete"}), + ("special", NoReverseMatch, [""], {}), + ("mixed", "/john/0/", [], {"name": "john"}), + ("repeats", "/repeats/a/", [], {}), + ("repeats2", "/repeats/aa/", [], {}), + ("repeats3", "/repeats/aa/", [], {}), + ("test", "/test/1", [], {}), + ("inner-nothing", "/outer/42/", [], {"outer": "42"}), + ("inner-nothing", "/outer/42/", ["42"], {}), + ("inner-nothing", NoReverseMatch, ["foo"], {}), + ("inner-extra", "/outer/42/extra/inner/", [], {"extra": "inner", "outer": "42"}), + ("inner-extra", "/outer/42/extra/inner/", ["42", "inner"], {}), + ("inner-extra", NoReverseMatch, ["fred", "inner"], {}), + ("inner-no-kwargs", "/outer-no-kwargs/42/inner-no-kwargs/1/", ["42", "1"], {}), + ("disjunction", NoReverseMatch, ["foo"], {}), + ("inner-disjunction", NoReverseMatch, ["10", "11"], {}), + ("extra-places", "/e-places/10/", ["10"], {}), + ("extra-people", "/e-people/fred/", ["fred"], {}), + ("extra-people", "/e-people/fred/", [], {"name": "fred"}), + ("part", "/part/one/", [], {"value": "one"}), + ("part", "/prefix/xx/part/one/", [], {"value": "one", "prefix": "xx"}), + ("part2", "/part2/one/", [], {"value": "one"}), + ("part2", "/part2/", [], {}), + ("part2", "/prefix/xx/part2/one/", [], {"value": "one", "prefix": "xx"}), + ("part2", "/prefix/xx/part2/", [], {"prefix": "xx"}), # Tests for nested groups. Nested capturing groups will only work if you # *only* supply the correct outer group. - ('nested-noncapture', '/nested/noncapture/opt', [], {'p': 'opt'}), - ('nested-capture', '/nested/capture/opt/', ['opt/'], {}), - ('nested-capture', NoReverseMatch, [], {'p': 'opt'}), - ('nested-mixedcapture', '/nested/capture/mixed/opt', ['opt'], {}), - ('nested-mixedcapture', NoReverseMatch, [], {'p': 'opt'}), - ('nested-namedcapture', '/nested/capture/named/opt/', [], {'outer': 'opt/'}), - ('nested-namedcapture', NoReverseMatch, [], {'outer': 'opt/', 'inner': 'opt'}), - ('nested-namedcapture', NoReverseMatch, [], {'inner': 'opt'}), - - ('non_path_include', '/includes/non_path_include/', [], {}), - + ("nested-noncapture", "/nested/noncapture/opt", [], {"p": "opt"}), + ("nested-capture", "/nested/capture/opt/", ["opt/"], {}), + ("nested-capture", NoReverseMatch, [], {"p": "opt"}), + ("nested-mixedcapture", "/nested/capture/mixed/opt", ["opt"], {}), + ("nested-mixedcapture", NoReverseMatch, [], {"p": "opt"}), + ("nested-namedcapture", "/nested/capture/named/opt/", [], {"outer": "opt/"}), + ("nested-namedcapture", NoReverseMatch, [], {"outer": "opt/", "inner": "opt"}), + ("nested-namedcapture", NoReverseMatch, [], {"inner": "opt"}), + ("non_path_include", "/includes/non_path_include/", [], {}), # Tests for #13154 - ('defaults', '/defaults_view1/3/', [], {'arg1': 3, 'arg2': 1}), - ('defaults', '/defaults_view2/3/', [], {'arg1': 3, 'arg2': 2}), - ('defaults', NoReverseMatch, [], {'arg1': 3, 'arg2': 3}), - ('defaults', NoReverseMatch, [], {'arg2': 1}), - + ("defaults", "/defaults_view1/3/", [], {"arg1": 3, "arg2": 1}), + ("defaults", "/defaults_view2/3/", [], {"arg1": 3, "arg2": 2}), + ("defaults", NoReverseMatch, [], {"arg1": 3, "arg2": 3}), + ("defaults", NoReverseMatch, [], {"arg2": 1}), # Security tests - ('security', '/%2Fexample.com/security/', ['/example.com'], {}), + ("security", "/%2Fexample.com/security/", ["/example.com"], {}), ) -@override_settings(ROOT_URLCONF='urlpatterns_reverse.no_urls') +@override_settings(ROOT_URLCONF="urlpatterns_reverse.no_urls") class NoURLPatternsTests(SimpleTestCase): - def test_no_urls_exception(self): """ URLResolver should raise an exception when no urlpatterns exist. """ - resolver = URLResolver(RegexPattern(r'^$'), settings.ROOT_URLCONF) + resolver = URLResolver(RegexPattern(r"^$"), settings.ROOT_URLCONF) with self.assertRaisesMessage( ImproperlyConfigured, "The included URLconf 'urlpatterns_reverse.no_urls' does not " "appear to have any patterns in it. If you see the 'urlpatterns' " "variable with valid patterns in the file then the issue is " - "probably caused by a circular import." + "probably caused by a circular import.", ): - getattr(resolver, 'url_patterns') + getattr(resolver, "url_patterns") -@override_settings(ROOT_URLCONF='urlpatterns_reverse.urls') +@override_settings(ROOT_URLCONF="urlpatterns_reverse.urls") class URLPatternReverse(SimpleTestCase): - def test_urlpattern_reverse(self): for name, expected, args, kwargs in test_data: with self.subTest(name=name, args=args, kwargs=kwargs): @@ -300,52 +445,50 @@ class URLPatternReverse(SimpleTestCase): def test_mixing_args_and_kwargs(self): msg = "Don't mix *args and **kwargs in call to reverse()!" with self.assertRaisesMessage(ValueError, msg): - reverse('name', args=['a'], kwargs={'b': 'c'}) + reverse("name", args=["a"], kwargs={"b": "c"}) - @override_script_prefix('/{{invalid}}/') + @override_script_prefix("/{{invalid}}/") def test_prefix_braces(self): self.assertEqual( - '/%7B%7Binvalid%7D%7D/includes/non_path_include/', - reverse('non_path_include') + "/%7B%7Binvalid%7D%7D/includes/non_path_include/", + reverse("non_path_include"), ) def test_prefix_parenthesis(self): # Parentheses are allowed and should not cause errors or be escaped - with override_script_prefix('/bogus)/'): + with override_script_prefix("/bogus)/"): self.assertEqual( - '/bogus)/includes/non_path_include/', - reverse('non_path_include') + "/bogus)/includes/non_path_include/", reverse("non_path_include") ) - with override_script_prefix('/(bogus)/'): + with override_script_prefix("/(bogus)/"): self.assertEqual( - '/(bogus)/includes/non_path_include/', - reverse('non_path_include') + "/(bogus)/includes/non_path_include/", reverse("non_path_include") ) - @override_script_prefix('/bump%20map/') + @override_script_prefix("/bump%20map/") def test_prefix_format_char(self): self.assertEqual( - '/bump%2520map/includes/non_path_include/', - reverse('non_path_include') + "/bump%2520map/includes/non_path_include/", reverse("non_path_include") ) - @override_script_prefix('/%7Eme/') + @override_script_prefix("/%7Eme/") def test_non_urlsafe_prefix_with_args(self): # Regression for #20022, adjusted for #24013 because ~ is an unreserved # character. Tests whether % is escaped. - self.assertEqual('/%257Eme/places/1/', reverse('places', args=[1])) + self.assertEqual("/%257Eme/places/1/", reverse("places", args=[1])) def test_patterns_reported(self): # Regression for #17076 - with self.assertRaisesMessage(NoReverseMatch, r"1 pattern(s) tried: ['people/(?P<name>\\w+)/$']"): + with self.assertRaisesMessage( + NoReverseMatch, r"1 pattern(s) tried: ['people/(?P<name>\\w+)/$']" + ): # this url exists, but requires an argument reverse("people", args=[]) - @override_script_prefix('/script:name/') + @override_script_prefix("/script:name/") def test_script_name_escaping(self): self.assertEqual( - reverse('optional', args=['foo:bar']), - '/script:name/optional/foo:bar/' + reverse("optional", args=["foo:bar"]), "/script:name/optional/foo:bar/" ) def test_view_not_found_message(self): @@ -354,22 +497,22 @@ class URLPatternReverse(SimpleTestCase): "is not a valid view function or pattern name." ) with self.assertRaisesMessage(NoReverseMatch, msg): - reverse('nonexistent-view') + reverse("nonexistent-view") def test_no_args_message(self): msg = "Reverse for 'places' with no arguments not found. 1 pattern(s) tried:" with self.assertRaisesMessage(NoReverseMatch, msg): - reverse('places') + reverse("places") def test_illegal_args_message(self): msg = "Reverse for 'places' with arguments '(1, 2)' not found. 1 pattern(s) tried:" with self.assertRaisesMessage(NoReverseMatch, msg): - reverse('places', args=(1, 2)) + reverse("places", args=(1, 2)) def test_illegal_kwargs_message(self): msg = "Reverse for 'places' with keyword arguments '{'arg1': 2}' not found. 1 pattern(s) tried:" with self.assertRaisesMessage(NoReverseMatch, msg): - reverse('places', kwargs={'arg1': 2}) + reverse("places", kwargs={"arg1": 2}) class ResolverTests(SimpleTestCase): @@ -379,27 +522,27 @@ class ResolverTests(SimpleTestCase): (#17892). """ # Pick a resolver from a namespaced URLconf - resolver = get_resolver('urlpatterns_reverse.namespace_urls') - sub_resolver = resolver.namespace_dict['test-ns1'][1] - self.assertIn('<URLPattern list>', repr(sub_resolver)) + resolver = get_resolver("urlpatterns_reverse.namespace_urls") + sub_resolver = resolver.namespace_dict["test-ns1"][1] + self.assertIn("<URLPattern list>", repr(sub_resolver)) def test_reverse_lazy_object_coercion_by_resolve(self): """ Verifies lazy object returned by reverse_lazy is coerced to text by resolve(). Previous to #21043, this would raise a TypeError. """ - urls = 'urlpatterns_reverse.named_urls' - proxy_url = reverse_lazy('named-url1', urlconf=urls) + urls = "urlpatterns_reverse.named_urls" + proxy_url = reverse_lazy("named-url1", urlconf=urls) resolver = get_resolver(urls) resolver.resolve(proxy_url) def test_resolver_reverse(self): - resolver = get_resolver('urlpatterns_reverse.named_urls') + resolver = get_resolver("urlpatterns_reverse.named_urls") test_urls = [ # (name, args, kwargs, expected) - ('named-url1', (), {}, ''), - ('named-url2', ('arg',), {}, 'extra/arg/'), - ('named-url2', (), {'extra': 'arg'}, 'extra/arg/'), + ("named-url1", (), {}, ""), + ("named-url2", ("arg",), {}, "extra/arg/"), + ("named-url2", (), {"extra": "arg"}, "extra/arg/"), ] for name, args, kwargs, expected in test_urls: with self.subTest(name=name, args=args, kwargs=kwargs): @@ -410,19 +553,19 @@ class ResolverTests(SimpleTestCase): URL pattern name arguments don't need to be unique. The last registered pattern takes precedence for conflicting names. """ - resolver = get_resolver('urlpatterns_reverse.named_urls_conflict') + resolver = get_resolver("urlpatterns_reverse.named_urls_conflict") test_urls = [ # (name, args, kwargs, expected) # Without arguments, the last URL in urlpatterns has precedence. - ('name-conflict', (), {}, 'conflict/'), + ("name-conflict", (), {}, "conflict/"), # With an arg, the last URL in urlpatterns has precedence. - ('name-conflict', ('arg',), {}, 'conflict-last/arg/'), + ("name-conflict", ("arg",), {}, "conflict-last/arg/"), # With a kwarg, other URL patterns can be reversed. - ('name-conflict', (), {'first': 'arg'}, 'conflict-first/arg/'), - ('name-conflict', (), {'middle': 'arg'}, 'conflict-middle/arg/'), - ('name-conflict', (), {'last': 'arg'}, 'conflict-last/arg/'), + ("name-conflict", (), {"first": "arg"}, "conflict-first/arg/"), + ("name-conflict", (), {"middle": "arg"}, "conflict-middle/arg/"), + ("name-conflict", (), {"last": "arg"}, "conflict-last/arg/"), # The number and order of the arguments don't interfere with reversing. - ('name-conflict', ('arg', 'arg'), {}, 'conflict/arg/arg/'), + ("name-conflict", ("arg", "arg"), {}, "conflict/arg/arg/"), ] for name, args, kwargs, expected in test_urls: with self.subTest(name=name, args=args, kwargs=kwargs): @@ -435,7 +578,7 @@ class ResolverTests(SimpleTestCase): the root pattern '^/'. Never return None from resolve() to prevent a TypeError from occurring later (#10834). """ - test_urls = ['', 'a', '\\', '.'] + test_urls = ["", "a", "\\", "."] for path_ in test_urls: with self.subTest(path=path_): with self.assertRaises(Resolver404): @@ -447,64 +590,76 @@ class ResolverTests(SimpleTestCase): a list in the right format for printing out in the DEBUG 404 page with both the patterns and URL names, if available. """ - urls = 'urlpatterns_reverse.named_urls' + urls = "urlpatterns_reverse.named_urls" # this list matches the expected URL types and names returned when # you try to resolve a nonexistent URL in the first level of included # URLs in named_urls.py (e.g., '/included/nonexistent-url') url_types_names = [ - [{'type': URLPattern, 'name': 'named-url1'}], - [{'type': URLPattern, 'name': 'named-url2'}], - [{'type': URLPattern, 'name': None}], - [{'type': URLResolver}, {'type': URLPattern, 'name': 'named-url3'}], - [{'type': URLResolver}, {'type': URLPattern, 'name': 'named-url4'}], - [{'type': URLResolver}, {'type': URLPattern, 'name': None}], - [{'type': URLResolver}, {'type': URLResolver}], + [{"type": URLPattern, "name": "named-url1"}], + [{"type": URLPattern, "name": "named-url2"}], + [{"type": URLPattern, "name": None}], + [{"type": URLResolver}, {"type": URLPattern, "name": "named-url3"}], + [{"type": URLResolver}, {"type": URLPattern, "name": "named-url4"}], + [{"type": URLResolver}, {"type": URLPattern, "name": None}], + [{"type": URLResolver}, {"type": URLResolver}], ] - with self.assertRaisesMessage(Resolver404, 'tried') as cm: - resolve('/included/nonexistent-url', urlconf=urls) + with self.assertRaisesMessage(Resolver404, "tried") as cm: + resolve("/included/nonexistent-url", urlconf=urls) e = cm.exception # make sure we at least matched the root ('/') url resolver: - self.assertIn('tried', e.args[0]) + self.assertIn("tried", e.args[0]) self.assertEqual( - len(e.args[0]['tried']), + len(e.args[0]["tried"]), len(url_types_names), - 'Wrong number of tried URLs returned. Expected %s, got %s.' % ( - len(url_types_names), len(e.args[0]['tried']) - ) + "Wrong number of tried URLs returned. Expected %s, got %s." + % (len(url_types_names), len(e.args[0]["tried"])), ) - for tried, expected in zip(e.args[0]['tried'], url_types_names): + for tried, expected in zip(e.args[0]["tried"], url_types_names): for t, e in zip(tried, expected): with self.subTest(t): - self.assertIsInstance(t, e['type']), '%s is not an instance of %s' % (t, e['type']) - if 'name' in e: - if not e['name']: - self.assertIsNone(t.name, 'Expected no URL name but found %s.' % t.name) + self.assertIsInstance( + t, e["type"] + ), "%s is not an instance of %s" % (t, e["type"]) + if "name" in e: + if not e["name"]: + self.assertIsNone( + t.name, "Expected no URL name but found %s." % t.name + ) else: self.assertEqual( t.name, - e['name'], - 'Wrong URL name. Expected "%s", got "%s".' % (e['name'], t.name) + e["name"], + 'Wrong URL name. Expected "%s", got "%s".' + % (e["name"], t.name), ) def test_namespaced_view_detail(self): - resolver = get_resolver('urlpatterns_reverse.nested_urls') - self.assertTrue(resolver._is_callback('urlpatterns_reverse.nested_urls.view1')) - self.assertTrue(resolver._is_callback('urlpatterns_reverse.nested_urls.view2')) - self.assertTrue(resolver._is_callback('urlpatterns_reverse.nested_urls.View3')) - self.assertFalse(resolver._is_callback('urlpatterns_reverse.nested_urls.blub')) + resolver = get_resolver("urlpatterns_reverse.nested_urls") + self.assertTrue(resolver._is_callback("urlpatterns_reverse.nested_urls.view1")) + self.assertTrue(resolver._is_callback("urlpatterns_reverse.nested_urls.view2")) + self.assertTrue(resolver._is_callback("urlpatterns_reverse.nested_urls.View3")) + self.assertFalse(resolver._is_callback("urlpatterns_reverse.nested_urls.blub")) def test_view_detail_as_method(self): # Views which have a class name as part of their path. - resolver = get_resolver('urlpatterns_reverse.method_view_urls') - self.assertTrue(resolver._is_callback('urlpatterns_reverse.method_view_urls.ViewContainer.method_view')) - self.assertTrue(resolver._is_callback('urlpatterns_reverse.method_view_urls.ViewContainer.classmethod_view')) + resolver = get_resolver("urlpatterns_reverse.method_view_urls") + self.assertTrue( + resolver._is_callback( + "urlpatterns_reverse.method_view_urls.ViewContainer.method_view" + ) + ) + self.assertTrue( + resolver._is_callback( + "urlpatterns_reverse.method_view_urls.ViewContainer.classmethod_view" + ) + ) def test_populate_concurrency(self): """ URLResolver._populate() can be called concurrently, but not more than once per thread (#26888). """ - resolver = URLResolver(RegexPattern(r'^/'), 'urlpatterns_reverse.urls') + resolver = URLResolver(RegexPattern(r"^/"), "urlpatterns_reverse.urls") resolver._local.populating = True thread = threading.Thread(target=resolver._populate) thread.start() @@ -512,33 +667,35 @@ class ResolverTests(SimpleTestCase): self.assertNotEqual(resolver._reverse_dict, {}) -@override_settings(ROOT_URLCONF='urlpatterns_reverse.reverse_lazy_urls') +@override_settings(ROOT_URLCONF="urlpatterns_reverse.reverse_lazy_urls") class ReverseLazyTest(TestCase): - def test_redirect_with_lazy_reverse(self): - response = self.client.get('/redirect/') + response = self.client.get("/redirect/") self.assertRedirects(response, "/redirected_to/", status_code=302) def test_user_permission_with_lazy_reverse(self): - alfred = User.objects.create_user('alfred', 'alfred@example.com', password='testpw') - response = self.client.get('/login_required_view/') - self.assertRedirects(response, "/login/?next=/login_required_view/", status_code=302) + alfred = User.objects.create_user( + "alfred", "alfred@example.com", password="testpw" + ) + response = self.client.get("/login_required_view/") + self.assertRedirects( + response, "/login/?next=/login_required_view/", status_code=302 + ) self.client.force_login(alfred) - response = self.client.get('/login_required_view/') + response = self.client.get("/login_required_view/") self.assertEqual(response.status_code, 200) def test_inserting_reverse_lazy_into_string(self): self.assertEqual( - 'Some URL: %s' % reverse_lazy('some-login-page'), - 'Some URL: /login/' + "Some URL: %s" % reverse_lazy("some-login-page"), "Some URL: /login/" ) def test_build_absolute_uri(self): factory = RequestFactory() - request = factory.get('/') + request = factory.get("/") self.assertEqual( - request.build_absolute_uri(reverse_lazy('some-login-page')), - 'http://testserver/login/', + request.build_absolute_uri(reverse_lazy("some-login-page")), + "http://testserver/login/", ) @@ -547,21 +704,21 @@ class ReverseLazySettingsTest(AdminScriptTestCase): reverse_lazy can be used in settings without causing a circular import error. """ + def setUp(self): super().setUp() self.write_settings( - 'settings.py', + "settings.py", extra="from django.urls import reverse_lazy\nLOGIN_URL = reverse_lazy('login')", ) def test_lazy_in_settings(self): - out, err = self.run_manage(['check']) + out, err = self.run_manage(["check"]) self.assertNoOutput(err) -@override_settings(ROOT_URLCONF='urlpatterns_reverse.urls') +@override_settings(ROOT_URLCONF="urlpatterns_reverse.urls") class ReverseShortcutTests(SimpleTestCase): - def test_redirect_to_object(self): # We don't really need a model; just something with a get_absolute_url class FakeObj: @@ -570,36 +727,36 @@ class ReverseShortcutTests(SimpleTestCase): res = redirect(FakeObj()) self.assertIsInstance(res, HttpResponseRedirect) - self.assertEqual(res.url, '/hi-there/') + self.assertEqual(res.url, "/hi-there/") res = redirect(FakeObj(), permanent=True) self.assertIsInstance(res, HttpResponsePermanentRedirect) - self.assertEqual(res.url, '/hi-there/') + self.assertEqual(res.url, "/hi-there/") def test_redirect_to_view_name(self): - res = redirect('hardcoded2') - self.assertEqual(res.url, '/hardcoded/doc.pdf') - res = redirect('places', 1) - self.assertEqual(res.url, '/places/1/') - res = redirect('headlines', year='2008', month='02', day='17') - self.assertEqual(res.url, '/headlines/2008.02.17/') + res = redirect("hardcoded2") + self.assertEqual(res.url, "/hardcoded/doc.pdf") + res = redirect("places", 1) + self.assertEqual(res.url, "/places/1/") + res = redirect("headlines", year="2008", month="02", day="17") + self.assertEqual(res.url, "/headlines/2008.02.17/") with self.assertRaises(NoReverseMatch): - redirect('not-a-view') + redirect("not-a-view") def test_redirect_to_url(self): - res = redirect('/foo/') - self.assertEqual(res.url, '/foo/') - res = redirect('http://example.com/') - self.assertEqual(res.url, 'http://example.com/') + res = redirect("/foo/") + self.assertEqual(res.url, "/foo/") + res = redirect("http://example.com/") + self.assertEqual(res.url, "http://example.com/") # Assert that we can redirect using UTF-8 strings - res = redirect('/æøå/abc/') - self.assertEqual(res.url, '/%C3%A6%C3%B8%C3%A5/abc/') + res = redirect("/æøå/abc/") + self.assertEqual(res.url, "/%C3%A6%C3%B8%C3%A5/abc/") # Assert that no imports are attempted when dealing with a relative path # (previously, the below would resolve in a UnicodeEncodeError from __import__ ) - res = redirect('/æøå.abc/') - self.assertEqual(res.url, '/%C3%A6%C3%B8%C3%A5.abc/') - res = redirect('os.path') - self.assertEqual(res.url, 'os.path') + res = redirect("/æøå.abc/") + self.assertEqual(res.url, "/%C3%A6%C3%B8%C3%A5.abc/") + res = redirect("os.path") + self.assertEqual(res.url, "os.path") def test_no_illegal_imports(self): # modules that are not listed in urlpatterns should not be importable @@ -609,28 +766,29 @@ class ReverseShortcutTests(SimpleTestCase): def test_reverse_by_path_nested(self): # Views added to urlpatterns using include() should be reversible. from .views import nested_view - self.assertEqual(reverse(nested_view), '/includes/nested_path/') + + self.assertEqual(reverse(nested_view), "/includes/nested_path/") def test_redirect_view_object(self): from .views import absolute_kwargs_view + res = redirect(absolute_kwargs_view) - self.assertEqual(res.url, '/absolute_arg_view/') + self.assertEqual(res.url, "/absolute_arg_view/") with self.assertRaises(NoReverseMatch): redirect(absolute_kwargs_view, wrong_argument=None) -@override_settings(ROOT_URLCONF='urlpatterns_reverse.namespace_urls') +@override_settings(ROOT_URLCONF="urlpatterns_reverse.namespace_urls") class NamespaceTests(SimpleTestCase): - def test_ambiguous_object(self): """ Names deployed via dynamic URL objects that require namespaces can't be resolved. """ test_urls = [ - ('urlobject-view', [], {}), - ('urlobject-view', [37, 42], {}), - ('urlobject-view', [], {'arg1': 42, 'arg2': 37}), + ("urlobject-view", [], {}), + ("urlobject-view", [37, 42], {}), + ("urlobject-view", [], {"arg1": 42, "arg2": 37}), ] for name, args, kwargs in test_urls: with self.subTest(name=name, args=args, kwargs=kwargs): @@ -643,9 +801,9 @@ class NamespaceTests(SimpleTestCase): be resolved. """ test_urls = [ - ('inner-nothing', [], {}), - ('inner-nothing', [37, 42], {}), - ('inner-nothing', [], {'arg1': 42, 'arg2': 37}), + ("inner-nothing", [], {}), + ("inner-nothing", [37, 42], {}), + ("inner-nothing", [], {"arg1": 42, "arg2": 37}), ] for name, args, kwargs in test_urls: with self.subTest(name=name, args=args, kwargs=kwargs): @@ -655,8 +813,8 @@ class NamespaceTests(SimpleTestCase): def test_non_existent_namespace(self): """Nonexistent namespaces raise errors.""" test_urls = [ - 'blahblah:urlobject-view', - 'test-ns1:blahblah:urlobject-view', + "blahblah:urlobject-view", + "test-ns1:blahblah:urlobject-view", ] for name in test_urls: with self.subTest(name=name): @@ -666,10 +824,10 @@ class NamespaceTests(SimpleTestCase): def test_normal_name(self): """Normal lookups work as expected.""" test_urls = [ - ('normal-view', [], {}, '/normal/'), - ('normal-view', [37, 42], {}, '/normal/37/42/'), - ('normal-view', [], {'arg1': 42, 'arg2': 37}, '/normal/42/37/'), - ('special-view', [], {}, '/+%5C$*/'), + ("normal-view", [], {}, "/normal/"), + ("normal-view", [37, 42], {}, "/normal/37/42/"), + ("normal-view", [], {"arg1": 42, "arg2": 37}, "/normal/42/37/"), + ("special-view", [], {}, "/+%5C$*/"), ] for name, args, kwargs, expected in test_urls: with self.subTest(name=name, args=args, kwargs=kwargs): @@ -678,10 +836,20 @@ class NamespaceTests(SimpleTestCase): def test_simple_included_name(self): """Normal lookups work on names included from other patterns.""" test_urls = [ - ('included_namespace_urls:inc-normal-view', [], {}, '/included/normal/'), - ('included_namespace_urls:inc-normal-view', [37, 42], {}, '/included/normal/37/42/'), - ('included_namespace_urls:inc-normal-view', [], {'arg1': 42, 'arg2': 37}, '/included/normal/42/37/'), - ('included_namespace_urls:inc-special-view', [], {}, '/included/+%5C$*/'), + ("included_namespace_urls:inc-normal-view", [], {}, "/included/normal/"), + ( + "included_namespace_urls:inc-normal-view", + [37, 42], + {}, + "/included/normal/37/42/", + ), + ( + "included_namespace_urls:inc-normal-view", + [], + {"arg1": 42, "arg2": 37}, + "/included/normal/42/37/", + ), + ("included_namespace_urls:inc-special-view", [], {}, "/included/+%5C$*/"), ] for name, args, kwargs, expected in test_urls: with self.subTest(name=name, args=args, kwargs=kwargs): @@ -690,10 +858,15 @@ class NamespaceTests(SimpleTestCase): def test_namespace_object(self): """Dynamic URL objects can be found using a namespace.""" test_urls = [ - ('test-ns1:urlobject-view', [], {}, '/test1/inner/'), - ('test-ns1:urlobject-view', [37, 42], {}, '/test1/inner/37/42/'), - ('test-ns1:urlobject-view', [], {'arg1': 42, 'arg2': 37}, '/test1/inner/42/37/'), - ('test-ns1:urlobject-special-view', [], {}, '/test1/inner/+%5C$*/'), + ("test-ns1:urlobject-view", [], {}, "/test1/inner/"), + ("test-ns1:urlobject-view", [37, 42], {}, "/test1/inner/37/42/"), + ( + "test-ns1:urlobject-view", + [], + {"arg1": 42, "arg2": 37}, + "/test1/inner/42/37/", + ), + ("test-ns1:urlobject-special-view", [], {}, "/test1/inner/+%5C$*/"), ] for name, args, kwargs, expected in test_urls: with self.subTest(name=name, args=args, kwargs=kwargs): @@ -705,10 +878,15 @@ class NamespaceTests(SimpleTestCase): include() can set the namespace. """ test_urls = [ - ('new-ns1:urlobject-view', [], {}, '/newapp1/inner/'), - ('new-ns1:urlobject-view', [37, 42], {}, '/newapp1/inner/37/42/'), - ('new-ns1:urlobject-view', [], {'arg1': 42, 'arg2': 37}, '/newapp1/inner/42/37/'), - ('new-ns1:urlobject-special-view', [], {}, '/newapp1/inner/+%5C$*/'), + ("new-ns1:urlobject-view", [], {}, "/newapp1/inner/"), + ("new-ns1:urlobject-view", [37, 42], {}, "/newapp1/inner/37/42/"), + ( + "new-ns1:urlobject-view", + [], + {"arg1": 42, "arg2": 37}, + "/newapp1/inner/42/37/", + ), + ("new-ns1:urlobject-special-view", [], {}, "/newapp1/inner/+%5C$*/"), ] for name, args, kwargs, expected in test_urls: with self.subTest(name=name, args=args, kwargs=kwargs): @@ -720,10 +898,15 @@ class NamespaceTests(SimpleTestCase): 2-tuple. """ test_urls = [ - ('newapp:urlobject-view', [], {}, '/new-default/inner/'), - ('newapp:urlobject-view', [37, 42], {}, '/new-default/inner/37/42/'), - ('newapp:urlobject-view', [], {'arg1': 42, 'arg2': 37}, '/new-default/inner/42/37/'), - ('newapp:urlobject-special-view', [], {}, '/new-default/inner/+%5C$*/'), + ("newapp:urlobject-view", [], {}, "/new-default/inner/"), + ("newapp:urlobject-view", [37, 42], {}, "/new-default/inner/37/42/"), + ( + "newapp:urlobject-view", + [], + {"arg1": 42, "arg2": 37}, + "/new-default/inner/42/37/", + ), + ("newapp:urlobject-special-view", [], {}, "/new-default/inner/+%5C$*/"), ] for name, args, kwargs, expected in test_urls: with self.subTest(name=name, args=args, kwargs=kwargs): @@ -732,13 +915,30 @@ class NamespaceTests(SimpleTestCase): def test_embedded_namespace_object(self): """Namespaces can be installed anywhere in the URL pattern tree.""" test_urls = [ - ('included_namespace_urls:test-ns3:urlobject-view', [], {}, '/included/test3/inner/'), - ('included_namespace_urls:test-ns3:urlobject-view', [37, 42], {}, '/included/test3/inner/37/42/'), ( - 'included_namespace_urls:test-ns3:urlobject-view', [], {'arg1': 42, 'arg2': 37}, - '/included/test3/inner/42/37/', + "included_namespace_urls:test-ns3:urlobject-view", + [], + {}, + "/included/test3/inner/", + ), + ( + "included_namespace_urls:test-ns3:urlobject-view", + [37, 42], + {}, + "/included/test3/inner/37/42/", + ), + ( + "included_namespace_urls:test-ns3:urlobject-view", + [], + {"arg1": 42, "arg2": 37}, + "/included/test3/inner/42/37/", + ), + ( + "included_namespace_urls:test-ns3:urlobject-special-view", + [], + {}, + "/included/test3/inner/+%5C$*/", ), - ('included_namespace_urls:test-ns3:urlobject-special-view', [], {}, '/included/test3/inner/+%5C$*/'), ] for name, args, kwargs, expected in test_urls: with self.subTest(name=name, args=args, kwargs=kwargs): @@ -747,10 +947,15 @@ class NamespaceTests(SimpleTestCase): def test_namespace_pattern(self): """Namespaces can be applied to include()'d urlpatterns.""" test_urls = [ - ('inc-ns1:inc-normal-view', [], {}, '/ns-included1/normal/'), - ('inc-ns1:inc-normal-view', [37, 42], {}, '/ns-included1/normal/37/42/'), - ('inc-ns1:inc-normal-view', [], {'arg1': 42, 'arg2': 37}, '/ns-included1/normal/42/37/'), - ('inc-ns1:inc-special-view', [], {}, '/ns-included1/+%5C$*/'), + ("inc-ns1:inc-normal-view", [], {}, "/ns-included1/normal/"), + ("inc-ns1:inc-normal-view", [37, 42], {}, "/ns-included1/normal/37/42/"), + ( + "inc-ns1:inc-normal-view", + [], + {"arg1": 42, "arg2": 37}, + "/ns-included1/normal/42/37/", + ), + ("inc-ns1:inc-special-view", [], {}, "/ns-included1/+%5C$*/"), ] for name, args, kwargs, expected in test_urls: with self.subTest(name=name, args=args, kwargs=kwargs): @@ -762,10 +967,15 @@ class NamespaceTests(SimpleTestCase): app_name attribute. """ test_urls = [ - ('app-ns1:inc-normal-view', [], {}, '/app-included1/normal/'), - ('app-ns1:inc-normal-view', [37, 42], {}, '/app-included1/normal/37/42/'), - ('app-ns1:inc-normal-view', [], {'arg1': 42, 'arg2': 37}, '/app-included1/normal/42/37/'), - ('app-ns1:inc-special-view', [], {}, '/app-included1/+%5C$*/'), + ("app-ns1:inc-normal-view", [], {}, "/app-included1/normal/"), + ("app-ns1:inc-normal-view", [37, 42], {}, "/app-included1/normal/37/42/"), + ( + "app-ns1:inc-normal-view", + [], + {"arg1": 42, "arg2": 37}, + "/app-included1/normal/42/37/", + ), + ("app-ns1:inc-special-view", [], {}, "/app-included1/+%5C$*/"), ] for name, args, kwargs, expected in test_urls: with self.subTest(name=name, args=args, kwargs=kwargs): @@ -777,12 +987,17 @@ class NamespaceTests(SimpleTestCase): of it. """ test_urls = [ - ('inc-outer:inc-normal-view', [], {'outer': 42}, '/ns-outer/42/normal/'), - ('inc-outer:inc-normal-view', [42], {}, '/ns-outer/42/normal/'), - ('inc-outer:inc-normal-view', [], {'arg1': 37, 'arg2': 4, 'outer': 42}, '/ns-outer/42/normal/37/4/'), - ('inc-outer:inc-normal-view', [42, 37, 4], {}, '/ns-outer/42/normal/37/4/'), - ('inc-outer:inc-special-view', [], {'outer': 42}, '/ns-outer/42/+%5C$*/'), - ('inc-outer:inc-special-view', [42], {}, '/ns-outer/42/+%5C$*/'), + ("inc-outer:inc-normal-view", [], {"outer": 42}, "/ns-outer/42/normal/"), + ("inc-outer:inc-normal-view", [42], {}, "/ns-outer/42/normal/"), + ( + "inc-outer:inc-normal-view", + [], + {"arg1": 37, "arg2": 4, "outer": 42}, + "/ns-outer/42/normal/37/4/", + ), + ("inc-outer:inc-normal-view", [42, 37, 4], {}, "/ns-outer/42/normal/37/4/"), + ("inc-outer:inc-special-view", [], {"outer": 42}, "/ns-outer/42/+%5C$*/"), + ("inc-outer:inc-special-view", [42], {}, "/ns-outer/42/+%5C$*/"), ] for name, args, kwargs, expected in test_urls: with self.subTest(name=name, args=args, kwargs=kwargs): @@ -791,13 +1006,25 @@ class NamespaceTests(SimpleTestCase): def test_multiple_namespace_pattern(self): """Namespaces can be embedded.""" test_urls = [ - ('inc-ns1:test-ns3:urlobject-view', [], {}, '/ns-included1/test3/inner/'), - ('inc-ns1:test-ns3:urlobject-view', [37, 42], {}, '/ns-included1/test3/inner/37/42/'), + ("inc-ns1:test-ns3:urlobject-view", [], {}, "/ns-included1/test3/inner/"), + ( + "inc-ns1:test-ns3:urlobject-view", + [37, 42], + {}, + "/ns-included1/test3/inner/37/42/", + ), ( - 'inc-ns1:test-ns3:urlobject-view', [], {'arg1': 42, 'arg2': 37}, - '/ns-included1/test3/inner/42/37/', + "inc-ns1:test-ns3:urlobject-view", + [], + {"arg1": 42, "arg2": 37}, + "/ns-included1/test3/inner/42/37/", + ), + ( + "inc-ns1:test-ns3:urlobject-special-view", + [], + {}, + "/ns-included1/test3/inner/+%5C$*/", ), - ('inc-ns1:test-ns3:urlobject-special-view', [], {}, '/ns-included1/test3/inner/+%5C$*/'), ] for name, args, kwargs, expected in test_urls: with self.subTest(name=name, args=args, kwargs=kwargs): @@ -807,20 +1034,28 @@ class NamespaceTests(SimpleTestCase): """Namespaces can be nested.""" test_urls = [ ( - 'inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-view', [], {}, - '/ns-included1/ns-included4/ns-included1/test3/inner/', + "inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-view", + [], + {}, + "/ns-included1/ns-included4/ns-included1/test3/inner/", ), ( - 'inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-view', [37, 42], {}, - '/ns-included1/ns-included4/ns-included1/test3/inner/37/42/', + "inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-view", + [37, 42], + {}, + "/ns-included1/ns-included4/ns-included1/test3/inner/37/42/", ), ( - 'inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-view', [], {'arg1': 42, 'arg2': 37}, - '/ns-included1/ns-included4/ns-included1/test3/inner/42/37/', + "inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-view", + [], + {"arg1": 42, "arg2": 37}, + "/ns-included1/ns-included4/ns-included1/test3/inner/42/37/", ), ( - 'inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-special-view', [], {}, - '/ns-included1/ns-included4/ns-included1/test3/inner/+%5C$*/', + "inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-special-view", + [], + {}, + "/ns-included1/ns-included4/ns-included1/test3/inner/+%5C$*/", ), ] for name, args, kwargs, expected in test_urls: @@ -830,10 +1065,15 @@ class NamespaceTests(SimpleTestCase): def test_app_lookup_object(self): """A default application namespace can be used for lookup.""" test_urls = [ - ('testapp:urlobject-view', [], {}, '/default/inner/'), - ('testapp:urlobject-view', [37, 42], {}, '/default/inner/37/42/'), - ('testapp:urlobject-view', [], {'arg1': 42, 'arg2': 37}, '/default/inner/42/37/'), - ('testapp:urlobject-special-view', [], {}, '/default/inner/+%5C$*/'), + ("testapp:urlobject-view", [], {}, "/default/inner/"), + ("testapp:urlobject-view", [37, 42], {}, "/default/inner/37/42/"), + ( + "testapp:urlobject-view", + [], + {"arg1": 42, "arg2": 37}, + "/default/inner/42/37/", + ), + ("testapp:urlobject-special-view", [], {}, "/default/inner/+%5C$*/"), ] for name, args, kwargs, expected in test_urls: with self.subTest(name=name, args=args, kwargs=kwargs): @@ -842,14 +1082,37 @@ class NamespaceTests(SimpleTestCase): def test_app_lookup_object_with_default(self): """A default application namespace is sensitive to the current app.""" test_urls = [ - ('testapp:urlobject-view', [], {}, 'test-ns3', '/default/inner/'), - ('testapp:urlobject-view', [37, 42], {}, 'test-ns3', '/default/inner/37/42/'), - ('testapp:urlobject-view', [], {'arg1': 42, 'arg2': 37}, 'test-ns3', '/default/inner/42/37/'), - ('testapp:urlobject-special-view', [], {}, 'test-ns3', '/default/inner/+%5C$*/'), + ("testapp:urlobject-view", [], {}, "test-ns3", "/default/inner/"), + ( + "testapp:urlobject-view", + [37, 42], + {}, + "test-ns3", + "/default/inner/37/42/", + ), + ( + "testapp:urlobject-view", + [], + {"arg1": 42, "arg2": 37}, + "test-ns3", + "/default/inner/42/37/", + ), + ( + "testapp:urlobject-special-view", + [], + {}, + "test-ns3", + "/default/inner/+%5C$*/", + ), ] for name, args, kwargs, current_app, expected in test_urls: - with self.subTest(name=name, args=args, kwargs=kwargs, current_app=current_app): - self.assertEqual(reverse(name, args=args, kwargs=kwargs, current_app=current_app), expected) + with self.subTest( + name=name, args=args, kwargs=kwargs, current_app=current_app + ): + self.assertEqual( + reverse(name, args=args, kwargs=kwargs, current_app=current_app), + expected, + ) def test_app_lookup_object_without_default(self): """ @@ -857,28 +1120,74 @@ class NamespaceTests(SimpleTestCase): app. """ test_urls = [ - ('nodefault:urlobject-view', [], {}, None, '/other2/inner/'), - ('nodefault:urlobject-view', [37, 42], {}, None, '/other2/inner/37/42/'), - ('nodefault:urlobject-view', [], {'arg1': 42, 'arg2': 37}, None, '/other2/inner/42/37/'), - ('nodefault:urlobject-special-view', [], {}, None, '/other2/inner/+%5C$*/'), - ('nodefault:urlobject-view', [], {}, 'other-ns1', '/other1/inner/'), - ('nodefault:urlobject-view', [37, 42], {}, 'other-ns1', '/other1/inner/37/42/'), - ('nodefault:urlobject-view', [], {'arg1': 42, 'arg2': 37}, 'other-ns1', '/other1/inner/42/37/'), - ('nodefault:urlobject-special-view', [], {}, 'other-ns1', '/other1/inner/+%5C$*/'), + ("nodefault:urlobject-view", [], {}, None, "/other2/inner/"), + ("nodefault:urlobject-view", [37, 42], {}, None, "/other2/inner/37/42/"), + ( + "nodefault:urlobject-view", + [], + {"arg1": 42, "arg2": 37}, + None, + "/other2/inner/42/37/", + ), + ("nodefault:urlobject-special-view", [], {}, None, "/other2/inner/+%5C$*/"), + ("nodefault:urlobject-view", [], {}, "other-ns1", "/other1/inner/"), + ( + "nodefault:urlobject-view", + [37, 42], + {}, + "other-ns1", + "/other1/inner/37/42/", + ), + ( + "nodefault:urlobject-view", + [], + {"arg1": 42, "arg2": 37}, + "other-ns1", + "/other1/inner/42/37/", + ), + ( + "nodefault:urlobject-special-view", + [], + {}, + "other-ns1", + "/other1/inner/+%5C$*/", + ), ] for name, args, kwargs, current_app, expected in test_urls: - with self.subTest(name=name, args=args, kwargs=kwargs, current_app=current_app): - self.assertEqual(reverse(name, args=args, kwargs=kwargs, current_app=current_app), expected) + with self.subTest( + name=name, args=args, kwargs=kwargs, current_app=current_app + ): + self.assertEqual( + reverse(name, args=args, kwargs=kwargs, current_app=current_app), + expected, + ) def test_special_chars_namespace(self): test_urls = [ - ('special:included_namespace_urls:inc-normal-view', [], {}, '/+%5C$*/included/normal/'), - ('special:included_namespace_urls:inc-normal-view', [37, 42], {}, '/+%5C$*/included/normal/37/42/'), ( - 'special:included_namespace_urls:inc-normal-view', [], {'arg1': 42, 'arg2': 37}, - '/+%5C$*/included/normal/42/37/', + "special:included_namespace_urls:inc-normal-view", + [], + {}, + "/+%5C$*/included/normal/", + ), + ( + "special:included_namespace_urls:inc-normal-view", + [37, 42], + {}, + "/+%5C$*/included/normal/37/42/", + ), + ( + "special:included_namespace_urls:inc-normal-view", + [], + {"arg1": 42, "arg2": 37}, + "/+%5C$*/included/normal/42/37/", + ), + ( + "special:included_namespace_urls:inc-special-view", + [], + {}, + "/+%5C$*/included/+%5C$*/", ), - ('special:included_namespace_urls:inc-special-view', [], {}, '/+%5C$*/included/+%5C$*/'), ] for name, args, kwargs, expected in test_urls: with self.subTest(name=name, args=args, kwargs=kwargs): @@ -887,10 +1196,15 @@ class NamespaceTests(SimpleTestCase): def test_namespaces_with_variables(self): """Namespace prefixes can capture variables.""" test_urls = [ - ('inc-ns5:inner-nothing', [], {'outer': '70'}, '/inc70/'), - ('inc-ns5:inner-extra', [], {'extra': 'foobar', 'outer': '78'}, '/inc78/extra/foobar/'), - ('inc-ns5:inner-nothing', ['70'], {}, '/inc70/'), - ('inc-ns5:inner-extra', ['78', 'foobar'], {}, '/inc78/extra/foobar/'), + ("inc-ns5:inner-nothing", [], {"outer": "70"}, "/inc70/"), + ( + "inc-ns5:inner-extra", + [], + {"extra": "foobar", "outer": "78"}, + "/inc78/extra/foobar/", + ), + ("inc-ns5:inner-nothing", ["70"], {}, "/inc70/"), + ("inc-ns5:inner-extra", ["78", "foobar"], {}, "/inc78/extra/foobar/"), ] for name, args, kwargs, expected in test_urls: with self.subTest(name=name, args=args, kwargs=kwargs): @@ -901,75 +1215,144 @@ class NamespaceTests(SimpleTestCase): A nested current_app should be split in individual namespaces (#24904). """ test_urls = [ - ('inc-ns1:testapp:urlobject-view', [], {}, None, '/ns-included1/test4/inner/'), - ('inc-ns1:testapp:urlobject-view', [37, 42], {}, None, '/ns-included1/test4/inner/37/42/'), - ('inc-ns1:testapp:urlobject-view', [], {'arg1': 42, 'arg2': 37}, None, '/ns-included1/test4/inner/42/37/'), - ('inc-ns1:testapp:urlobject-special-view', [], {}, None, '/ns-included1/test4/inner/+%5C$*/'), - ('inc-ns1:testapp:urlobject-view', [], {}, 'inc-ns1:test-ns3', '/ns-included1/test3/inner/'), - ('inc-ns1:testapp:urlobject-view', [37, 42], {}, 'inc-ns1:test-ns3', '/ns-included1/test3/inner/37/42/'), ( - 'inc-ns1:testapp:urlobject-view', [], {'arg1': 42, 'arg2': 37}, 'inc-ns1:test-ns3', - '/ns-included1/test3/inner/42/37/', + "inc-ns1:testapp:urlobject-view", + [], + {}, + None, + "/ns-included1/test4/inner/", + ), + ( + "inc-ns1:testapp:urlobject-view", + [37, 42], + {}, + None, + "/ns-included1/test4/inner/37/42/", + ), + ( + "inc-ns1:testapp:urlobject-view", + [], + {"arg1": 42, "arg2": 37}, + None, + "/ns-included1/test4/inner/42/37/", + ), + ( + "inc-ns1:testapp:urlobject-special-view", + [], + {}, + None, + "/ns-included1/test4/inner/+%5C$*/", + ), + ( + "inc-ns1:testapp:urlobject-view", + [], + {}, + "inc-ns1:test-ns3", + "/ns-included1/test3/inner/", + ), + ( + "inc-ns1:testapp:urlobject-view", + [37, 42], + {}, + "inc-ns1:test-ns3", + "/ns-included1/test3/inner/37/42/", + ), + ( + "inc-ns1:testapp:urlobject-view", + [], + {"arg1": 42, "arg2": 37}, + "inc-ns1:test-ns3", + "/ns-included1/test3/inner/42/37/", ), ( - 'inc-ns1:testapp:urlobject-special-view', [], {}, 'inc-ns1:test-ns3', - '/ns-included1/test3/inner/+%5C$*/', + "inc-ns1:testapp:urlobject-special-view", + [], + {}, + "inc-ns1:test-ns3", + "/ns-included1/test3/inner/+%5C$*/", ), ] for name, args, kwargs, current_app, expected in test_urls: - with self.subTest(name=name, args=args, kwargs=kwargs, current_app=current_app): - self.assertEqual(reverse(name, args=args, kwargs=kwargs, current_app=current_app), expected) + with self.subTest( + name=name, args=args, kwargs=kwargs, current_app=current_app + ): + self.assertEqual( + reverse(name, args=args, kwargs=kwargs, current_app=current_app), + expected, + ) def test_current_app_no_partial_match(self): """current_app shouldn't be used unless it matches the whole path.""" test_urls = [ - ('inc-ns1:testapp:urlobject-view', [], {}, 'nonexistent:test-ns3', '/ns-included1/test4/inner/'), ( - 'inc-ns1:testapp:urlobject-view', [37, 42], {}, 'nonexistent:test-ns3', - '/ns-included1/test4/inner/37/42/', + "inc-ns1:testapp:urlobject-view", + [], + {}, + "nonexistent:test-ns3", + "/ns-included1/test4/inner/", + ), + ( + "inc-ns1:testapp:urlobject-view", + [37, 42], + {}, + "nonexistent:test-ns3", + "/ns-included1/test4/inner/37/42/", ), ( - 'inc-ns1:testapp:urlobject-view', [], {'arg1': 42, 'arg2': 37}, 'nonexistent:test-ns3', - '/ns-included1/test4/inner/42/37/', + "inc-ns1:testapp:urlobject-view", + [], + {"arg1": 42, "arg2": 37}, + "nonexistent:test-ns3", + "/ns-included1/test4/inner/42/37/", ), ( - 'inc-ns1:testapp:urlobject-special-view', [], {}, 'nonexistent:test-ns3', - '/ns-included1/test4/inner/+%5C$*/', + "inc-ns1:testapp:urlobject-special-view", + [], + {}, + "nonexistent:test-ns3", + "/ns-included1/test4/inner/+%5C$*/", ), ] for name, args, kwargs, current_app, expected in test_urls: - with self.subTest(name=name, args=args, kwargs=kwargs, current_app=current_app): - self.assertEqual(reverse(name, args=args, kwargs=kwargs, current_app=current_app), expected) + with self.subTest( + name=name, args=args, kwargs=kwargs, current_app=current_app + ): + self.assertEqual( + reverse(name, args=args, kwargs=kwargs, current_app=current_app), + expected, + ) @override_settings(ROOT_URLCONF=urlconf_outer.__name__) class RequestURLconfTests(SimpleTestCase): def test_urlconf(self): - response = self.client.get('/test/me/') + response = self.client.get("/test/me/") self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, b'outer:/test/me/,inner:/inner_urlconf/second_test/') - response = self.client.get('/inner_urlconf/second_test/') + self.assertEqual( + response.content, b"outer:/test/me/,inner:/inner_urlconf/second_test/" + ) + response = self.client.get("/inner_urlconf/second_test/") self.assertEqual(response.status_code, 200) - response = self.client.get('/second_test/') + response = self.client.get("/second_test/") self.assertEqual(response.status_code, 404) @override_settings( MIDDLEWARE=[ - '%s.ChangeURLconfMiddleware' % middleware.__name__, + "%s.ChangeURLconfMiddleware" % middleware.__name__, ] ) def test_urlconf_overridden(self): - response = self.client.get('/test/me/') + response = self.client.get("/test/me/") self.assertEqual(response.status_code, 404) - response = self.client.get('/inner_urlconf/second_test/') + response = self.client.get("/inner_urlconf/second_test/") self.assertEqual(response.status_code, 404) - response = self.client.get('/second_test/') + response = self.client.get("/second_test/") self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, b'outer:,inner:/second_test/') + self.assertEqual(response.content, b"outer:,inner:/second_test/") @override_settings( MIDDLEWARE=[ - '%s.NullChangeURLconfMiddleware' % middleware.__name__, + "%s.NullChangeURLconfMiddleware" % middleware.__name__, ] ) def test_urlconf_overridden_with_null(self): @@ -977,18 +1360,20 @@ class RequestURLconfTests(SimpleTestCase): Overriding request.urlconf with None will fall back to the default URLconf. """ - response = self.client.get('/test/me/') + response = self.client.get("/test/me/") self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, b'outer:/test/me/,inner:/inner_urlconf/second_test/') - response = self.client.get('/inner_urlconf/second_test/') + self.assertEqual( + response.content, b"outer:/test/me/,inner:/inner_urlconf/second_test/" + ) + response = self.client.get("/inner_urlconf/second_test/") self.assertEqual(response.status_code, 200) - response = self.client.get('/second_test/') + response = self.client.get("/second_test/") self.assertEqual(response.status_code, 404) @override_settings( MIDDLEWARE=[ - '%s.ChangeURLconfMiddleware' % middleware.__name__, - '%s.ReverseInnerInResponseMiddleware' % middleware.__name__, + "%s.ChangeURLconfMiddleware" % middleware.__name__, + "%s.ReverseInnerInResponseMiddleware" % middleware.__name__, ] ) def test_reverse_inner_in_response_middleware(self): @@ -996,14 +1381,14 @@ class RequestURLconfTests(SimpleTestCase): Test reversing an URL from the *overridden* URLconf from inside a response middleware. """ - response = self.client.get('/second_test/') + response = self.client.get("/second_test/") self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, b'/second_test/') + self.assertEqual(response.content, b"/second_test/") @override_settings( MIDDLEWARE=[ - '%s.ChangeURLconfMiddleware' % middleware.__name__, - '%s.ReverseOuterInResponseMiddleware' % middleware.__name__, + "%s.ChangeURLconfMiddleware" % middleware.__name__, + "%s.ReverseOuterInResponseMiddleware" % middleware.__name__, ] ) def test_reverse_outer_in_response_middleware(self): @@ -1016,12 +1401,12 @@ class RequestURLconfTests(SimpleTestCase): "function or pattern name." ) with self.assertRaisesMessage(NoReverseMatch, msg): - self.client.get('/second_test/') + self.client.get("/second_test/") @override_settings( MIDDLEWARE=[ - '%s.ChangeURLconfMiddleware' % middleware.__name__, - '%s.ReverseInnerInStreaming' % middleware.__name__, + "%s.ChangeURLconfMiddleware" % middleware.__name__, + "%s.ReverseInnerInStreaming" % middleware.__name__, ] ) def test_reverse_inner_in_streaming(self): @@ -1029,14 +1414,14 @@ class RequestURLconfTests(SimpleTestCase): Test reversing an URL from the *overridden* URLconf from inside a streaming response. """ - response = self.client.get('/second_test/') + response = self.client.get("/second_test/") self.assertEqual(response.status_code, 200) - self.assertEqual(b''.join(response), b'/second_test/') + self.assertEqual(b"".join(response), b"/second_test/") @override_settings( MIDDLEWARE=[ - '%s.ChangeURLconfMiddleware' % middleware.__name__, - '%s.ReverseOuterInStreaming' % middleware.__name__, + "%s.ChangeURLconfMiddleware" % middleware.__name__, + "%s.ReverseOuterInStreaming" % middleware.__name__, ] ) def test_reverse_outer_in_streaming(self): @@ -1046,14 +1431,16 @@ class RequestURLconfTests(SimpleTestCase): """ message = "Reverse for 'outer' not found." with self.assertRaisesMessage(NoReverseMatch, message): - self.client.get('/second_test/') - b''.join(self.client.get('/second_test/')) + self.client.get("/second_test/") + b"".join(self.client.get("/second_test/")) def test_urlconf_is_reset_after_request(self): """The URLconf is reset after each request.""" self.assertIsNone(get_urlconf()) - with override_settings(MIDDLEWARE=['%s.ChangeURLconfMiddleware' % middleware.__name__]): - self.client.get(reverse('inner')) + with override_settings( + MIDDLEWARE=["%s.ChangeURLconfMiddleware" % middleware.__name__] + ): + self.client.get(reverse("inner")) self.assertIsNone(get_urlconf()) @@ -1061,10 +1448,10 @@ class ErrorHandlerResolutionTests(SimpleTestCase): """Tests for handler400, handler404 and handler500""" def setUp(self): - urlconf = 'urlpatterns_reverse.urls_error_handlers' - urlconf_callables = 'urlpatterns_reverse.urls_error_handlers_callables' - self.resolver = URLResolver(RegexPattern(r'^$'), urlconf) - self.callable_resolver = URLResolver(RegexPattern(r'^$'), urlconf_callables) + urlconf = "urlpatterns_reverse.urls_error_handlers" + urlconf_callables = "urlpatterns_reverse.urls_error_handlers_callables" + self.resolver = URLResolver(RegexPattern(r"^$"), urlconf) + self.callable_resolver = URLResolver(RegexPattern(r"^$"), urlconf_callables) def test_named_handlers(self): for code in [400, 404, 500]: @@ -1074,20 +1461,21 @@ class ErrorHandlerResolutionTests(SimpleTestCase): def test_callable_handlers(self): for code in [400, 404, 500]: with self.subTest(code=code): - self.assertEqual(self.callable_resolver.resolve_error_handler(code), empty_view) + self.assertEqual( + self.callable_resolver.resolve_error_handler(code), empty_view + ) -@override_settings(ROOT_URLCONF='urlpatterns_reverse.urls_without_handlers') +@override_settings(ROOT_URLCONF="urlpatterns_reverse.urls_without_handlers") class DefaultErrorHandlerTests(SimpleTestCase): - def test_default_handler(self): "If the urls.py doesn't specify handlers, the defaults are used" - response = self.client.get('/test/') + response = self.client.get("/test/") self.assertEqual(response.status_code, 404) msg = "I don't think I'm getting good value for this view" with self.assertRaisesMessage(ValueError, msg): - self.client.get('/bad_view/') + self.client.get("/bad_view/") @override_settings(ROOT_URLCONF=None) @@ -1102,14 +1490,22 @@ class NoRootUrlConfTests(SimpleTestCase): "import." ) with self.assertRaisesMessage(ImproperlyConfigured, msg): - self.client.get('/test/me/') + self.client.get("/test/me/") -@override_settings(ROOT_URLCONF='urlpatterns_reverse.namespace_urls') +@override_settings(ROOT_URLCONF="urlpatterns_reverse.namespace_urls") class ResolverMatchTests(SimpleTestCase): - def test_urlpattern_resolve(self): - for path_, url_name, app_name, namespace, view_name, func, args, kwargs in resolve_test_data: + for ( + path_, + url_name, + app_name, + namespace, + view_name, + func, + args, + kwargs, + ) in resolve_test_data: with self.subTest(path=path_): # Legacy support for extracting "function, args, kwargs". match_func, match_args, match_kwargs = resolve(path_) @@ -1132,9 +1528,9 @@ class ResolverMatchTests(SimpleTestCase): self.assertEqual(match[2], kwargs) def test_resolver_match_on_request(self): - response = self.client.get('/resolver_match/') + response = self.client.get("/resolver_match/") resolver_match = response.resolver_match - self.assertEqual(resolver_match.url_name, 'test-resolver-match') + self.assertEqual(resolver_match.url_name, "test-resolver-match") def test_resolver_match_on_request_before_resolution(self): request = HttpRequest() @@ -1142,27 +1538,27 @@ class ResolverMatchTests(SimpleTestCase): def test_repr(self): self.assertEqual( - repr(resolve('/no_kwargs/42/37/')), + repr(resolve("/no_kwargs/42/37/")), "ResolverMatch(func=urlpatterns_reverse.views.empty_view, " "args=('42', '37'), kwargs={}, url_name='no-kwargs', app_names=[], " "namespaces=[], route='^no_kwargs/([0-9]+)/([0-9]+)/$')", ) - @override_settings(ROOT_URLCONF='urlpatterns_reverse.reverse_lazy_urls') + @override_settings(ROOT_URLCONF="urlpatterns_reverse.reverse_lazy_urls") def test_classbased_repr(self): self.assertEqual( - repr(resolve('/redirect/')), + repr(resolve("/redirect/")), "ResolverMatch(func=urlpatterns_reverse.views.LazyRedirectView, " "args=(), kwargs={}, url_name=None, app_names=[], " "namespaces=[], route='redirect/')", ) - @override_settings(ROOT_URLCONF='urlpatterns_reverse.urls') + @override_settings(ROOT_URLCONF="urlpatterns_reverse.urls") def test_repr_functools_partial(self): tests = [ - ('partial', 'template.html'), - ('partial_nested', 'nested_partial.html'), - ('partial_wrapped', 'template.html'), + ("partial", "template.html"), + ("partial_nested", "nested_partial.html"), + ("partial_wrapped", "template.html"), ] for name, template_name in tests: with self.subTest(name=name): @@ -1171,26 +1567,25 @@ class ResolverMatchTests(SimpleTestCase): f"template_name='{template_name}')" ) self.assertEqual( - repr(resolve(f'/{name}/')), + repr(resolve(f"/{name}/")), f"ResolverMatch(func={func}, args=(), kwargs={{}}, " f"url_name='{name}', app_names=[], namespaces=[], " f"route='{name}/')", ) - @override_settings(ROOT_URLCONF='urlpatterns.path_urls') + @override_settings(ROOT_URLCONF="urlpatterns.path_urls") def test_pickling(self): - msg = 'Cannot pickle ResolverMatch.' + msg = "Cannot pickle ResolverMatch." with self.assertRaisesMessage(pickle.PicklingError, msg): - pickle.dumps(resolve('/users/')) + pickle.dumps(resolve("/users/")) -@override_settings(ROOT_URLCONF='urlpatterns_reverse.erroneous_urls') +@override_settings(ROOT_URLCONF="urlpatterns_reverse.erroneous_urls") class ErroneousViewTests(SimpleTestCase): - def test_noncallable_view(self): # View is not a callable (explicit import; arbitrary Python object) - with self.assertRaisesMessage(TypeError, 'view must be a callable'): - path('uncallable-object/', views.uncallable) + with self.assertRaisesMessage(TypeError, "view must be a callable"): + path("uncallable-object/", views.uncallable) def test_invalid_regex(self): # Regex contains an error (refs #6170) @@ -1201,18 +1596,20 @@ class ErroneousViewTests(SimpleTestCase): class ViewLoadingTests(SimpleTestCase): def test_view_loading(self): - self.assertEqual(get_callable('urlpatterns_reverse.views.empty_view'), empty_view) + self.assertEqual( + get_callable("urlpatterns_reverse.views.empty_view"), empty_view + ) self.assertEqual(get_callable(empty_view), empty_view) def test_view_does_not_exist(self): msg = "View does not exist in module urlpatterns_reverse.views." with self.assertRaisesMessage(ViewDoesNotExist, msg): - get_callable('urlpatterns_reverse.views.i_should_not_exist') + get_callable("urlpatterns_reverse.views.i_should_not_exist") def test_attributeerror_not_hidden(self): - msg = 'I am here to confuse django.urls.get_callable' + msg = "I am here to confuse django.urls.get_callable" with self.assertRaisesMessage(AttributeError, msg): - get_callable('urlpatterns_reverse.views_broken.i_am_broken') + get_callable("urlpatterns_reverse.views_broken.i_am_broken") def test_non_string_value(self): msg = "'1' is not a callable or a dot-notation path" @@ -1222,16 +1619,16 @@ class ViewLoadingTests(SimpleTestCase): def test_string_without_dot(self): msg = "Could not import 'test'. The path must be fully qualified." with self.assertRaisesMessage(ImportError, msg): - get_callable('test') + get_callable("test") def test_module_does_not_exist(self): with self.assertRaisesMessage(ImportError, "No module named 'foo'"): - get_callable('foo.bar') + get_callable("foo.bar") def test_parent_module_does_not_exist(self): - msg = 'Parent module urlpatterns_reverse.foo does not exist.' + msg = "Parent module urlpatterns_reverse.foo does not exist." with self.assertRaisesMessage(ViewDoesNotExist, msg): - get_callable('urlpatterns_reverse.foo.bar') + get_callable("urlpatterns_reverse.foo.bar") def test_not_callable(self): msg = ( @@ -1239,87 +1636,87 @@ class ViewLoadingTests(SimpleTestCase): "View is not callable." ) with self.assertRaisesMessage(ViewDoesNotExist, msg): - get_callable('urlpatterns_reverse.tests.resolve_test_data') + get_callable("urlpatterns_reverse.tests.resolve_test_data") class IncludeTests(SimpleTestCase): url_patterns = [ - path('inner/', views.empty_view, name='urlobject-view'), - re_path(r'^inner/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.empty_view, name='urlobject-view'), - re_path(r'^inner/\+\\\$\*/$', views.empty_view, name='urlobject-special-view'), + path("inner/", views.empty_view, name="urlobject-view"), + re_path( + r"^inner/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$", + views.empty_view, + name="urlobject-view", + ), + re_path(r"^inner/\+\\\$\*/$", views.empty_view, name="urlobject-special-view"), ] - app_urls = URLObject('inc-app') + app_urls = URLObject("inc-app") def test_include_urls(self): self.assertEqual(include(self.url_patterns), (self.url_patterns, None, None)) def test_include_namespace(self): msg = ( - 'Specifying a namespace in include() without providing an ' - 'app_name is not supported.' + "Specifying a namespace in include() without providing an " + "app_name is not supported." ) with self.assertRaisesMessage(ImproperlyConfigured, msg): - include(self.url_patterns, 'namespace') + include(self.url_patterns, "namespace") def test_include_4_tuple(self): - msg = 'Passing a 4-tuple to include() is not supported.' + msg = "Passing a 4-tuple to include() is not supported." with self.assertRaisesMessage(ImproperlyConfigured, msg): - include((self.url_patterns, 'app_name', 'namespace', 'blah')) + include((self.url_patterns, "app_name", "namespace", "blah")) def test_include_3_tuple(self): - msg = 'Passing a 3-tuple to include() is not supported.' + msg = "Passing a 3-tuple to include() is not supported." with self.assertRaisesMessage(ImproperlyConfigured, msg): - include((self.url_patterns, 'app_name', 'namespace')) + include((self.url_patterns, "app_name", "namespace")) def test_include_3_tuple_namespace(self): - msg = 'Cannot override the namespace for a dynamic module that provides a namespace.' + msg = "Cannot override the namespace for a dynamic module that provides a namespace." with self.assertRaisesMessage(ImproperlyConfigured, msg): - include((self.url_patterns, 'app_name', 'namespace'), 'namespace') + include((self.url_patterns, "app_name", "namespace"), "namespace") def test_include_2_tuple(self): self.assertEqual( - include((self.url_patterns, 'app_name')), - (self.url_patterns, 'app_name', 'app_name') + include((self.url_patterns, "app_name")), + (self.url_patterns, "app_name", "app_name"), ) def test_include_2_tuple_namespace(self): self.assertEqual( - include((self.url_patterns, 'app_name'), namespace='namespace'), - (self.url_patterns, 'app_name', 'namespace') + include((self.url_patterns, "app_name"), namespace="namespace"), + (self.url_patterns, "app_name", "namespace"), ) def test_include_app_name(self): - self.assertEqual( - include(self.app_urls), - (self.app_urls, 'inc-app', 'inc-app') - ) + self.assertEqual(include(self.app_urls), (self.app_urls, "inc-app", "inc-app")) def test_include_app_name_namespace(self): self.assertEqual( - include(self.app_urls, 'namespace'), - (self.app_urls, 'inc-app', 'namespace') + include(self.app_urls, "namespace"), (self.app_urls, "inc-app", "namespace") ) -@override_settings(ROOT_URLCONF='urlpatterns_reverse.urls') +@override_settings(ROOT_URLCONF="urlpatterns_reverse.urls") class LookaheadTests(SimpleTestCase): def test_valid_resolve(self): test_urls = [ - '/lookahead-/a-city/', - '/lookbehind-/a-city/', - '/lookahead+/a-city/', - '/lookbehind+/a-city/', + "/lookahead-/a-city/", + "/lookbehind-/a-city/", + "/lookahead+/a-city/", + "/lookbehind+/a-city/", ] for test_url in test_urls: with self.subTest(url=test_url): - self.assertEqual(resolve(test_url).kwargs, {'city': 'a-city'}) + self.assertEqual(resolve(test_url).kwargs, {"city": "a-city"}) def test_invalid_resolve(self): test_urls = [ - '/lookahead-/not-a-city/', - '/lookbehind-/not-a-city/', - '/lookahead+/other-city/', - '/lookbehind+/other-city/', + "/lookahead-/not-a-city/", + "/lookbehind-/not-a-city/", + "/lookahead+/other-city/", + "/lookbehind+/other-city/", ] for test_url in test_urls: with self.subTest(url=test_url): @@ -1328,10 +1725,10 @@ class LookaheadTests(SimpleTestCase): def test_valid_reverse(self): test_urls = [ - ('lookahead-positive', {'city': 'a-city'}, '/lookahead+/a-city/'), - ('lookahead-negative', {'city': 'a-city'}, '/lookahead-/a-city/'), - ('lookbehind-positive', {'city': 'a-city'}, '/lookbehind+/a-city/'), - ('lookbehind-negative', {'city': 'a-city'}, '/lookbehind-/a-city/'), + ("lookahead-positive", {"city": "a-city"}, "/lookahead+/a-city/"), + ("lookahead-negative", {"city": "a-city"}, "/lookahead-/a-city/"), + ("lookbehind-positive", {"city": "a-city"}, "/lookbehind+/a-city/"), + ("lookbehind-negative", {"city": "a-city"}, "/lookbehind-/a-city/"), ] for name, kwargs, expected in test_urls: with self.subTest(name=name, kwargs=kwargs): @@ -1339,10 +1736,10 @@ class LookaheadTests(SimpleTestCase): def test_invalid_reverse(self): test_urls = [ - ('lookahead-positive', {'city': 'other-city'}), - ('lookahead-negative', {'city': 'not-a-city'}), - ('lookbehind-positive', {'city': 'other-city'}), - ('lookbehind-negative', {'city': 'not-a-city'}), + ("lookahead-positive", {"city": "other-city"}), + ("lookahead-negative", {"city": "not-a-city"}), + ("lookbehind-positive", {"city": "other-city"}), + ("lookbehind-negative", {"city": "not-a-city"}), ] for name, kwargs in test_urls: with self.subTest(name=name, kwargs=kwargs): diff --git a/tests/urlpatterns_reverse/urlconf_inner.py b/tests/urlpatterns_reverse/urlconf_inner.py index 6ea4e90f20..5cd104c372 100644 --- a/tests/urlpatterns_reverse/urlconf_inner.py +++ b/tests/urlpatterns_reverse/urlconf_inner.py @@ -4,11 +4,13 @@ from django.urls import path def inner_view(request): - content = Template('{% url "outer" as outer_url %}outer:{{ outer_url }},' - '{% url "inner" as inner_url %}inner:{{ inner_url }}').render(Context()) + content = Template( + '{% url "outer" as outer_url %}outer:{{ outer_url }},' + '{% url "inner" as inner_url %}inner:{{ inner_url }}' + ).render(Context()) return HttpResponse(content) urlpatterns = [ - path('second_test/', inner_view, name='inner'), + path("second_test/", inner_view, name="inner"), ] diff --git a/tests/urlpatterns_reverse/urlconf_outer.py b/tests/urlpatterns_reverse/urlconf_outer.py index 100b1f52b1..a15932bccf 100644 --- a/tests/urlpatterns_reverse/urlconf_outer.py +++ b/tests/urlpatterns_reverse/urlconf_outer.py @@ -3,6 +3,6 @@ from django.urls import include, path from . import urlconf_inner urlpatterns = [ - path('test/me/', urlconf_inner.inner_view, name='outer'), - path('inner_urlconf/', include(urlconf_inner.__name__)) + path("test/me/", urlconf_inner.inner_view, name="outer"), + path("inner_urlconf/", include(urlconf_inner.__name__)), ] diff --git a/tests/urlpatterns_reverse/urls.py b/tests/urlpatterns_reverse/urls.py index f3c27b8e13..ba3f51b563 100644 --- a/tests/urlpatterns_reverse/urls.py +++ b/tests/urlpatterns_reverse/urls.py @@ -1,79 +1,132 @@ from django.urls import include, path, re_path from .views import ( - absolute_kwargs_view, defaults_view, empty_view, empty_view_nested_partial, - empty_view_partial, empty_view_wrapped, nested_view, + absolute_kwargs_view, + defaults_view, + empty_view, + empty_view_nested_partial, + empty_view_partial, + empty_view_wrapped, + nested_view, ) other_patterns = [ - path('non_path_include/', empty_view, name='non_path_include'), - path('nested_path/', nested_view), + path("non_path_include/", empty_view, name="non_path_include"), + path("nested_path/", nested_view), ] urlpatterns = [ - re_path(r'^places/([0-9]+)/$', empty_view, name='places'), - re_path(r'^places?/$', empty_view, name='places?'), - re_path(r'^places+/$', empty_view, name='places+'), - re_path(r'^places*/$', empty_view, name='places*'), - re_path(r'^(?:places/)?$', empty_view, name='places2?'), - re_path(r'^(?:places/)+$', empty_view, name='places2+'), - re_path(r'^(?:places/)*$', empty_view, name='places2*'), - re_path(r'^places/([0-9]+|[a-z_]+)/', empty_view, name='places3'), - re_path(r'^places/(?P<id>[0-9]+)/$', empty_view, name='places4'), - re_path(r'^people/(?P<name>\w+)/$', empty_view, name='people'), - re_path(r'^people/(?:name/)$', empty_view, name='people2'), - re_path(r'^people/(?:name/(\w+)/)?$', empty_view, name='people2a'), - re_path(r'^people/(?P<name>\w+)-(?P=name)/$', empty_view, name='people_backref'), - re_path(r'^optional/(?P<name>.*)/(?:.+/)?', empty_view, name='optional'), - re_path(r'^optional/(?P<arg1>\d+)/(?:(?P<arg2>\d+)/)?', absolute_kwargs_view, name='named_optional'), - re_path(r'^optional/(?P<arg1>\d+)/(?:(?P<arg2>\d+)/)?$', absolute_kwargs_view, name='named_optional_terminated'), - re_path(r'^nested/noncapture/(?:(?P<p>\w+))$', empty_view, name='nested-noncapture'), - re_path(r'^nested/capture/((\w+)/)?$', empty_view, name='nested-capture'), - re_path(r'^nested/capture/mixed/((?P<p>\w+))$', empty_view, name='nested-mixedcapture'), - re_path(r'^nested/capture/named/(?P<outer>(?P<inner>\w+)/)?$', empty_view, name='nested-namedcapture'), - re_path(r'^hardcoded/$', empty_view, name='hardcoded'), - re_path(r'^hardcoded/doc\.pdf$', empty_view, name='hardcoded2'), - re_path(r'^people/(?P<state>\w\w)/(?P<name>\w+)/$', empty_view, name='people3'), - re_path(r'^people/(?P<state>\w\w)/(?P<name>[0-9])/$', empty_view, name='people4'), - re_path(r'^people/((?P<state>\w\w)/test)?/(\w+)/$', empty_view, name='people6'), - re_path(r'^character_set/[abcdef0-9]/$', empty_view, name='range'), - re_path(r'^character_set/[\w]/$', empty_view, name='range2'), - re_path(r'^price/\$([0-9]+)/$', empty_view, name='price'), - re_path(r'^price/[$]([0-9]+)/$', empty_view, name='price2'), - re_path(r'^price/[\$]([0-9]+)/$', empty_view, name='price3'), - re_path(r'^product/(?P<product>\w+)\+\(\$(?P<price>[0-9]+(\.[0-9]+)?)\)/$', empty_view, name='product'), - re_path(r'^headlines/(?P<year>[0-9]+)\.(?P<month>[0-9]+)\.(?P<day>[0-9]+)/$', empty_view, name='headlines'), - re_path(r'^windows_path/(?P<drive_name>[A-Z]):\\(?P<path>.+)/$', empty_view, name='windows'), - re_path(r'^special_chars/(?P<chars>.+)/$', empty_view, name='special'), - re_path(r'^(?P<name>.+)/[0-9]+/$', empty_view, name='mixed'), - re_path(r'^repeats/a{1,2}/$', empty_view, name='repeats'), - re_path(r'^repeats/a{2,4}/$', empty_view, name='repeats2'), - re_path(r'^repeats/a{2}/$', empty_view, name='repeats3'), - re_path(r'^test/1/?', empty_view, name='test'), - re_path(r'^outer/(?P<outer>[0-9]+)/', include('urlpatterns_reverse.included_urls')), - re_path(r'^outer-no-kwargs/([0-9]+)/', include('urlpatterns_reverse.included_no_kwargs_urls')), - re_path('', include('urlpatterns_reverse.extra_urls')), - re_path(r'^lookahead-/(?!not-a-city)(?P<city>[^/]+)/$', empty_view, name='lookahead-negative'), - re_path(r'^lookahead\+/(?=a-city)(?P<city>[^/]+)/$', empty_view, name='lookahead-positive'), - re_path(r'^lookbehind-/(?P<city>[^/]+)(?<!not-a-city)/$', empty_view, name='lookbehind-negative'), - re_path(r'^lookbehind\+/(?P<city>[^/]+)(?<=a-city)/$', empty_view, name='lookbehind-positive'), - + re_path(r"^places/([0-9]+)/$", empty_view, name="places"), + re_path(r"^places?/$", empty_view, name="places?"), + re_path(r"^places+/$", empty_view, name="places+"), + re_path(r"^places*/$", empty_view, name="places*"), + re_path(r"^(?:places/)?$", empty_view, name="places2?"), + re_path(r"^(?:places/)+$", empty_view, name="places2+"), + re_path(r"^(?:places/)*$", empty_view, name="places2*"), + re_path(r"^places/([0-9]+|[a-z_]+)/", empty_view, name="places3"), + re_path(r"^places/(?P<id>[0-9]+)/$", empty_view, name="places4"), + re_path(r"^people/(?P<name>\w+)/$", empty_view, name="people"), + re_path(r"^people/(?:name/)$", empty_view, name="people2"), + re_path(r"^people/(?:name/(\w+)/)?$", empty_view, name="people2a"), + re_path(r"^people/(?P<name>\w+)-(?P=name)/$", empty_view, name="people_backref"), + re_path(r"^optional/(?P<name>.*)/(?:.+/)?", empty_view, name="optional"), + re_path( + r"^optional/(?P<arg1>\d+)/(?:(?P<arg2>\d+)/)?", + absolute_kwargs_view, + name="named_optional", + ), + re_path( + r"^optional/(?P<arg1>\d+)/(?:(?P<arg2>\d+)/)?$", + absolute_kwargs_view, + name="named_optional_terminated", + ), + re_path( + r"^nested/noncapture/(?:(?P<p>\w+))$", empty_view, name="nested-noncapture" + ), + re_path(r"^nested/capture/((\w+)/)?$", empty_view, name="nested-capture"), + re_path( + r"^nested/capture/mixed/((?P<p>\w+))$", empty_view, name="nested-mixedcapture" + ), + re_path( + r"^nested/capture/named/(?P<outer>(?P<inner>\w+)/)?$", + empty_view, + name="nested-namedcapture", + ), + re_path(r"^hardcoded/$", empty_view, name="hardcoded"), + re_path(r"^hardcoded/doc\.pdf$", empty_view, name="hardcoded2"), + re_path(r"^people/(?P<state>\w\w)/(?P<name>\w+)/$", empty_view, name="people3"), + re_path(r"^people/(?P<state>\w\w)/(?P<name>[0-9])/$", empty_view, name="people4"), + re_path(r"^people/((?P<state>\w\w)/test)?/(\w+)/$", empty_view, name="people6"), + re_path(r"^character_set/[abcdef0-9]/$", empty_view, name="range"), + re_path(r"^character_set/[\w]/$", empty_view, name="range2"), + re_path(r"^price/\$([0-9]+)/$", empty_view, name="price"), + re_path(r"^price/[$]([0-9]+)/$", empty_view, name="price2"), + re_path(r"^price/[\$]([0-9]+)/$", empty_view, name="price3"), + re_path( + r"^product/(?P<product>\w+)\+\(\$(?P<price>[0-9]+(\.[0-9]+)?)\)/$", + empty_view, + name="product", + ), + re_path( + r"^headlines/(?P<year>[0-9]+)\.(?P<month>[0-9]+)\.(?P<day>[0-9]+)/$", + empty_view, + name="headlines", + ), + re_path( + r"^windows_path/(?P<drive_name>[A-Z]):\\(?P<path>.+)/$", + empty_view, + name="windows", + ), + re_path(r"^special_chars/(?P<chars>.+)/$", empty_view, name="special"), + re_path(r"^(?P<name>.+)/[0-9]+/$", empty_view, name="mixed"), + re_path(r"^repeats/a{1,2}/$", empty_view, name="repeats"), + re_path(r"^repeats/a{2,4}/$", empty_view, name="repeats2"), + re_path(r"^repeats/a{2}/$", empty_view, name="repeats3"), + re_path(r"^test/1/?", empty_view, name="test"), + re_path(r"^outer/(?P<outer>[0-9]+)/", include("urlpatterns_reverse.included_urls")), + re_path( + r"^outer-no-kwargs/([0-9]+)/", + include("urlpatterns_reverse.included_no_kwargs_urls"), + ), + re_path("", include("urlpatterns_reverse.extra_urls")), + re_path( + r"^lookahead-/(?!not-a-city)(?P<city>[^/]+)/$", + empty_view, + name="lookahead-negative", + ), + re_path( + r"^lookahead\+/(?=a-city)(?P<city>[^/]+)/$", + empty_view, + name="lookahead-positive", + ), + re_path( + r"^lookbehind-/(?P<city>[^/]+)(?<!not-a-city)/$", + empty_view, + name="lookbehind-negative", + ), + re_path( + r"^lookbehind\+/(?P<city>[^/]+)(?<=a-city)/$", + empty_view, + name="lookbehind-positive", + ), # Partials should be fine. - path('partial/', empty_view_partial, name='partial'), - path('partial_nested/', empty_view_nested_partial, name='partial_nested'), - path('partial_wrapped/', empty_view_wrapped, name='partial_wrapped'), - + path("partial/", empty_view_partial, name="partial"), + path("partial_nested/", empty_view_nested_partial, name="partial_nested"), + path("partial_wrapped/", empty_view_wrapped, name="partial_wrapped"), # This is non-reversible, but we shouldn't blow up when parsing it. - re_path(r'^(?:foo|bar)(\w+)/$', empty_view, name='disjunction'), - - path('absolute_arg_view/', absolute_kwargs_view), - + re_path(r"^(?:foo|bar)(\w+)/$", empty_view, name="disjunction"), + path("absolute_arg_view/", absolute_kwargs_view), # Tests for #13154. Mixed syntax to test both ways of defining URLs. - re_path(r'^defaults_view1/(?P<arg1>[0-9]+)/$', defaults_view, {'arg2': 1}, name='defaults'), - re_path(r'^defaults_view2/(?P<arg1>[0-9]+)/$', defaults_view, {'arg2': 2}, 'defaults'), - - path('includes/', include(other_patterns)), - + re_path( + r"^defaults_view1/(?P<arg1>[0-9]+)/$", + defaults_view, + {"arg2": 1}, + name="defaults", + ), + re_path( + r"^defaults_view2/(?P<arg1>[0-9]+)/$", defaults_view, {"arg2": 2}, "defaults" + ), + path("includes/", include(other_patterns)), # Security tests - re_path('(.+)/security/$', empty_view, name='security'), + re_path("(.+)/security/$", empty_view, name="security"), ] diff --git a/tests/urlpatterns_reverse/urls_error_handlers.py b/tests/urlpatterns_reverse/urls_error_handlers.py index aee6bb91ae..7261a97e07 100644 --- a/tests/urlpatterns_reverse/urls_error_handlers.py +++ b/tests/urlpatterns_reverse/urls_error_handlers.py @@ -2,6 +2,6 @@ urlpatterns = [] -handler400 = 'urlpatterns_reverse.views.empty_view' -handler404 = 'urlpatterns_reverse.views.empty_view' -handler500 = 'urlpatterns_reverse.views.empty_view' +handler400 = "urlpatterns_reverse.views.empty_view" +handler404 = "urlpatterns_reverse.views.empty_view" +handler500 = "urlpatterns_reverse.views.empty_view" diff --git a/tests/urlpatterns_reverse/urls_without_handlers.py b/tests/urlpatterns_reverse/urls_without_handlers.py index 65fb054e00..8d5ee0d347 100644 --- a/tests/urlpatterns_reverse/urls_without_handlers.py +++ b/tests/urlpatterns_reverse/urls_without_handlers.py @@ -4,6 +4,6 @@ from django.urls import path from .views import bad_view, empty_view urlpatterns = [ - path('test_view/', empty_view, name="test_view"), - path('bad_view/', bad_view, name="bad_view"), + path("test_view/", empty_view, name="test_view"), + path("bad_view/", bad_view, name="bad_view"), ] diff --git a/tests/urlpatterns_reverse/utils.py b/tests/urlpatterns_reverse/utils.py index c1f9a55913..82218f1de4 100644 --- a/tests/urlpatterns_reverse/utils.py +++ b/tests/urlpatterns_reverse/utils.py @@ -5,9 +5,13 @@ from . import views class URLObject: urlpatterns = [ - path('inner/', views.empty_view, name='urlobject-view'), - re_path(r'^inner/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.empty_view, name='urlobject-view'), - re_path(r'^inner/\+\\\$\*/$', views.empty_view, name='urlobject-special-view'), + path("inner/", views.empty_view, name="urlobject-view"), + re_path( + r"^inner/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$", + views.empty_view, + name="urlobject-view", + ), + re_path(r"^inner/\+\\\$\*/$", views.empty_view, name="urlobject-special-view"), ] def __init__(self, app_name, namespace=None): diff --git a/tests/urlpatterns_reverse/views.py b/tests/urlpatterns_reverse/views.py index 3cf97723d4..17c7fe1c3d 100644 --- a/tests/urlpatterns_reverse/views.py +++ b/tests/urlpatterns_reverse/views.py @@ -44,12 +44,14 @@ view_class_instance = ViewClass() class LazyRedirectView(RedirectView): - url = reverse_lazy('named-lazy-url-redirected-to') + url = reverse_lazy("named-lazy-url-redirected-to") -@user_passes_test(lambda u: u.is_authenticated, login_url=reverse_lazy('some-login-page')) +@user_passes_test( + lambda u: u.is_authenticated, login_url=reverse_lazy("some-login-page") +) def login_required_view(request): - return HttpResponse('Hello you') + return HttpResponse("Hello you") def bad_view(request, *args, **kwargs): @@ -57,7 +59,10 @@ def bad_view(request, *args, **kwargs): empty_view_partial = partial(empty_view, template_name="template.html") -empty_view_nested_partial = partial(empty_view_partial, template_name="nested_partial.html") +empty_view_nested_partial = partial( + empty_view_partial, template_name="nested_partial.html" +) empty_view_wrapped = update_wrapper( - partial(empty_view, template_name="template.html"), empty_view, + partial(empty_view, template_name="template.html"), + empty_view, ) diff --git a/tests/urlpatterns_reverse/views_broken.py b/tests/urlpatterns_reverse/views_broken.py index 2bc60c4b98..6975941bdc 100644 --- a/tests/urlpatterns_reverse/views_broken.py +++ b/tests/urlpatterns_reverse/views_broken.py @@ -1,2 +1,2 @@ # I just raise an AttributeError to confuse the view loading mechanism -raise AttributeError('I am here to confuse django.urls.get_callable') +raise AttributeError("I am here to confuse django.urls.get_callable") |