Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/django/core/checks/urls.py: 70%
57 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 collections import Counter
3from django.conf import settings
5from . import Error, Tags, Warning, register
8@register(Tags.urls)
9def check_url_config(app_configs, **kwargs):
10 if getattr(settings, "ROOT_URLCONF", None): 10 ↛ 15line 10 didn't jump to line 15, because the condition on line 10 was never false
11 from django.urls import get_resolver
13 resolver = get_resolver()
14 return check_resolver(resolver)
15 return []
18def check_resolver(resolver):
19 """
20 Recursively check the resolver.
21 """
22 check_method = getattr(resolver, "check", None)
23 if check_method is not None: 23 ↛ 25line 23 didn't jump to line 25, because the condition on line 23 was never false
24 return check_method()
25 elif not hasattr(resolver, "resolve"):
26 return get_warning_for_invalid_pattern(resolver)
27 else:
28 return []
31@register(Tags.urls)
32def check_url_namespaces_unique(app_configs, **kwargs):
33 """
34 Warn if URL namespaces used in applications aren't unique.
35 """
36 if not getattr(settings, "ROOT_URLCONF", None): 36 ↛ 37line 36 didn't jump to line 37, because the condition on line 36 was never true
37 return []
39 from django.urls import get_resolver
41 resolver = get_resolver()
42 all_namespaces = _load_all_namespaces(resolver)
43 counter = Counter(all_namespaces)
44 non_unique_namespaces = [n for n, count in counter.items() if count > 1]
45 errors = []
46 for namespace in non_unique_namespaces: 46 ↛ 47line 46 didn't jump to line 47, because the loop on line 46 never started
47 errors.append(
48 Warning(
49 "URL namespace '{}' isn't unique. You may not be able to reverse "
50 "all URLs in this namespace".format(namespace),
51 id="urls.W005",
52 )
53 )
54 return errors
57def _load_all_namespaces(resolver, parents=()):
58 """
59 Recursively load all namespaces from URL patterns.
60 """
61 url_patterns = getattr(resolver, "url_patterns", [])
62 namespaces = [
63 ":".join(parents + (url.namespace,))
64 for url in url_patterns
65 if getattr(url, "namespace", None) is not None
66 ]
67 for pattern in url_patterns:
68 namespace = getattr(pattern, "namespace", None)
69 current = parents
70 if namespace is not None:
71 current += (namespace,)
72 namespaces.extend(_load_all_namespaces(pattern, current))
73 return namespaces
76def get_warning_for_invalid_pattern(pattern):
77 """
78 Return a list containing a warning that the pattern is invalid.
80 describe_pattern() cannot be used here, because we cannot rely on the
81 urlpattern having regex or name attributes.
82 """
83 if isinstance(pattern, str):
84 hint = (
85 "Try removing the string '{}'. The list of urlpatterns should not "
86 "have a prefix string as the first element.".format(pattern)
87 )
88 elif isinstance(pattern, tuple):
89 hint = "Try using path() instead of a tuple."
90 else:
91 hint = None
93 return [
94 Error(
95 "Your URL pattern {!r} is invalid. Ensure that urlpatterns is a list "
96 "of path() and/or re_path() instances.".format(pattern),
97 hint=hint,
98 id="urls.E004",
99 )
100 ]
103@register(Tags.urls)
104def check_url_settings(app_configs, **kwargs):
105 errors = []
106 for name in ("STATIC_URL", "MEDIA_URL"):
107 value = getattr(settings, name)
108 if value and not value.endswith("/"): 108 ↛ 109line 108 didn't jump to line 109, because the condition on line 108 was never true
109 errors.append(E006(name))
110 return errors
113def E006(name):
114 return Error(
115 "The {} setting must end with a slash.".format(name),
116 id="urls.E006",
117 )