From 9f9921e89c5c559ff4324f8cf968007cefbf6442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Starck?= Date: Tue, 5 Jan 2016 16:47:48 -0500 Subject: [PATCH] Fixed #26039 -- Unwrapped nested partials in URL reversal. Prior to Python 3.5 nested partials need to be fully "unfolded" to get the actual function. --- django/urls/resolvers.py | 4 +++- tests/urlpatterns_reverse/urls.py | 5 +++-- tests/urlpatterns_reverse/views.py | 3 +-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/django/urls/resolvers.py b/django/urls/resolvers.py index 7b9db5506f..0208601f79 100644 --- a/django/urls/resolvers.py +++ b/django/urls/resolvers.py @@ -135,7 +135,9 @@ class RegexURLPattern(LocaleRegexProvider): 'path.to.ClassBasedView'). """ callback = self.callback - if isinstance(callback, functools.partial): + # Python 3.5 collapses nested partials, so can change "while" to "if" + # when it's the minimum supported version. + while isinstance(callback, functools.partial): callback = callback.func if not hasattr(callback, '__name__'): return callback.__module__ + "." + callback.__class__.__name__ diff --git a/tests/urlpatterns_reverse/urls.py b/tests/urlpatterns_reverse/urls.py index 0ede20da3b..35e2ff707c 100644 --- a/tests/urlpatterns_reverse/urls.py +++ b/tests/urlpatterns_reverse/urls.py @@ -1,8 +1,8 @@ from django.conf.urls import include, url from .views import ( - absolute_kwargs_view, defaults_view, empty_view, 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 = [ @@ -62,6 +62,7 @@ urlpatterns = [ # Partials should be fine. url(r'^partial/', empty_view_partial, name="partial"), + url(r'^partial_nested/', empty_view_nested_partial, name="partial_nested"), url(r'^partial_wrapped/', empty_view_wrapped, name="partial_wrapped"), # This is non-reversible, but we shouldn't blow up when parsing it. diff --git a/tests/urlpatterns_reverse/views.py b/tests/urlpatterns_reverse/views.py index 6bf5c453d1..acfa530b4c 100644 --- a/tests/urlpatterns_reverse/views.py +++ b/tests/urlpatterns_reverse/views.py @@ -55,8 +55,7 @@ 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_wrapped = update_wrapper( partial(empty_view, template_name="template.html"), empty_view, )