Plain is headed towards 1.0! Subscribe for development updates →

 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)