Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/django/template/utils.py: 83%

56 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1import functools 

2from collections import Counter 

3from pathlib import Path 

4 

5from django.apps import apps 

6from django.conf import settings 

7from django.core.exceptions import ImproperlyConfigured 

8from django.utils.functional import cached_property 

9from django.utils.module_loading import import_string 

10 

11 

12class InvalidTemplateEngineError(ImproperlyConfigured): 

13 pass 

14 

15 

16class EngineHandler: 

17 def __init__(self, templates=None): 

18 """ 

19 templates is an optional list of template engine definitions 

20 (structured like settings.TEMPLATES). 

21 """ 

22 self._templates = templates 

23 self._engines = {} 

24 

25 @cached_property 

26 def templates(self): 

27 if self._templates is None: 27 ↛ 30line 27 didn't jump to line 30, because the condition on line 27 was never false

28 self._templates = settings.TEMPLATES 

29 

30 templates = {} 

31 backend_names = [] 

32 for tpl in self._templates: 

33 try: 

34 # This will raise an exception if 'BACKEND' doesn't exist or 

35 # isn't a string containing at least one dot. 

36 default_name = tpl["BACKEND"].rsplit(".", 2)[-2] 

37 except Exception: 

38 invalid_backend = tpl.get("BACKEND", "<not defined>") 

39 raise ImproperlyConfigured( 

40 "Invalid BACKEND for a template engine: {}. Check " 

41 "your TEMPLATES setting.".format(invalid_backend) 

42 ) 

43 

44 tpl = { 

45 "NAME": default_name, 

46 "DIRS": [], 

47 "APP_DIRS": False, 

48 "OPTIONS": {}, 

49 **tpl, 

50 } 

51 

52 templates[tpl["NAME"]] = tpl 

53 backend_names.append(tpl["NAME"]) 

54 

55 counts = Counter(backend_names) 

56 duplicates = [alias for alias, count in counts.most_common() if count > 1] 

57 if duplicates: 57 ↛ 58line 57 didn't jump to line 58, because the condition on line 57 was never true

58 raise ImproperlyConfigured( 

59 "Template engine aliases aren't unique, duplicates: {}. " 

60 "Set a unique NAME for each engine in settings.TEMPLATES.".format( 

61 ", ".join(duplicates) 

62 ) 

63 ) 

64 

65 return templates 

66 

67 def __getitem__(self, alias): 

68 try: 

69 return self._engines[alias] 

70 except KeyError: 

71 try: 

72 params = self.templates[alias] 

73 except KeyError: 

74 raise InvalidTemplateEngineError( 

75 "Could not find config for '{}' " 

76 "in settings.TEMPLATES".format(alias) 

77 ) 

78 

79 # If importing or initializing the backend raises an exception, 

80 # self._engines[alias] isn't set and this code may get executed 

81 # again, so we must preserve the original params. See #24265. 

82 params = params.copy() 

83 backend = params.pop("BACKEND") 

84 engine_cls = import_string(backend) 

85 engine = engine_cls(params) 

86 

87 self._engines[alias] = engine 

88 return engine 

89 

90 def __iter__(self): 

91 return iter(self.templates) 

92 

93 def all(self): 

94 return [self[alias] for alias in self] 

95 

96 

97@functools.lru_cache() 

98def get_app_template_dirs(dirname): 

99 """ 

100 Return an iterable of paths of directories to load app templates from. 

101 

102 dirname is the name of the subdirectory containing templates inside 

103 installed applications. 

104 """ 

105 template_dirs = [ 

106 Path(app_config.path) / dirname 

107 for app_config in apps.get_app_configs() 

108 if app_config.path and (Path(app_config.path) / dirname).is_dir() 

109 ] 

110 # Immutable return value because it will be cached and shared by callers. 

111 return tuple(template_dirs)