this module converts requested urls to callback view functions urlresolver is the main class here its resolve method takes a url as a string and returns a resolvermatch object which provides access to all attributes of the resolved url match if a urlregexresolver doesn t have a namespace or appname it passes in an empty value a classbased view a functionbased view build a namespaced resolver for the given parent urlconf pattern this makes it possible to have captured parameters in the parent urlconf pattern return a compiled regular expression based on the active language as a performance optimization if the given regex string is a regular string not a lazilytranslated string proxy compile it once and avoid perlanguage compilation format the url pattern for display in warning messages check that the pattern does not begin with a forward slash skip check as it can be useful to start a url pattern with a slash when appendslashfalse if there are any named groups use those as kwargs ignoring nonnamed groups otherwise pass all nonnamed arguments as positional arguments compile and return the given regular expression try return re compileregex except re error as e raise improperlyconfigured s is not a valid regular expression s regex e from e def strself return strself regex pathparametercomponentre lazyrecompile r pconverter pparameter def routetoregexroute isendpointfalse originalroute route parts converters while true match pathparametercomponentre searchroute if not match parts appendre escaperoute break elif not setmatch group isdisjointstring whitespace raise improperlyconfigured url route s cannot contain whitespace in angle brackets originalroute parts appendre escaperoute match start route routematch end parameter matchparameter if not parameter isidentifier raise improperlyconfigured url route s uses parameter name r which isn t a valid python identifier originalroute parameter rawconverter matchconverter if rawconverter is none if a converter isn t specified the default is str rawconverter str try converter getconverterrawconverter except keyerror as e raise improperlyconfigured url route r uses invalid converter r originalroute rawconverter from e convertersparameter converter parts append p parameter converter regex if isendpoint parts appendrz return joinparts converters class routepatterncheckurlmixin regex localeregexdescriptorroute def initself route namenone isendpointfalse self route route self regexdict self isendpoint isendpoint self name name self converters routetoregexstrroute isendpoint1 def matchself path match self regex searchpath if match routepattern doesn t allow nonnamed groups so args are ignored kwargs match groupdict for key value in kwargs items converter self converterskey try kwargskey converter topythonvalue except valueerror return none return pathmatch end kwargs return none def checkself warnings self checkpatternstartswithslash self checkpatternunmatchedanglebrackets 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 formatself describe id20 w001 return warnings def checkpatternunmatchedanglebracketsself warnings msg your url pattern s has an unmatched s bracket brackets re findallr strself route openbracketcounter 0 for bracket in brackets if bracket openbracketcounter 1 elif bracket openbracketcounter 1 if openbracketcounter 0 warnings append warningmsg self describe idurls w010 openbracketcounter 0 if openbracketcounter 0 warnings appendwarningmsg self describe idurls w010 return warnings def compileself route return re compileroutetoregexroute self isendpoint0 def strself return strself route class localeprefixpattern def initself prefixdefaultlanguagetrue self prefixdefaultlanguage prefixdefaultlanguage self converters property def regexself this is only used by reverse and cached in reversedict return re compilere escapeself languageprefix property def languageprefixself languagecode getlanguage or settings languagecode if languagecode settings languagecode and not self prefixdefaultlanguage return else return s languagecode def matchself path languageprefix self languageprefix if path startswithlanguageprefix return path removeprefixlanguageprefix return none def checkself return def describeself return formatself def strself return self languageprefix class urlpattern def initself pattern callback defaultargsnone namenone self pattern pattern self callback callback the view self defaultargs defaultargs or self name name def reprself return s s self class name self pattern describe def checkself warnings self checkpatternname warnings extendself pattern check warnings extendself checkcallback return warnings def checkpatternnameself if self pattern name is not none and in self pattern name warning warning your url pattern has a name including a remove the colon to avoid ambiguous namespace references formatself pattern describe idurls w003 return warning else return def checkcallbackself from django views import view view self callback if inspect isclassview and issubclassview view return error your url pattern s has an invalid view pass s asview instead of s self pattern describe view name view name idurls e009 return def resolveself path match self pattern matchpath if match newpath args capturedkwargs match pass any default args as kwargs kwargs capturedkwargs self defaultargs return resolvermatch self callback args kwargs self pattern name routestrself pattern capturedkwargscapturedkwargs extrakwargsself defaultargs cachedproperty def lookupstrself callback self callback if isinstancecallback functools partial callback callback func if hasattrcallback viewclass callback callback viewclass elif not hasattrcallback name return callback module callback class name return callback module callback qualname class urlresolver def init self pattern urlconfname defaultkwargsnone appnamenone namespacenone self pattern pattern urlconfname is the dotted python path to the module defining urlpatterns it may also be an object with an urlpatterns attribute or urlpatterns itself self urlconfname urlconfname self callback none self defaultkwargs defaultkwargs or self namespace namespace self appname appname self reversedict self namespacedict self appdict set of dotted paths to all functions and classes that are used in urlpatterns self callbackstrs set self populated false self local local def reprself if isinstanceself urlconfname list and self urlconfname don t bother to output the whole list it can be huge urlconfrepr s list self urlconfname0 class name else urlconfrepr reprself urlconfname return s s s s s self class name urlconfrepr self appname self namespace self pattern describe def checkself messages for pattern in self urlpatterns messages extendcheckresolverpattern messages extendself checkcustomerrorhandlers return messages or self pattern check def checkcustomerrorhandlersself messages all handlers take request exception arguments except handler500 which takes request for statuscode numparameters in 400 2 403 2 404 2 500 1 try handler self resolveerrorhandlerstatuscode except importerror viewdoesnotexist as e path getattrself urlconfmodule handlers statuscode msg the custom handlerstatuscode view path could not be imported formatstatuscodestatuscode pathpath messages appenderrormsg hintstre idurls e008 continue signature inspect signaturehandler args none numparameters try signature bindargs except typeerror msg the custom handlerstatuscode view path does not take the correct number of arguments args format statuscodestatuscode pathhandler module handler qualname argsrequest exception if numparameters 2 else request messages appenderrormsg idurls e007 return messages def populateself shortcircuit if called recursively in this thread to prevent infinite recursion concurrent threads may call this at the same time and will need to continue so set populating on a threadlocal variable if getattrself local populating false return try self local populating true lookups multivaluedict namespaces apps languagecode getlanguage for urlpattern in reversedself urlpatterns ppattern urlpattern pattern regex pattern ppattern ppattern removeprefix if isinstanceurlpattern urlpattern self callbackstrs addurlpattern lookupstr bits normalizeurlpattern pattern regex pattern lookups appendlist urlpattern callback bits ppattern urlpattern defaultargs urlpattern pattern converters if urlpattern name is not none lookups appendlist urlpattern name bits ppattern urlpattern defaultargs urlpattern pattern converters else urlpattern is a urlresolver urlpattern populate if urlpattern appname apps setdefaulturlpattern appname append urlpattern namespace namespacesurlpattern namespace ppattern urlpattern else for name in urlpattern reversedict for matches pat defaults converters in urlpattern reversedict getlistname newmatches normalizeppattern pat lookups appendlist name newmatches ppattern pat defaults urlpattern defaultkwargs self pattern converters urlpattern pattern converters converters for namespace prefix subpattern in urlpattern namespacedict items currentconverters urlpattern pattern converters subpattern pattern converters updatecurrentconverters namespacesnamespace ppattern prefix subpattern for appname namespacelist in urlpattern appdict items apps setdefaultappname extendnamespacelist self callbackstrs updateurlpattern callbackstrs self namespacedictlanguagecode namespaces self appdictlanguagecode apps self reversedictlanguagecode lookups self populated true finally self local populating false property def reversedictself languagecode getlanguage if languagecode not in self reversedict self populate return self reversedictlanguagecode property def namespacedictself languagecode getlanguage if languagecode not in self namespacedict self populate return self namespacedictlanguagecode property def appdictself languagecode getlanguage if languagecode not in self appdict self populate return self appdictlanguagecode staticmethod def extendtriedtried pattern subtriednone if subtried is none tried appendpattern else tried extendpattern t for t in subtried staticmethod def joinrouteroute1 route2 merge captured arguments in match with submatch update the submatchdict with the kwargs from the submatch if there are any named groups ignore all nonnamed groups otherwise pass all nonnamed arguments as positional arguments urlconfmodule might be a valid set of patterns so we default to it no handler specified in file use lazy import since django conf urls imports this file convert the candidate subs to text using converter tourl wsgi provides decoded urls without xx escapes and the url resolver operates on such urls first substitute arguments 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 safe characters from pchar definition of rfc 3986 don t allow construction of scheme relative urls lookupview can be url name or callable but callables are not friendly in error messages if a urlregexresolver doesn t have a namespace or app_name it passes in an empty value a class based view a function based view build a namespaced resolver for the given parent urlconf pattern this makes it possible to have captured parameters in the parent urlconf pattern return a compiled regular expression based on the active language as a performance optimization if the given regex string is a regular string not a lazily translated string proxy compile it once and avoid per language compilation format the url pattern for display in warning messages check that the pattern does not begin with a forward slash skip check as it can be useful to start a url pattern with a slash when append_slash false if there are any named groups use those as kwargs ignoring non named groups otherwise pass all non named arguments as positional arguments compile and return the given regular expression convert a path pattern into a regular expression return the regular expression and a dictionary mapping the capture names to the converters for example foo int pk returns foo p pk 0 9 and pk django urls converters intconverter if a converter isn t specified the default is str routepattern doesn t allow non named groups so args are ignored this is only used by reverse and cached in _reverse_dict the view check that the pattern name does not contain a colon pass any default args as kwargs a string that identifies the view e g path to view_function or path to classbasedview urlconf_name is the dotted python path to the module defining urlpatterns it may also be an object with an urlpatterns attribute or urlpatterns itself set of dotted paths to all functions and classes that are used in urlpatterns don t bother to output the whole list it can be huge all handlers take request exception arguments except handler500 which takes request short circuit if called recursively in this thread to prevent infinite recursion concurrent threads may call this at the same time and will need to continue so set populating on a thread local variable url_pattern is a urlresolver join two routes without the starting in the second route path may be a reverse_lazy object merge captured arguments in match with submatch update the sub_match_dict with the kwargs from the sub_match if there are any named groups ignore all non named groups otherwise pass all non named arguments as positional arguments urlconf_module might be a valid set of patterns so we default to it no handler specified in file use lazy import since django conf urls imports this file convert the candidate subs to text using converter to_url wsgi provides decoded urls without xx escapes and the url resolver operates on such urls first substitute arguments 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 safe characters from pchar definition of rfc 3986 don t allow construction of scheme relative urls lookup_view can be url name or callable but callables are not friendly in error messages
import functools
import inspect
import re
import string
from importlib import import_module
from pickle import PicklingError
from urllib.parse import quote

from asgiref.local import Local

from django.conf import settings
from django.core.checks import Error, Warning
from django.core.checks.urls import check_resolver
from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
from django.utils.datastructures import MultiValueDict
from django.utils.functional import cached_property
from django.utils.http import RFC3986_SUBDELIMS, escape_leading_slashes
from django.utils.regex_helper import _lazy_re_compile, normalize
from django.utils.translation import get_language

from .converters import get_converter
from .exceptions import NoReverseMatch, Resolver404
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,
        captured_kwargs=None,
        extra_kwargs=None,
    ):
        self.func = func
        self.args = args
        self.kwargs = kwargs
        self.url_name = url_name
        self.route = route
        self.tried = tried
        self.captured_kwargs = captured_kwargs
        self.extra_kwargs = extra_kwargs

        
        
        self.app_names = [x for x in app_names if x] if app_names else []
        self.app_name = ":".join(self.app_names)
        self.namespaces = [x for x in namespaces if x] if namespaces else []
        self.namespace = ":".join(self.namespaces)

        if hasattr(func, "view_class"):
            func = func.view_class
        if not hasattr(func, "__name__"):
            
            self._func_path = func.__class__.__module__ + "." + func.__class__.__name__
        else:
            
            self._func_path = func.__module__ + "." + func.__name__

        view_path = url_name or self._func_path
        self.view_name = ":".join(self.namespaces + [view_path])

    def __getitem__(self, index):
        return (self.func, self.args, self.kwargs)[index]

    def __repr__(self):
        if isinstance(self.func, functools.partial):
            func = repr(self.func)
        else:
            func = self._func_path
        return (
            "ResolverMatch(func=%s, args=%r, kwargs=%r, url_name=%r, "
            "app_names=%r, namespaces=%r, route=%r%s%s)"
            % (
                func,
                self.args,
                self.kwargs,
                self.url_name,
                self.app_names,
                self.namespaces,
                self.route,
                f", captured_kwargs={self.captured_kwargs!r}"
                if self.captured_kwargs
                else "",
                f", extra_kwargs={self.extra_kwargs!r}" if self.extra_kwargs else "",
            )
        )

    def __reduce_ex__(self, protocol):
        raise PicklingError(f"Cannot pickle {self.__class__.__qualname__}.")


def get_resolver(urlconf=None):
    if urlconf is None:
        urlconf = settings.ROOT_URLCONF
    return _get_cached_resolver(urlconf)


@functools.cache
def _get_cached_resolver(urlconf=None):
    return URLResolver(RegexPattern(r"^/"), urlconf)


@functools.cache
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])


class LocaleRegexDescriptor:
    def __init__(self, attr):
        self.attr = attr

    def __get__(self, instance, cls=None):
        
        if instance is None:
            return self
        
        
        
        pattern = getattr(instance, self.attr)
        if isinstance(pattern, str):
            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))
        return instance._regex_dict[language_code]


class CheckURLMixin:
    def describe(self):
        
        description = "'{}'".format(self)
        if self.name:
            description += " [name='{}']".format(self.name)
        return description

    def _check_pattern_startswith_slash(self):
        
        regex_pattern = self.regex.pattern
        if not settings.APPEND_SLASH:
            
            
            return []
        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 "
                "include(), ensure the include() pattern has a trailing '/'.".format(
                    self.describe()
                ),
                id="urls.W002",
            )
            return [warning]
        else:
            return []


class RegexPattern(CheckURLMixin):
    regex = LocaleRegexDescriptor("_regex")

    def __init__(self, regex, name=None, is_endpoint=False):
        self._regex = regex
        self._regex_dict = {}
        self._is_endpoint = is_endpoint
        self.name = name
        self.converters = {}

    def match(self, path):
        match = (
            self.regex.fullmatch(path)
            if self._is_endpoint and self.regex.pattern.endswith("$")
            else self.regex.search(path)
        )
        if match:
            
            
            
            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 None

    def check(self):
        warnings = []
        warnings.extend(self._check_pattern_startswith_slash())
        if not self._is_endpoint:
            warnings.extend(self._check_include_trailing_dollar())
        return warnings

    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",
                )
            ]
        else:
            return []

    def _compile(self, regex):
        
        try:
            return re.compile(regex)
        except re.error as e:
            raise ImproperlyConfigured(
                '"%s" is not a valid regular expression: %s' % (regex, e)
            ) from e

    def __str__(self):
        return str(self._regex)


_PATH_PARAMETER_COMPONENT_RE = _lazy_re_compile(
    r"<(?:(?P<converter>[^>:]+):)?(?P<parameter>[^>]+)>"
)


def _route_to_regex(route, is_endpoint=False):
    
    original_route = route
    parts = ["^"]
    converters = {}
    while True:
        match = _PATH_PARAMETER_COMPONENT_RE.search(route)
        if not match:
            parts.append(re.escape(route))
            break
        elif not set(match.group()).isdisjoint(string.whitespace):
            raise ImproperlyConfigured(
                "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"]
        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"]
        if raw_converter is None:
            
            raw_converter = "str"
        try:
            converter = get_converter(raw_converter)
        except KeyError as e:
            raise ImproperlyConfigured(
                "URL route %r uses invalid converter %r."
                % (original_route, raw_converter)
            ) from e
        converters[parameter] = converter
        parts.append("(?P<" + parameter + ">" + converter.regex + ")")
    if is_endpoint:
        parts.append(r"\Z")
    return "".join(parts), converters


class RoutePattern(CheckURLMixin):
    regex = LocaleRegexDescriptor("_route")

    def __init__(self, route, name=None, is_endpoint=False):
        self._route = route
        self._regex_dict = {}
        self._is_endpoint = is_endpoint
        self.name = name
        self.converters = _route_to_regex(str(route), is_endpoint)[1]

    def match(self, path):
        match = self.regex.search(path)
        if match:
            
            kwargs = match.groupdict()
            for key, value in kwargs.items():
                converter = self.converters[key]
                try:
                    kwargs[key] = converter.to_python(value)
                except ValueError:
                    return None
            return path[match.end() :], (), kwargs
        return None

    def check(self):
        warnings = [
            *self._check_pattern_startswith_slash(),
            *self._check_pattern_unmatched_angle_brackets(),
        ]
        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",
                )
            )
        return warnings

    def _check_pattern_unmatched_angle_brackets(self):
        warnings = []
        msg = "Your URL pattern %s has an unmatched '%s' bracket."
        brackets = re.findall(r"[<>]", str(self._route))
        open_bracket_counter = 0
        for bracket in brackets:
            if bracket == "<":
                open_bracket_counter += 1
            elif bracket == ">":
                open_bracket_counter -= 1
                if open_bracket_counter < 0:
                    warnings.append(
                        Warning(msg % (self.describe(), ">"), id="urls.W010")
                    )
                    open_bracket_counter = 0
        if open_bracket_counter > 0:
            warnings.append(Warning(msg % (self.describe(), "<"), id="urls.W010"))
        return warnings

    def _compile(self, route):
        return re.compile(_route_to_regex(route, self._is_endpoint)[0])

    def __str__(self):
        return str(self._route)


class LocalePrefixPattern:
    def __init__(self, prefix_default_language=True):
        self.prefix_default_language = prefix_default_language
        self.converters = {}

    @property
    def regex(self):
        
        return re.compile(re.escape(self.language_prefix))

    @property
    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 ""
        else:
            return "%s/" % language_code

    def match(self, path):
        language_prefix = self.language_prefix
        if path.startswith(language_prefix):
            return path.removeprefix(language_prefix), (), {}
        return None

    def check(self):
        return []

    def describe(self):
        return "'{}'".format(self)

    def __str__(self):
        return self.language_prefix


class URLPattern:
    def __init__(self, pattern, callback, default_args=None, name=None):
        self.pattern = pattern
        self.callback = callback  
        self.default_args = default_args or {}
        self.name = name

    def __repr__(self):
        return "<%s %s>" % (self.__class__.__name__, self.pattern.describe())

    def check(self):
        warnings = self._check_pattern_name()
        warnings.extend(self.pattern.check())
        warnings.extend(self._check_callback())
        return warnings

    def _check_pattern_name(self):
        
        if self.pattern.name is not None and ":" in self.pattern.name:
            warning = Warning(
                "Your URL pattern {} has a name including a ':'. Remove the colon, to "
                "avoid ambiguous namespace references.".format(self.pattern.describe()),
                id="urls.W003",
            )
            return [warning]
        else:
            return []

    def _check_callback(self):
        from django.views import View

        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 []

    def resolve(self, path):
        match = self.pattern.match(path)
        if match:
            new_path, args, captured_kwargs = match
            
            kwargs = {**captured_kwargs, **self.default_args}
            return ResolverMatch(
                self.callback,
                args,
                kwargs,
                self.pattern.name,
                route=str(self.pattern),
                captured_kwargs=captured_kwargs,
                extra_kwargs=self.default_args,
            )

    @cached_property
    def lookup_str(self):
        
        callback = self.callback
        if isinstance(callback, functools.partial):
            callback = callback.func
        if hasattr(callback, "view_class"):
            callback = callback.view_class
        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
    ):
        self.pattern = pattern
        
        
        
        self.urlconf_name = urlconf_name
        self.callback = None
        self.default_kwargs = default_kwargs or {}
        self.namespace = namespace
        self.app_name = app_name
        self._reverse_dict = {}
        self._namespace_dict = {}
        self._app_dict = {}
        
        
        self._callback_strs = set()
        self._populated = False
        self._local = Local()

    def __repr__(self):
        if isinstance(self.urlconf_name, list) and self.urlconf_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(),
        )

    def check(self):
        messages = []
        for pattern in self.url_patterns:
            messages.extend(check_resolver(pattern))
        messages.extend(self._check_custom_error_handlers())
        return messages or self.pattern.check()

    def _check_custom_error_handlers(self):
        messages = []
        
        
        for status_code, num_parameters in [(400, 2), (403, 2), (404, 2), (500, 1)]:
            try:
                handler = self.resolve_error_handler(status_code)
            except (ImportError, ViewDoesNotExist) as e:
                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"))
                continue
            signature = inspect.signature(handler)
            args = [None] * num_parameters
            try:
                signature.bind(*args)
            except TypeError:
                msg = (
                    "The custom handler{status_code} view '{path}' does not "
                    "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",
                )
                messages.append(Error(msg, id="urls.E007"))
        return messages

    def _populate(self):
        
        
        
        
        if getattr(self._local, "populating", False):
            return
        try:
            self._local.populating = True
            lookups = MultiValueDict()
            namespaces = {}
            apps = {}
            language_code = get_language()
            for url_pattern in reversed(self.url_patterns):
                p_pattern = url_pattern.pattern.regex.pattern
                p_pattern = p_pattern.removeprefix("^")
                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,
                        ),
                    )
                    if url_pattern.name is not None:
                        lookups.appendlist(
                            url_pattern.name,
                            (
                                bits,
                                p_pattern,
                                url_pattern.default_args,
                                url_pattern.pattern.converters,
                            ),
                        )
                else:  
                    url_pattern._populate()
                    if url_pattern.app_name:
                        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):
                                new_matches = normalize(p_pattern + pat)
                                lookups.appendlist(
                                    name,
                                    (
                                        new_matches,
                                        p_pattern + pat,
                                        {**defaults, **url_pattern.default_kwargs},
                                        {
                                            **self.pattern.converters,
                                            **url_pattern.pattern.converters,
                                            **converters,
                                        },
                                    ),
                                )
                        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)
                        for app_name, namespace_list in url_pattern.app_dict.items():
                            apps.setdefault(app_name, []).extend(namespace_list)
                    self._callback_strs.update(url_pattern._callback_strs)
            self._namespace_dict[language_code] = namespaces
            self._app_dict[language_code] = apps
            self._reverse_dict[language_code] = lookups
            self._populated = True
        finally:
            self._local.populating = False

    @property
    def reverse_dict(self):
        language_code = get_language()
        if language_code not in self._reverse_dict:
            self._populate()
        return self._reverse_dict[language_code]

    @property
    def namespace_dict(self):
        language_code = get_language()
        if language_code not in self._namespace_dict:
            self._populate()
        return self._namespace_dict[language_code]

    @property
    def app_dict(self):
        language_code = get_language()
        if language_code not in self._app_dict:
            self._populate()
        return self._app_dict[language_code]

    @staticmethod
    def _extend_tried(tried, pattern, sub_tried=None):
        if sub_tried is None:
            tried.append([pattern])
        else:
            tried.extend([pattern, *t] for t in sub_tried)

    @staticmethod
    def _join_route(route1, route2):
        
        if not route1:
            return route2
        route2 = route2.removeprefix("^")
        return route1 + route2

    def _is_callback(self, name):
        if not self._populated:
            self._populate()
        return name in self._callback_strs

    def resolve(self, path):
        path = str(path)  
        tried = []
        match = self.pattern.match(path)
        if match:
            new_path, args, kwargs = match
            for pattern in self.url_patterns:
                try:
                    sub_match = pattern.resolve(new_path)
                except Resolver404 as e:
                    self._extend_tried(tried, pattern, e.args[0].get("tried"))
                else:
                    if sub_match:
                        
                        sub_match_dict = {**kwargs, **self.default_kwargs}
                        
                        sub_match_dict.update(sub_match.kwargs)
                        
                        
                        
                        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)
                        )
                        self._extend_tried(tried, pattern, sub_match.tried)
                        return ResolverMatch(
                            sub_match.func,
                            sub_match_args,
                            sub_match_dict,
                            sub_match.url_name,
                            [self.app_name] + sub_match.app_names,
                            [self.namespace] + sub_match.namespaces,
                            self._join_route(current_route, sub_match.route),
                            tried,
                            captured_kwargs=sub_match.captured_kwargs,
                            extra_kwargs={
                                **self.default_kwargs,
                                **sub_match.extra_kwargs,
                            },
                        )
                    tried.append([pattern])
            raise Resolver404({"tried": tried, "path": new_path})
        raise Resolver404({"path": path})

    @cached_property
    def urlconf_module(self):
        if isinstance(self.urlconf_name, str):
            return import_module(self.urlconf_name)
        else:
            return self.urlconf_name

    @cached_property
    def url_patterns(self):
        
        patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
        try:
            iter(patterns)
        except TypeError as e:
            msg = (
                "The included URLconf '{name}' 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."
            )
            raise ImproperlyConfigured(msg.format(name=self.urlconf_name)) from e
        return patterns

    def resolve_error_handler(self, view_type):
        callback = getattr(self.urlconf_module, "handler%s" % view_type, None)
        if not callback:
            
            
            from django.conf import urls

            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)

    def _reverse_with_prefix(self, lookup_view, _prefix, *args, **kwargs):
        if args and kwargs:
            raise ValueError("Don't mix *args and **kwargs in call to reverse()!")

        if not self._populated:
            self._populate()

        possibilities = self.reverse_dict.getlist(lookup_view)

        for possibility, pattern, defaults, converters in possibilities:
            for result, params in possibility:
                if args:
                    if len(args) != len(params):
                        continue
                    candidate_subs = dict(zip(params, args))
                else:
                    if set(kwargs).symmetric_difference(params).difference(defaults):
                        continue
                    matches = True
                    for k, v in defaults.items():
                        if k in params:
                            continue
                        if kwargs.get(k, v) != v:
                            matches = False
                            break
                    if not matches:
                        continue
                    candidate_subs = kwargs
                
                text_candidate_subs = {}
                match = True
                for k, v in candidate_subs.items():
                    if k in converters:
                        try:
                            text_candidate_subs[k] = converters[k].to_url(v)
                        except ValueError:
                            match = False
                            break
                    else:
                        text_candidate_subs[k] = str(v)
                if not match:
                    continue
                
                
                
                
                
                candidate_pat = _prefix.replace("%", "%%") + result
                if re.search(
                    "^%s%s" % (re.escape(_prefix), pattern),
                    candidate_pat % text_candidate_subs,
                ):
                    
                    url = quote(
                        candidate_pat % text_candidate_subs,
                        safe=RFC3986_SUBDELIMS + "/~:@",
                    )
                    
                    return escape_leading_slashes(url)
        
        
        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:
            lookup_view_s = lookup_view

        patterns = [pattern for (_, pattern, _, _) in possibilities]
        if patterns:
            if args:
                arg_msg = "arguments '%s'" % (args,)
            elif kwargs:
                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,
            )
        else:
            msg = (
                "Reverse for '%(view)s' not found. '%(view)s' is not "
                "a valid view function or pattern name." % {"view": lookup_view_s}
            )
        raise NoReverseMatch(msg)