summaryrefslogtreecommitdiff
path: root/django/urls
diff options
context:
space:
mode:
authordjango-bot <ops@djangoproject.com>2022-02-03 20:24:19 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-02-07 20:37:05 +0100
commit9c19aff7c7561e3a82978a272ecdaad40dda5c00 (patch)
treef0506b668a013d0063e5fba3dbf4863b466713ba /django/urls
parentf68fa8b45dfac545cfc4111d4e52804c86db68d3 (diff)
Refs #33476 -- Reformatted code with Black.
Diffstat (limited to 'django/urls')
-rw-r--r--django/urls/__init__.py54
-rw-r--r--django/urls/base.py30
-rw-r--r--django/urls/conf.py42
-rw-r--r--django/urls/converters.py20
-rw-r--r--django/urls/resolvers.py269
-rw-r--r--django/urls/utils.py26
6 files changed, 279 insertions, 162 deletions
diff --git a/django/urls/__init__.py b/django/urls/__init__.py
index e9e32ac5b9..9aaf4814f2 100644
--- a/django/urls/__init__.py
+++ b/django/urls/__init__.py
@@ -1,23 +1,53 @@
from .base import (
- clear_script_prefix, clear_url_caches, get_script_prefix, get_urlconf,
- is_valid_path, resolve, reverse, reverse_lazy, set_script_prefix,
- set_urlconf, translate_url,
+ clear_script_prefix,
+ clear_url_caches,
+ get_script_prefix,
+ get_urlconf,
+ is_valid_path,
+ resolve,
+ reverse,
+ reverse_lazy,
+ set_script_prefix,
+ set_urlconf,
+ translate_url,
)
from .conf import include, path, re_path
from .converters import register_converter
from .exceptions import NoReverseMatch, Resolver404
from .resolvers import (
- LocalePrefixPattern, ResolverMatch, URLPattern, URLResolver,
- get_ns_resolver, get_resolver,
+ LocalePrefixPattern,
+ ResolverMatch,
+ URLPattern,
+ URLResolver,
+ get_ns_resolver,
+ get_resolver,
)
from .utils import get_callable, get_mod_func
__all__ = [
- 'LocalePrefixPattern', 'NoReverseMatch', 'URLPattern',
- 'URLResolver', 'Resolver404', 'ResolverMatch', 'clear_script_prefix',
- 'clear_url_caches', 'get_callable', 'get_mod_func', 'get_ns_resolver',
- 'get_resolver', 'get_script_prefix', 'get_urlconf', 'include',
- 'is_valid_path', 'path', 're_path', 'register_converter', 'resolve',
- 'reverse', 'reverse_lazy', 'set_script_prefix', 'set_urlconf',
- 'translate_url',
+ "LocalePrefixPattern",
+ "NoReverseMatch",
+ "URLPattern",
+ "URLResolver",
+ "Resolver404",
+ "ResolverMatch",
+ "clear_script_prefix",
+ "clear_url_caches",
+ "get_callable",
+ "get_mod_func",
+ "get_ns_resolver",
+ "get_resolver",
+ "get_script_prefix",
+ "get_urlconf",
+ "include",
+ "is_valid_path",
+ "path",
+ "re_path",
+ "register_converter",
+ "resolve",
+ "reverse",
+ "reverse_lazy",
+ "set_script_prefix",
+ "set_urlconf",
+ "translate_url",
]
diff --git a/django/urls/base.py b/django/urls/base.py
index 8c26a3880b..647ef3e2de 100644
--- a/django/urls/base.py
+++ b/django/urls/base.py
@@ -36,16 +36,16 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None):
if not isinstance(viewname, str):
view = viewname
else:
- *path, view = viewname.split(':')
+ *path, view = viewname.split(":")
if current_app:
- current_path = current_app.split(':')
+ current_path = current_app.split(":")
current_path.reverse()
else:
current_path = None
resolved_path = []
- ns_pattern = ''
+ ns_pattern = ""
ns_converters = {}
for ns in path:
current_ns = current_path.pop() if current_path else None
@@ -75,13 +75,15 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None):
except KeyError as key:
if resolved_path:
raise NoReverseMatch(
- "%s is not a registered namespace inside '%s'" %
- (key, ':'.join(resolved_path))
+ "%s is not a registered namespace inside '%s'"
+ % (key, ":".join(resolved_path))
)
else:
raise NoReverseMatch("%s is not a registered namespace" % key)
if ns_pattern:
- resolver = get_ns_resolver(ns_pattern, resolver, tuple(ns_converters.items()))
+ resolver = get_ns_resolver(
+ ns_pattern, resolver, tuple(ns_converters.items())
+ )
return resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
@@ -99,8 +101,8 @@ def set_script_prefix(prefix):
"""
Set the script prefix for the current thread.
"""
- if not prefix.endswith('/'):
- prefix += '/'
+ if not prefix.endswith("/"):
+ prefix += "/"
_prefixes.value = prefix
@@ -110,7 +112,7 @@ def get_script_prefix():
wishes to construct their own URLs manually (although accessing the request
instance is normally going to be a lot cleaner).
"""
- return getattr(_prefixes, "value", '/')
+ return getattr(_prefixes, "value", "/")
def clear_script_prefix():
@@ -168,12 +170,18 @@ def translate_url(url, lang_code):
except Resolver404:
pass
else:
- to_be_reversed = "%s:%s" % (match.namespace, match.url_name) if match.namespace else match.url_name
+ to_be_reversed = (
+ "%s:%s" % (match.namespace, match.url_name)
+ if match.namespace
+ else match.url_name
+ )
with override(lang_code):
try:
url = reverse(to_be_reversed, args=match.args, kwargs=match.kwargs)
except NoReverseMatch:
pass
else:
- url = urlunsplit((parsed.scheme, parsed.netloc, url, parsed.query, parsed.fragment))
+ url = urlunsplit(
+ (parsed.scheme, parsed.netloc, url, parsed.query, parsed.fragment)
+ )
return url
diff --git a/django/urls/conf.py b/django/urls/conf.py
index 40990d10f5..40708028a3 100644
--- a/django/urls/conf.py
+++ b/django/urls/conf.py
@@ -5,7 +5,11 @@ from importlib import import_module
from django.core.exceptions import ImproperlyConfigured
from .resolvers import (
- LocalePrefixPattern, RegexPattern, RoutePattern, URLPattern, URLResolver,
+ LocalePrefixPattern,
+ RegexPattern,
+ RoutePattern,
+ URLPattern,
+ URLResolver,
)
@@ -18,13 +22,13 @@ def include(arg, namespace=None):
except ValueError:
if namespace:
raise ImproperlyConfigured(
- 'Cannot override the namespace for a dynamic module that '
- 'provides a namespace.'
+ "Cannot override the namespace for a dynamic module that "
+ "provides a namespace."
)
raise ImproperlyConfigured(
- 'Passing a %d-tuple to include() is not supported. Pass a '
- '2-tuple containing the list of patterns and app_name, and '
- 'provide the namespace argument to include() instead.' % len(arg)
+ "Passing a %d-tuple to include() is not supported. Pass a "
+ "2-tuple containing the list of patterns and app_name, and "
+ "provide the namespace argument to include() instead." % len(arg)
)
else:
# No namespace hint - use manually provided namespace.
@@ -32,24 +36,24 @@ def include(arg, namespace=None):
if isinstance(urlconf_module, str):
urlconf_module = import_module(urlconf_module)
- patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module)
- app_name = getattr(urlconf_module, 'app_name', app_name)
+ patterns = getattr(urlconf_module, "urlpatterns", urlconf_module)
+ app_name = getattr(urlconf_module, "app_name", app_name)
if namespace and not app_name:
raise ImproperlyConfigured(
- 'Specifying a namespace in include() without providing an app_name '
- 'is not supported. Set the app_name attribute in the included '
- 'module, or pass a 2-tuple containing the list of patterns and '
- 'app_name instead.',
+ "Specifying a namespace in include() without providing an app_name "
+ "is not supported. Set the app_name attribute in the included "
+ "module, or pass a 2-tuple containing the list of patterns and "
+ "app_name instead.",
)
namespace = namespace or app_name
# Make sure the patterns can be iterated through (without this, some
# testcases will break).
if isinstance(patterns, (list, tuple)):
for url_pattern in patterns:
- pattern = getattr(url_pattern, 'pattern', None)
+ pattern = getattr(url_pattern, "pattern", None)
if isinstance(pattern, LocalePrefixPattern):
raise ImproperlyConfigured(
- 'Using i18n_patterns in an included URLconf is not allowed.'
+ "Using i18n_patterns in an included URLconf is not allowed."
)
return (urlconf_module, app_name, namespace)
@@ -59,7 +63,7 @@ def _path(route, view, kwargs=None, name=None, Pattern=None):
if kwargs is not None and not isinstance(kwargs, dict):
raise TypeError(
- f'kwargs argument must be a dict, but got {kwargs.__class__.__name__}.'
+ f"kwargs argument must be a dict, but got {kwargs.__class__.__name__}."
)
if isinstance(view, (list, tuple)):
# For include(...) processing.
@@ -78,11 +82,13 @@ def _path(route, view, kwargs=None, name=None, Pattern=None):
elif isinstance(view, View):
view_cls_name = view.__class__.__name__
raise TypeError(
- f'view must be a callable, pass {view_cls_name}.as_view(), not '
- f'{view_cls_name}().'
+ f"view must be a callable, pass {view_cls_name}.as_view(), not "
+ f"{view_cls_name}()."
)
else:
- raise TypeError('view must be a callable or a list/tuple in the case of include().')
+ raise TypeError(
+ "view must be a callable or a list/tuple in the case of include()."
+ )
path = partial(_path, Pattern=RoutePattern)
diff --git a/django/urls/converters.py b/django/urls/converters.py
index bb8478e32f..8af3cbab25 100644
--- a/django/urls/converters.py
+++ b/django/urls/converters.py
@@ -3,7 +3,7 @@ from functools import lru_cache
class IntConverter:
- regex = '[0-9]+'
+ regex = "[0-9]+"
def to_python(self, value):
return int(value)
@@ -13,7 +13,7 @@ class IntConverter:
class StringConverter:
- regex = '[^/]+'
+ regex = "[^/]+"
def to_python(self, value):
return value
@@ -23,7 +23,7 @@ class StringConverter:
class UUIDConverter:
- regex = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
+ regex = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
def to_python(self, value):
return uuid.UUID(value)
@@ -33,19 +33,19 @@ class UUIDConverter:
class SlugConverter(StringConverter):
- regex = '[-a-zA-Z0-9_]+'
+ regex = "[-a-zA-Z0-9_]+"
class PathConverter(StringConverter):
- regex = '.+'
+ regex = ".+"
DEFAULT_CONVERTERS = {
- 'int': IntConverter(),
- 'path': PathConverter(),
- 'slug': SlugConverter(),
- 'str': StringConverter(),
- 'uuid': UUIDConverter(),
+ "int": IntConverter(),
+ "path": PathConverter(),
+ "slug": SlugConverter(),
+ "str": StringConverter(),
+ "uuid": UUIDConverter(),
}
diff --git a/django/urls/resolvers.py b/django/urls/resolvers.py
index 2ef173c2c8..fee8ae9750 100644
--- a/django/urls/resolvers.py
+++ b/django/urls/resolvers.py
@@ -31,7 +31,17 @@ from .utils import get_callable
class ResolverMatch:
- def __init__(self, func, args, kwargs, url_name=None, app_names=None, namespaces=None, route=None, tried=None):
+ def __init__(
+ self,
+ func,
+ args,
+ kwargs,
+ url_name=None,
+ app_names=None,
+ namespaces=None,
+ route=None,
+ tried=None,
+ ):
self.func = func
self.args = args
self.kwargs = kwargs
@@ -42,21 +52,21 @@ class ResolverMatch:
# If a URLRegexResolver doesn't have a namespace or app_name, it passes
# in an empty value.
self.app_names = [x for x in app_names if x] if app_names else []
- self.app_name = ':'.join(self.app_names)
+ self.app_name = ":".join(self.app_names)
self.namespaces = [x for x in namespaces if x] if namespaces else []
- self.namespace = ':'.join(self.namespaces)
+ self.namespace = ":".join(self.namespaces)
- if hasattr(func, 'view_class'):
+ if hasattr(func, "view_class"):
func = func.view_class
- if not hasattr(func, '__name__'):
+ if not hasattr(func, "__name__"):
# A class-based view
- self._func_path = func.__class__.__module__ + '.' + func.__class__.__name__
+ self._func_path = func.__class__.__module__ + "." + func.__class__.__name__
else:
# A function-based view
- self._func_path = func.__module__ + '.' + func.__name__
+ self._func_path = func.__module__ + "." + func.__name__
view_path = url_name or self._func_path
- self.view_name = ':'.join(self.namespaces + [view_path])
+ self.view_name = ":".join(self.namespaces + [view_path])
def __getitem__(self, index):
return (self.func, self.args, self.kwargs)[index]
@@ -67,15 +77,21 @@ class ResolverMatch:
else:
func = self._func_path
return (
- 'ResolverMatch(func=%s, args=%r, kwargs=%r, url_name=%r, '
- 'app_names=%r, namespaces=%r, route=%r)' % (
- func, self.args, self.kwargs, self.url_name,
- self.app_names, self.namespaces, self.route,
+ "ResolverMatch(func=%s, args=%r, kwargs=%r, url_name=%r, "
+ "app_names=%r, namespaces=%r, route=%r)"
+ % (
+ func,
+ self.args,
+ self.kwargs,
+ self.url_name,
+ self.app_names,
+ self.namespaces,
+ self.route,
)
)
def __reduce_ex__(self, protocol):
- raise PicklingError(f'Cannot pickle {self.__class__.__qualname__}.')
+ raise PicklingError(f"Cannot pickle {self.__class__.__qualname__}.")
def get_resolver(urlconf=None):
@@ -86,7 +102,7 @@ def get_resolver(urlconf=None):
@functools.lru_cache(maxsize=None)
def _get_cached_resolver(urlconf=None):
- return URLResolver(RegexPattern(r'^/'), urlconf)
+ return URLResolver(RegexPattern(r"^/"), urlconf)
@functools.lru_cache(maxsize=None)
@@ -97,7 +113,7 @@ def get_ns_resolver(ns_pattern, resolver, converters):
pattern = RegexPattern(ns_pattern)
pattern.converters = dict(converters)
ns_resolver = URLResolver(pattern, resolver.url_patterns)
- return URLResolver(RegexPattern(r'^/'), [ns_resolver])
+ return URLResolver(RegexPattern(r"^/"), [ns_resolver])
class LocaleRegexDescriptor:
@@ -115,8 +131,8 @@ class LocaleRegexDescriptor:
# avoid per-language compilation.
pattern = getattr(instance, self.attr)
if isinstance(pattern, str):
- instance.__dict__['regex'] = instance._compile(pattern)
- return instance.__dict__['regex']
+ instance.__dict__["regex"] = instance._compile(pattern)
+ return instance.__dict__["regex"]
language_code = get_language()
if language_code not in instance._regex_dict:
instance._regex_dict[language_code] = instance._compile(str(pattern))
@@ -142,7 +158,9 @@ class CheckURLMixin:
# Skip check as it can be useful to start a URL pattern with a slash
# when APPEND_SLASH=False.
return []
- if regex_pattern.startswith(('/', '^/', '^\\/')) and not regex_pattern.endswith('/'):
+ if regex_pattern.startswith(("/", "^/", "^\\/")) and not regex_pattern.endswith(
+ "/"
+ ):
warning = Warning(
"Your URL pattern {} has a route beginning with a '/'. Remove this "
"slash as it is unnecessary. If this pattern is targeted in an "
@@ -157,7 +175,7 @@ class CheckURLMixin:
class RegexPattern(CheckURLMixin):
- regex = LocaleRegexDescriptor('_regex')
+ regex = LocaleRegexDescriptor("_regex")
def __init__(self, regex, name=None, is_endpoint=False):
self._regex = regex
@@ -169,7 +187,7 @@ class RegexPattern(CheckURLMixin):
def match(self, path):
match = (
self.regex.fullmatch(path)
- if self._is_endpoint and self.regex.pattern.endswith('$')
+ if self._is_endpoint and self.regex.pattern.endswith("$")
else self.regex.search(path)
)
if match:
@@ -179,7 +197,7 @@ class RegexPattern(CheckURLMixin):
kwargs = match.groupdict()
args = () if kwargs else match.groups()
kwargs = {k: v for k, v in kwargs.items() if v is not None}
- return path[match.end():], args, kwargs
+ return path[match.end() :], args, kwargs
return None
def check(self):
@@ -191,13 +209,15 @@ class RegexPattern(CheckURLMixin):
def _check_include_trailing_dollar(self):
regex_pattern = self.regex.pattern
- if regex_pattern.endswith('$') and not regex_pattern.endswith(r'\$'):
- return [Warning(
- "Your URL pattern {} uses include with a route ending with a '$'. "
- "Remove the dollar from the route to avoid problems including "
- "URLs.".format(self.describe()),
- id='urls.W001',
- )]
+ if regex_pattern.endswith("$") and not regex_pattern.endswith(r"\$"):
+ return [
+ Warning(
+ "Your URL pattern {} uses include with a route ending with a '$'. "
+ "Remove the dollar from the route to avoid problems including "
+ "URLs.".format(self.describe()),
+ id="urls.W001",
+ )
+ ]
else:
return []
@@ -215,7 +235,7 @@ class RegexPattern(CheckURLMixin):
_PATH_PARAMETER_COMPONENT_RE = _lazy_re_compile(
- r'<(?:(?P<converter>[^>:]+):)?(?P<parameter>[^>]+)>'
+ r"<(?:(?P<converter>[^>:]+):)?(?P<parameter>[^>]+)>"
)
@@ -227,7 +247,7 @@ def _route_to_regex(route, is_endpoint=False):
and {'pk': <django.urls.converters.IntConverter>}.
"""
original_route = route
- parts = ['^']
+ parts = ["^"]
converters = {}
while True:
match = _PATH_PARAMETER_COMPONENT_RE.search(route)
@@ -239,34 +259,34 @@ def _route_to_regex(route, is_endpoint=False):
"URL route '%s' cannot contain whitespace in angle brackets "
"<…>." % original_route
)
- parts.append(re.escape(route[:match.start()]))
- route = route[match.end():]
- parameter = match['parameter']
+ parts.append(re.escape(route[: match.start()]))
+ route = route[match.end() :]
+ parameter = match["parameter"]
if not parameter.isidentifier():
raise ImproperlyConfigured(
"URL route '%s' uses parameter name %r which isn't a valid "
"Python identifier." % (original_route, parameter)
)
- raw_converter = match['converter']
+ raw_converter = match["converter"]
if raw_converter is None:
# If a converter isn't specified, the default is `str`.
- raw_converter = 'str'
+ raw_converter = "str"
try:
converter = get_converter(raw_converter)
except KeyError as e:
raise ImproperlyConfigured(
- 'URL route %r uses invalid converter %r.'
+ "URL route %r uses invalid converter %r."
% (original_route, raw_converter)
) from e
converters[parameter] = converter
- parts.append('(?P<' + parameter + '>' + converter.regex + ')')
+ parts.append("(?P<" + parameter + ">" + converter.regex + ")")
if is_endpoint:
- parts.append(r'\Z')
- return ''.join(parts), converters
+ parts.append(r"\Z")
+ return "".join(parts), converters
class RoutePattern(CheckURLMixin):
- regex = LocaleRegexDescriptor('_route')
+ regex = LocaleRegexDescriptor("_route")
def __init__(self, route, name=None, is_endpoint=False):
self._route = route
@@ -286,19 +306,21 @@ class RoutePattern(CheckURLMixin):
kwargs[key] = converter.to_python(value)
except ValueError:
return None
- return path[match.end():], (), kwargs
+ return path[match.end() :], (), kwargs
return None
def check(self):
warnings = self._check_pattern_startswith_slash()
route = self._route
- if '(?P<' in route or route.startswith('^') or route.endswith('$'):
- warnings.append(Warning(
- "Your URL pattern {} has a route that contains '(?P<', begins "
- "with a '^', or ends with a '$'. This was likely an oversight "
- "when migrating to django.urls.path().".format(self.describe()),
- id='2_0.W001',
- ))
+ if "(?P<" in route or route.startswith("^") or route.endswith("$"):
+ warnings.append(
+ Warning(
+ "Your URL pattern {} has a route that contains '(?P<', begins "
+ "with a '^', or ends with a '$'. This was likely an oversight "
+ "when migrating to django.urls.path().".format(self.describe()),
+ id="2_0.W001",
+ )
+ )
return warnings
def _compile(self, route):
@@ -322,14 +344,14 @@ class LocalePrefixPattern:
def language_prefix(self):
language_code = get_language() or settings.LANGUAGE_CODE
if language_code == settings.LANGUAGE_CODE and not self.prefix_default_language:
- return ''
+ return ""
else:
- return '%s/' % language_code
+ return "%s/" % language_code
def match(self, path):
language_prefix = self.language_prefix
if path.startswith(language_prefix):
- return path[len(language_prefix):], (), {}
+ return path[len(language_prefix) :], (), {}
return None
def check(self):
@@ -350,7 +372,7 @@ class URLPattern:
self.name = name
def __repr__(self):
- return '<%s %s>' % (self.__class__.__name__, self.pattern.describe())
+ return "<%s %s>" % (self.__class__.__name__, self.pattern.describe())
def check(self):
warnings = self._check_pattern_name()
@@ -377,15 +399,18 @@ class URLPattern:
view = self.callback
if inspect.isclass(view) and issubclass(view, View):
- return [Error(
- 'Your URL pattern %s has an invalid view, pass %s.as_view() '
- 'instead of %s.' % (
- self.pattern.describe(),
- view.__name__,
- view.__name__,
- ),
- id='urls.E009',
- )]
+ return [
+ Error(
+ "Your URL pattern %s has an invalid view, pass %s.as_view() "
+ "instead of %s."
+ % (
+ self.pattern.describe(),
+ view.__name__,
+ view.__name__,
+ ),
+ id="urls.E009",
+ )
+ ]
return []
def resolve(self, path):
@@ -394,7 +419,9 @@ class URLPattern:
new_path, args, kwargs = match
# Pass any extra_kwargs as **kwargs.
kwargs.update(self.default_args)
- return ResolverMatch(self.callback, args, kwargs, self.pattern.name, route=str(self.pattern))
+ return ResolverMatch(
+ self.callback, args, kwargs, self.pattern.name, route=str(self.pattern)
+ )
@cached_property
def lookup_str(self):
@@ -405,15 +432,17 @@ class URLPattern:
callback = self.callback
if isinstance(callback, functools.partial):
callback = callback.func
- if hasattr(callback, 'view_class'):
+ if hasattr(callback, "view_class"):
callback = callback.view_class
- elif not hasattr(callback, '__name__'):
+ elif not hasattr(callback, "__name__"):
return callback.__module__ + "." + callback.__class__.__name__
return callback.__module__ + "." + callback.__qualname__
class URLResolver:
- def __init__(self, pattern, urlconf_name, default_kwargs=None, app_name=None, namespace=None):
+ def __init__(
+ self, pattern, urlconf_name, default_kwargs=None, app_name=None, namespace=None
+ ):
self.pattern = pattern
# urlconf_name is the dotted Python path to the module defining
# urlpatterns. It may also be an object with an urlpatterns attribute
@@ -435,12 +464,15 @@ class URLResolver:
def __repr__(self):
if isinstance(self.urlconf_name, list) and self.urlconf_name:
# Don't bother to output the whole list, it can be huge
- urlconf_repr = '<%s list>' % self.urlconf_name[0].__class__.__name__
+ urlconf_repr = "<%s list>" % self.urlconf_name[0].__class__.__name__
else:
urlconf_repr = repr(self.urlconf_name)
- return '<%s %s (%s:%s) %s>' % (
- self.__class__.__name__, urlconf_repr, self.app_name,
- self.namespace, self.pattern.describe(),
+ return "<%s %s (%s:%s) %s>" % (
+ self.__class__.__name__,
+ urlconf_repr,
+ self.app_name,
+ self.namespace,
+ self.pattern.describe(),
)
def check(self):
@@ -458,11 +490,11 @@ class URLResolver:
try:
handler = self.resolve_error_handler(status_code)
except (ImportError, ViewDoesNotExist) as e:
- path = getattr(self.urlconf_module, 'handler%s' % status_code)
+ path = getattr(self.urlconf_module, "handler%s" % status_code)
msg = (
"The custom handler{status_code} view '{path}' could not be imported."
).format(status_code=status_code, path=path)
- messages.append(Error(msg, hint=str(e), id='urls.E008'))
+ messages.append(Error(msg, hint=str(e), id="urls.E008"))
continue
signature = inspect.signature(handler)
args = [None] * num_parameters
@@ -474,10 +506,10 @@ class URLResolver:
"take the correct number of arguments ({args})."
).format(
status_code=status_code,
- path=handler.__module__ + '.' + handler.__qualname__,
- args='request, exception' if num_parameters == 2 else 'request',
+ path=handler.__module__ + "." + handler.__qualname__,
+ args="request, exception" if num_parameters == 2 else "request",
)
- messages.append(Error(msg, id='urls.E007'))
+ messages.append(Error(msg, id="urls.E007"))
return messages
def _populate(self):
@@ -485,7 +517,7 @@ class URLResolver:
# infinite recursion. Concurrent threads may call this at the same
# time and will need to continue, so set 'populating' on a
# thread-local variable.
- if getattr(self._local, 'populating', False):
+ if getattr(self._local, "populating", False):
return
try:
self._local.populating = True
@@ -495,28 +527,45 @@ class URLResolver:
language_code = get_language()
for url_pattern in reversed(self.url_patterns):
p_pattern = url_pattern.pattern.regex.pattern
- if p_pattern.startswith('^'):
+ if p_pattern.startswith("^"):
p_pattern = p_pattern[1:]
if isinstance(url_pattern, URLPattern):
self._callback_strs.add(url_pattern.lookup_str)
bits = normalize(url_pattern.pattern.regex.pattern)
lookups.appendlist(
url_pattern.callback,
- (bits, p_pattern, url_pattern.default_args, url_pattern.pattern.converters)
+ (
+ bits,
+ p_pattern,
+ url_pattern.default_args,
+ url_pattern.pattern.converters,
+ ),
)
if url_pattern.name is not None:
lookups.appendlist(
url_pattern.name,
- (bits, p_pattern, url_pattern.default_args, url_pattern.pattern.converters)
+ (
+ bits,
+ p_pattern,
+ url_pattern.default_args,
+ url_pattern.pattern.converters,
+ ),
)
else: # url_pattern is a URLResolver.
url_pattern._populate()
if url_pattern.app_name:
- apps.setdefault(url_pattern.app_name, []).append(url_pattern.namespace)
+ apps.setdefault(url_pattern.app_name, []).append(
+ url_pattern.namespace
+ )
namespaces[url_pattern.namespace] = (p_pattern, url_pattern)
else:
for name in url_pattern.reverse_dict:
- for matches, pat, defaults, converters in url_pattern.reverse_dict.getlist(name):
+ for (
+ matches,
+ pat,
+ defaults,
+ converters,
+ ) in url_pattern.reverse_dict.getlist(name):
new_matches = normalize(p_pattern + pat)
lookups.appendlist(
name,
@@ -524,10 +573,17 @@ class URLResolver:
new_matches,
p_pattern + pat,
{**defaults, **url_pattern.default_kwargs},
- {**self.pattern.converters, **url_pattern.pattern.converters, **converters}
- )
+ {
+ **self.pattern.converters,
+ **url_pattern.pattern.converters,
+ **converters,
+ },
+ ),
)
- for namespace, (prefix, sub_pattern) in url_pattern.namespace_dict.items():
+ for namespace, (
+ prefix,
+ sub_pattern,
+ ) in url_pattern.namespace_dict.items():
current_converters = url_pattern.pattern.converters
sub_pattern.pattern.converters.update(current_converters)
namespaces[namespace] = (p_pattern + prefix, sub_pattern)
@@ -574,7 +630,7 @@ class URLResolver:
"""Join two routes, without the starting ^ in the second route."""
if not route1:
return route2
- if route2.startswith('^'):
+ if route2.startswith("^"):
route2 = route2[1:]
return route1 + route2
@@ -593,7 +649,7 @@ class URLResolver:
try:
sub_match = pattern.resolve(new_path)
except Resolver404 as e:
- self._extend_tried(tried, pattern, e.args[0].get('tried'))
+ self._extend_tried(tried, pattern, e.args[0].get("tried"))
else:
if sub_match:
# Merge captured arguments in match with submatch
@@ -605,7 +661,11 @@ class URLResolver:
sub_match_args = sub_match.args
if not sub_match_dict:
sub_match_args = args + sub_match.args
- current_route = '' if isinstance(pattern, URLPattern) else str(pattern.pattern)
+ current_route = (
+ ""
+ if isinstance(pattern, URLPattern)
+ else str(pattern.pattern)
+ )
self._extend_tried(tried, pattern, sub_match.tried)
return ResolverMatch(
sub_match.func,
@@ -618,8 +678,8 @@ class URLResolver:
tried,
)
tried.append([pattern])
- raise Resolver404({'tried': tried, 'path': new_path})
- raise Resolver404({'path': path})
+ raise Resolver404({"tried": tried, "path": new_path})
+ raise Resolver404({"path": path})
@cached_property
def urlconf_module(self):
@@ -645,16 +705,17 @@ class URLResolver:
return patterns
def resolve_error_handler(self, view_type):
- callback = getattr(self.urlconf_module, 'handler%s' % view_type, None)
+ callback = getattr(self.urlconf_module, "handler%s" % view_type, None)
if not callback:
# No handler specified in file; use lazy import, since
# django.conf.urls imports this file.
from django.conf import urls
- callback = getattr(urls, 'handler%s' % view_type)
+
+ callback = getattr(urls, "handler%s" % view_type)
return get_callable(callback)
def reverse(self, lookup_view, *args, **kwargs):
- return self._reverse_with_prefix(lookup_view, '', *args, **kwargs)
+ return self._reverse_with_prefix(lookup_view, "", *args, **kwargs)
def _reverse_with_prefix(self, lookup_view, _prefix, *args, **kwargs):
if args and kwargs:
@@ -696,16 +757,22 @@ class URLResolver:
# without quoting to build a decoded URL and look for a match.
# Then, if we have a match, redo the substitution with quoted
# arguments in order to return a properly encoded URL.
- candidate_pat = _prefix.replace('%', '%%') + result
- if re.search('^%s%s' % (re.escape(_prefix), pattern), candidate_pat % text_candidate_subs):
+ candidate_pat = _prefix.replace("%", "%%") + result
+ if re.search(
+ "^%s%s" % (re.escape(_prefix), pattern),
+ candidate_pat % text_candidate_subs,
+ ):
# safe characters from `pchar` definition of RFC 3986
- url = quote(candidate_pat % text_candidate_subs, safe=RFC3986_SUBDELIMS + '/~:@')
+ url = quote(
+ candidate_pat % text_candidate_subs,
+ safe=RFC3986_SUBDELIMS + "/~:@",
+ )
# Don't allow construction of scheme relative urls.
return escape_leading_slashes(url)
# lookup_view can be URL name or callable, but callables are not
# friendly in error messages.
- m = getattr(lookup_view, '__module__', None)
- n = getattr(lookup_view, '__name__', None)
+ m = getattr(lookup_view, "__module__", None)
+ n = getattr(lookup_view, "__name__", None)
if m is not None and n is not None:
lookup_view_s = "%s.%s" % (m, n)
else:
@@ -719,13 +786,15 @@ class URLResolver:
arg_msg = "keyword arguments '%s'" % kwargs
else:
arg_msg = "no arguments"
- msg = (
- "Reverse for '%s' with %s not found. %d pattern(s) tried: %s" %
- (lookup_view_s, arg_msg, len(patterns), patterns)
+ msg = "Reverse for '%s' with %s not found. %d pattern(s) tried: %s" % (
+ lookup_view_s,
+ arg_msg,
+ len(patterns),
+ patterns,
)
else:
msg = (
"Reverse for '%(view)s' not found. '%(view)s' is not "
- "a valid view function or pattern name." % {'view': lookup_view_s}
+ "a valid view function or pattern name." % {"view": lookup_view_s}
)
raise NoReverseMatch(msg)
diff --git a/django/urls/utils.py b/django/urls/utils.py
index e59ab9fdbd..60b46d9050 100644
--- a/django/urls/utils.py
+++ b/django/urls/utils.py
@@ -18,11 +18,15 @@ def get_callable(lookup_view):
return lookup_view
if not isinstance(lookup_view, str):
- raise ViewDoesNotExist("'%s' is not a callable or a dot-notation path" % lookup_view)
+ raise ViewDoesNotExist(
+ "'%s' is not a callable or a dot-notation path" % lookup_view
+ )
mod_name, func_name = get_mod_func(lookup_view)
if not func_name: # No '.' in lookup_view
- raise ImportError("Could not import '%s'. The path must be fully qualified." % lookup_view)
+ raise ImportError(
+ "Could not import '%s'. The path must be fully qualified." % lookup_view
+ )
try:
mod = import_module(mod_name)
@@ -30,8 +34,8 @@ def get_callable(lookup_view):
parentmod, submod = get_mod_func(mod_name)
if submod and not module_has_submodule(import_module(parentmod), submod):
raise ViewDoesNotExist(
- "Could not import '%s'. Parent module %s does not exist." %
- (lookup_view, mod_name)
+ "Could not import '%s'. Parent module %s does not exist."
+ % (lookup_view, mod_name)
)
else:
raise
@@ -40,14 +44,14 @@ def get_callable(lookup_view):
view_func = getattr(mod, func_name)
except AttributeError:
raise ViewDoesNotExist(
- "Could not import '%s'. View does not exist in module %s." %
- (lookup_view, mod_name)
+ "Could not import '%s'. View does not exist in module %s."
+ % (lookup_view, mod_name)
)
else:
if not callable(view_func):
raise ViewDoesNotExist(
- "Could not import '%s.%s'. View is not callable." %
- (mod_name, func_name)
+ "Could not import '%s.%s'. View is not callable."
+ % (mod_name, func_name)
)
return view_func
@@ -56,7 +60,7 @@ def get_mod_func(callback):
# Convert 'django.views.news.stories.story_detail' to
# ['django.views.news.stories', 'story_detail']
try:
- dot = callback.rindex('.')
+ dot = callback.rindex(".")
except ValueError:
- return callback, ''
- return callback[:dot], callback[dot + 1:]
+ return callback, ""
+ return callback[:dot], callback[dot + 1 :]