1from plain.utils.functional import lazy
2
3from .exceptions import NoReverseMatch
4from .resolvers import get_ns_resolver, get_resolver
5
6
7def reverse(url_name: str, *args, **kwargs):
8 resolver = get_resolver()
9
10 *path, view = url_name.split(":")
11
12 current_path = None
13
14 resolved_path = []
15 ns_pattern = ""
16 ns_converters = {}
17 for ns in path:
18 current_ns = current_path.pop() if current_path else None
19
20 if ns != current_ns:
21 current_path = None
22
23 try:
24 extra, resolver = resolver.namespace_dict[ns]
25 resolved_path.append(ns)
26 ns_pattern += extra
27 ns_converters.update(resolver.pattern.converters)
28 except KeyError as key:
29 if resolved_path:
30 raise NoReverseMatch(
31 "{} is not a registered namespace inside '{}'".format(
32 key, ":".join(resolved_path)
33 )
34 )
35 else:
36 raise NoReverseMatch(f"{key} is not a registered namespace")
37 if ns_pattern:
38 resolver = get_ns_resolver(ns_pattern, resolver, tuple(ns_converters.items()))
39
40 return resolver.reverse(view, *args, **kwargs)
41
42
43reverse_lazy = lazy(reverse, str)