Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/django/urls/base.py: 58%
96 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1from urllib.parse import unquote, urlsplit, urlunsplit
3from asgiref.local import Local
5from django.utils.functional import lazy
6from django.utils.translation import override
8from .exceptions import NoReverseMatch, Resolver404
9from .resolvers import _get_cached_resolver, get_ns_resolver, get_resolver
10from .utils import get_callable
12# SCRIPT_NAME prefixes for each thread are stored here. If there's no entry for
13# the current thread (which is the only one we ever access), it is assumed to
14# be empty.
15_prefixes = Local()
17# Overridden URLconfs for each thread are stored here.
18_urlconfs = Local()
21def resolve(path, urlconf=None):
22 if urlconf is None:
23 urlconf = get_urlconf()
24 return get_resolver(urlconf).resolve(path)
27def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None):
28 if urlconf is None: 28 ↛ 30line 28 didn't jump to line 30, because the condition on line 28 was never false
29 urlconf = get_urlconf()
30 resolver = get_resolver(urlconf)
31 args = args or []
32 kwargs = kwargs or {}
34 prefix = get_script_prefix()
36 if not isinstance(viewname, str): 36 ↛ 37line 36 didn't jump to line 37, because the condition on line 36 was never true
37 view = viewname
38 else:
39 *path, view = viewname.split(":")
41 if current_app: 41 ↛ 42line 41 didn't jump to line 42, because the condition on line 41 was never true
42 current_path = current_app.split(":")
43 current_path.reverse()
44 else:
45 current_path = None
47 resolved_path = []
48 ns_pattern = ""
49 ns_converters = {}
50 for ns in path:
51 current_ns = current_path.pop() if current_path else None
52 # Lookup the name to see if it could be an app identifier.
53 try:
54 app_list = resolver.app_dict[ns]
55 # Yes! Path part matches an app in the current Resolver.
56 if current_ns and current_ns in app_list: 56 ↛ 59line 56 didn't jump to line 59, because the condition on line 56 was never true
57 # If we are reversing for a particular app, use that
58 # namespace.
59 ns = current_ns
60 elif ns not in app_list: 60 ↛ 63line 60 didn't jump to line 63, because the condition on line 60 was never true
61 # The name isn't shared by one of the instances (i.e.,
62 # the default) so pick the first instance as the default.
63 ns = app_list[0]
64 except KeyError:
65 pass
67 if ns != current_ns: 67 ↛ 70line 67 didn't jump to line 70, because the condition on line 67 was never false
68 current_path = None
70 try:
71 extra, resolver = resolver.namespace_dict[ns]
72 resolved_path.append(ns)
73 ns_pattern = ns_pattern + extra
74 ns_converters.update(resolver.pattern.converters)
75 except KeyError as key:
76 if resolved_path:
77 raise NoReverseMatch(
78 "%s is not a registered namespace inside '%s'"
79 % (key, ":".join(resolved_path))
80 )
81 else:
82 raise NoReverseMatch("%s is not a registered namespace" % key)
83 if ns_pattern:
84 resolver = get_ns_resolver(
85 ns_pattern, resolver, tuple(ns_converters.items())
86 )
88 return resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
91reverse_lazy = lazy(reverse, str)
94def clear_url_caches():
95 get_callable.cache_clear()
96 _get_cached_resolver.cache_clear()
97 get_ns_resolver.cache_clear()
100def set_script_prefix(prefix):
101 """
102 Set the script prefix for the current thread.
103 """
104 if not prefix.endswith("/"): 104 ↛ 105line 104 didn't jump to line 105, because the condition on line 104 was never true
105 prefix += "/"
106 _prefixes.value = prefix
109def get_script_prefix():
110 """
111 Return the currently active script prefix. Useful for client code that
112 wishes to construct their own URLs manually (although accessing the request
113 instance is normally going to be a lot cleaner).
114 """
115 return getattr(_prefixes, "value", "/")
118def clear_script_prefix():
119 """
120 Unset the script prefix for the current thread.
121 """
122 try:
123 del _prefixes.value
124 except AttributeError:
125 pass
128def set_urlconf(urlconf_name):
129 """
130 Set the URLconf for the current thread (overriding the default one in
131 settings). If urlconf_name is None, revert back to the default.
132 """
133 if urlconf_name:
134 _urlconfs.value = urlconf_name
135 else:
136 if hasattr(_urlconfs, "value"): 136 ↛ exitline 136 didn't return from function 'set_urlconf', because the condition on line 136 was never false
137 del _urlconfs.value
140def get_urlconf(default=None):
141 """
142 Return the root URLconf to use for the current thread if it has been
143 changed from the default one.
144 """
145 return getattr(_urlconfs, "value", default)
148def is_valid_path(path, urlconf=None):
149 """
150 Return the ResolverMatch if the given path resolves against the default URL
151 resolver, False otherwise. This is a convenience method to make working
152 with "is this a match?" cases easier, avoiding try...except blocks.
153 """
154 try:
155 return resolve(path, urlconf)
156 except Resolver404:
157 return False
160def translate_url(url, lang_code):
161 """
162 Given a URL (absolute or relative), try to get its translated version in
163 the `lang_code` language (either by i18n_patterns or by translated regex).
164 Return the original URL if no translated version is found.
165 """
166 parsed = urlsplit(url)
167 try:
168 # URL may be encoded.
169 match = resolve(unquote(parsed.path))
170 except Resolver404:
171 pass
172 else:
173 to_be_reversed = (
174 "%s:%s" % (match.namespace, match.url_name)
175 if match.namespace
176 else match.url_name
177 )
178 with override(lang_code):
179 try:
180 url = reverse(to_be_reversed, args=match.args, kwargs=match.kwargs)
181 except NoReverseMatch:
182 pass
183 else:
184 url = urlunsplit(
185 (parsed.scheme, parsed.netloc, url, parsed.query, parsed.fragment)
186 )
187 return url