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

1from collections import Counter 

2 

3from django.conf import settings 

4 

5from . import Error, Tags, Warning, register 

6 

7 

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 

12 

13 resolver = get_resolver() 

14 return check_resolver(resolver) 

15 return [] 

16 

17 

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 [] 

29 

30 

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 [] 

38 

39 from django.urls import get_resolver 

40 

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 

55 

56 

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 

74 

75 

76def get_warning_for_invalid_pattern(pattern): 

77 """ 

78 Return a list containing a warning that the pattern is invalid. 

79 

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 

92 

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 ] 

101 

102 

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 

111 

112 

113def E006(name): 

114 return Error( 

115 "The {} setting must end with a slash.".format(name), 

116 id="urls.E006", 

117 )