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 /django/urls | |
| parent | f68fa8b45dfac545cfc4111d4e52804c86db68d3 (diff) | |
Refs #33476 -- Reformatted code with Black.
Diffstat (limited to 'django/urls')
| -rw-r--r-- | django/urls/__init__.py | 54 | ||||
| -rw-r--r-- | django/urls/base.py | 30 | ||||
| -rw-r--r-- | django/urls/conf.py | 42 | ||||
| -rw-r--r-- | django/urls/converters.py | 20 | ||||
| -rw-r--r-- | django/urls/resolvers.py | 269 | ||||
| -rw-r--r-- | django/urls/utils.py | 26 |
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 :] |
