scriptname prefixes for each thread are stored here if there s no entry for the current thread which is the only one we ever access it is assumed to be empty overridden urlconfs for each thread are stored here lookup the name to see if it could be an app identifier yes path part matches an app in the current resolver if we are reversing for a particular app use that namespace the name isn t shared by one of the instances i e the default so pick the first instance as the default set the script prefix for the current thread return the currently active script prefix useful for client code that wishes to construct their own urls manually although accessing the request instance is normally going to be a lot cleaner unset the script prefix for the current thread set the urlconf for the current thread overriding the default one in settings if urlconfname is none revert back to the default return the root urlconf to use for the current thread if it has been changed from the default one return the resolvermatch if the given path resolves against the default url resolver false otherwise this is a convenience method to make working with is this a match cases easier avoiding try except blocks given a url absolute or relative try to get its translated version in the langcode language either by i18npatterns or by translated regex return the original url if no translated version is found url may be encoded script_name prefixes for each thread are stored here if there s no entry for the current thread which is the only one we ever access it is assumed to be empty overridden urlconfs for each thread are stored here lookup the name to see if it could be an app identifier yes path part matches an app in the current resolver if we are reversing for a particular app use that namespace the name isn t shared by one of the instances i e the default so pick the first instance as the default set the script prefix for the current thread return the currently active script prefix useful for client code that wishes to construct their own urls manually although accessing the request instance is normally going to be a lot cleaner unset the script prefix for the current thread set the urlconf for the current thread overriding the default one in settings if urlconf_name is none revert back to the default return the root urlconf to use for the current thread if it has been changed from the default one return the resolvermatch if the given path resolves against the default url resolver false otherwise this is a convenience method to make working with is this a match cases easier avoiding try except blocks given a url absolute or relative try to get its translated version in the lang_code language either by i18n_patterns or by translated regex return the original url if no translated version is found url may be encoded
from urllib.parse import unquote, urlsplit, urlunsplit

from asgiref.local import Local

from django.utils.functional import lazy
from django.utils.translation import override

from .exceptions import NoReverseMatch, Resolver404
from .resolvers import _get_cached_resolver, get_ns_resolver, get_resolver
from .utils import get_callable




_prefixes = Local()


_urlconfs = Local()


def resolve(path, urlconf=None):
    if urlconf is None:
        urlconf = get_urlconf()
    return get_resolver(urlconf).resolve(path)


def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None):
    if urlconf is None:
        urlconf = get_urlconf()
    resolver = get_resolver(urlconf)
    args = args or []
    kwargs = kwargs or {}

    prefix = get_script_prefix()

    if not isinstance(viewname, str):
        view = viewname
    else:
        *path, view = viewname.split(":")

        if current_app:
            current_path = current_app.split(":")
            current_path.reverse()
        else:
            current_path = None

        resolved_path = []
        ns_pattern = ""
        ns_converters = {}
        for ns in path:
            current_ns = current_path.pop() if current_path else None
            
            try:
                app_list = resolver.app_dict[ns]
                
                if current_ns and current_ns in app_list:
                    
                    
                    ns = current_ns
                elif ns not in app_list:
                    
                    
                    ns = app_list[0]
            except KeyError:
                pass

            if ns != current_ns:
                current_path = None

            try:
                extra, resolver = resolver.namespace_dict[ns]
                resolved_path.append(ns)
                ns_pattern += extra
                ns_converters.update(resolver.pattern.converters)
            except KeyError as key:
                if resolved_path:
                    raise NoReverseMatch(
                        "%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())
            )

    return resolver._reverse_with_prefix(view, prefix, *args, **kwargs)


reverse_lazy = lazy(reverse, str)


def clear_url_caches():
    get_callable.cache_clear()
    _get_cached_resolver.cache_clear()
    get_ns_resolver.cache_clear()


def set_script_prefix(prefix):
    
    if not prefix.endswith("/"):
        prefix += "/"
    _prefixes.value = prefix


def get_script_prefix():
    
    return getattr(_prefixes, "value", "/")


def clear_script_prefix():
    
    try:
        del _prefixes.value
    except AttributeError:
        pass


def set_urlconf(urlconf_name):
    
    if urlconf_name:
        _urlconfs.value = urlconf_name
    else:
        if hasattr(_urlconfs, "value"):
            del _urlconfs.value


def get_urlconf(default=None):
    
    return getattr(_urlconfs, "value", default)


def is_valid_path(path, urlconf=None):
    
    try:
        return resolve(path, urlconf)
    except Resolver404:
        return False


def translate_url(url, lang_code):
    
    parsed = urlsplit(url)
    try:
        
        match = resolve(unquote(parsed.path))
    except Resolver404:
        pass
    else:
        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)
                )
    return url