summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShreya Bamne <shreya.bamne@gmail.com>2021-08-03 15:20:49 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-10-20 11:15:47 +0200
commit004b4620f6f4ad87261e149898940f2dcd5757ef (patch)
tree233f505d749bbd26208bc5b6236df629942ec5fe
parentb98394fa62753c867a287c2839696695557281a5 (diff)
Fixed #32987 -- Added system check for template tag modules with the same name.
Co-authored-by: Daniel Fairhead <daniel@dev.ngo>
-rw-r--r--AUTHORS2
-rw-r--r--django/core/checks/templates.py32
-rw-r--r--docs/ref/checks.txt2
-rw-r--r--tests/check_framework/template_test_apps/__init__.py0
-rw-r--r--tests/check_framework/template_test_apps/different_tags_app/__init__.py0
-rw-r--r--tests/check_framework/template_test_apps/different_tags_app/apps.py5
-rw-r--r--tests/check_framework/template_test_apps/different_tags_app/templatetags/__init__.py0
-rw-r--r--tests/check_framework/template_test_apps/different_tags_app/templatetags/different_tags.py3
-rw-r--r--tests/check_framework/template_test_apps/same_tags_app_1/__init__.py0
-rw-r--r--tests/check_framework/template_test_apps/same_tags_app_1/apps.py5
-rw-r--r--tests/check_framework/template_test_apps/same_tags_app_1/templatetags/__init__.py0
-rw-r--r--tests/check_framework/template_test_apps/same_tags_app_1/templatetags/same_tags.py3
-rw-r--r--tests/check_framework/template_test_apps/same_tags_app_2/__init__.py0
-rw-r--r--tests/check_framework/template_test_apps/same_tags_app_2/apps.py5
-rw-r--r--tests/check_framework/template_test_apps/same_tags_app_2/templatetags/__init__.py0
-rw-r--r--tests/check_framework/template_test_apps/same_tags_app_2/templatetags/same_tags.py3
-rw-r--r--tests/check_framework/test_templates.py87
17 files changed, 145 insertions, 2 deletions
diff --git a/AUTHORS b/AUTHORS
index 55e6579840..01adc8575a 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -223,6 +223,7 @@ answer newbie questions, and generally made Django that much better:
Daniel Alves Barbosa de Oliveira Vaz <danielvaz@gmail.com>
Daniel Duan <DaNmarner@gmail.com>
Daniele Procida <daniele@vurt.org>
+ Daniel Fairhead <danthedeckie@gmail.com>
Daniel Greenfeld
dAniel hAhler
Daniel Jilg <daniel@breakthesystem.org>
@@ -860,6 +861,7 @@ answer newbie questions, and generally made Django that much better:
Shai Berger <shai@platonix.com>
Shannon -jj Behrens <https://www.jjinux.com/>
Shawn Milochik <shawn@milochik.com>
+ Shreya Bamne <shreya.bamne@gmail.com>
Silvan Spross <silvan.spross@gmail.com>
Simeon Visser <http://simeonvisser.com>
Simon Blanchard
diff --git a/django/core/checks/templates.py b/django/core/checks/templates.py
index 8c4b7c172b..14325bd3e0 100644
--- a/django/core/checks/templates.py
+++ b/django/core/checks/templates.py
@@ -1,6 +1,8 @@
import copy
+from collections import defaultdict
from django.conf import settings
+from django.template.backends.django import get_template_tag_modules
from . import Error, Tags, register
@@ -13,6 +15,10 @@ E002 = Error(
"'string_if_invalid' in TEMPLATES OPTIONS must be a string but got: {} ({}).",
id="templates.E002",
)
+E003 = Error(
+ '{} is used for multiple template tag modules: {}',
+ id='templates.E003',
+)
@register(Tags.templates)
@@ -33,3 +39,29 @@ def check_string_if_invalid_is_string(app_configs, **kwargs):
error.msg = error.msg.format(string_if_invalid, type(string_if_invalid).__name__)
errors.append(error)
return errors
+
+
+@register(Tags.templates)
+def check_for_template_tags_with_the_same_name(app_configs, **kwargs):
+ errors = []
+ libraries = defaultdict(list)
+
+ for conf in settings.TEMPLATES:
+ custom_libraries = conf.get('OPTIONS', {}).get('libraries', {})
+ for module_name, module_path in custom_libraries.items():
+ libraries[module_name].append(module_path)
+
+ for module_name, module_path in get_template_tag_modules():
+ libraries[module_name].append(module_path)
+
+ for library_name, items in libraries.items():
+ if len(items) > 1:
+ errors.append(Error(
+ E003.msg.format(
+ repr(library_name),
+ ', '.join(repr(item) for item in items),
+ ),
+ id=E003.id,
+ ))
+
+ return errors
diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt
index 727d16b772..6c95b9376d 100644
--- a/docs/ref/checks.txt
+++ b/docs/ref/checks.txt
@@ -541,6 +541,8 @@ configured:
* **templates.E002**: ``string_if_invalid`` in :setting:`TEMPLATES`
:setting:`OPTIONS <TEMPLATES-OPTIONS>` must be a string but got: ``{value}``
(``{type}``).
+* **templates.E003**:``<name>`` is used for multiple template tag modules:
+ ``<module list>``.
Translation
-----------
diff --git a/tests/check_framework/template_test_apps/__init__.py b/tests/check_framework/template_test_apps/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/check_framework/template_test_apps/__init__.py
diff --git a/tests/check_framework/template_test_apps/different_tags_app/__init__.py b/tests/check_framework/template_test_apps/different_tags_app/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/check_framework/template_test_apps/different_tags_app/__init__.py
diff --git a/tests/check_framework/template_test_apps/different_tags_app/apps.py b/tests/check_framework/template_test_apps/different_tags_app/apps.py
new file mode 100644
index 0000000000..90d54b3d50
--- /dev/null
+++ b/tests/check_framework/template_test_apps/different_tags_app/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class DifferentTagsAppAppConfig(AppConfig):
+ name = 'check_framework.template_test_apps.different_tags_app'
diff --git a/tests/check_framework/template_test_apps/different_tags_app/templatetags/__init__.py b/tests/check_framework/template_test_apps/different_tags_app/templatetags/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/check_framework/template_test_apps/different_tags_app/templatetags/__init__.py
diff --git a/tests/check_framework/template_test_apps/different_tags_app/templatetags/different_tags.py b/tests/check_framework/template_test_apps/different_tags_app/templatetags/different_tags.py
new file mode 100644
index 0000000000..9bec93d8e5
--- /dev/null
+++ b/tests/check_framework/template_test_apps/different_tags_app/templatetags/different_tags.py
@@ -0,0 +1,3 @@
+from django.template import Library
+
+register = Library()
diff --git a/tests/check_framework/template_test_apps/same_tags_app_1/__init__.py b/tests/check_framework/template_test_apps/same_tags_app_1/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/check_framework/template_test_apps/same_tags_app_1/__init__.py
diff --git a/tests/check_framework/template_test_apps/same_tags_app_1/apps.py b/tests/check_framework/template_test_apps/same_tags_app_1/apps.py
new file mode 100644
index 0000000000..44149177a0
--- /dev/null
+++ b/tests/check_framework/template_test_apps/same_tags_app_1/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class SameTagsApp1AppConfig(AppConfig):
+ name = 'check_framework.template_test_apps.same_tags_app_1'
diff --git a/tests/check_framework/template_test_apps/same_tags_app_1/templatetags/__init__.py b/tests/check_framework/template_test_apps/same_tags_app_1/templatetags/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/check_framework/template_test_apps/same_tags_app_1/templatetags/__init__.py
diff --git a/tests/check_framework/template_test_apps/same_tags_app_1/templatetags/same_tags.py b/tests/check_framework/template_test_apps/same_tags_app_1/templatetags/same_tags.py
new file mode 100644
index 0000000000..9bec93d8e5
--- /dev/null
+++ b/tests/check_framework/template_test_apps/same_tags_app_1/templatetags/same_tags.py
@@ -0,0 +1,3 @@
+from django.template import Library
+
+register = Library()
diff --git a/tests/check_framework/template_test_apps/same_tags_app_2/__init__.py b/tests/check_framework/template_test_apps/same_tags_app_2/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/check_framework/template_test_apps/same_tags_app_2/__init__.py
diff --git a/tests/check_framework/template_test_apps/same_tags_app_2/apps.py b/tests/check_framework/template_test_apps/same_tags_app_2/apps.py
new file mode 100644
index 0000000000..d90c800d1f
--- /dev/null
+++ b/tests/check_framework/template_test_apps/same_tags_app_2/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class SameTagsApp2AppConfig(AppConfig):
+ name = 'check_framework.template_test_apps.same_tags_app_2'
diff --git a/tests/check_framework/template_test_apps/same_tags_app_2/templatetags/__init__.py b/tests/check_framework/template_test_apps/same_tags_app_2/templatetags/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/check_framework/template_test_apps/same_tags_app_2/templatetags/__init__.py
diff --git a/tests/check_framework/template_test_apps/same_tags_app_2/templatetags/same_tags.py b/tests/check_framework/template_test_apps/same_tags_app_2/templatetags/same_tags.py
new file mode 100644
index 0000000000..9bec93d8e5
--- /dev/null
+++ b/tests/check_framework/template_test_apps/same_tags_app_2/templatetags/same_tags.py
@@ -0,0 +1,3 @@
+from django.template import Library
+
+register = Library()
diff --git a/tests/check_framework/test_templates.py b/tests/check_framework/test_templates.py
index 955c863822..88c0479436 100644
--- a/tests/check_framework/test_templates.py
+++ b/tests/check_framework/test_templates.py
@@ -1,8 +1,9 @@
from copy import copy, deepcopy
+from django.core.checks import Error
from django.core.checks.templates import (
- E001, E002, check_setting_app_dirs_loaders,
- check_string_if_invalid_is_string,
+ E001, E002, E003, check_for_template_tags_with_the_same_name,
+ check_setting_app_dirs_loaders, check_string_if_invalid_is_string,
)
from django.test import SimpleTestCase
from django.test.utils import override_settings
@@ -87,3 +88,85 @@ class CheckTemplateStringIfInvalidTest(SimpleTestCase):
del TEMPLATES[1]['OPTIONS']['string_if_invalid']
with self.settings(TEMPLATES=TEMPLATES):
self.assertEqual(check_string_if_invalid_is_string(None), [self.error1])
+
+
+class CheckTemplateTagLibrariesWithSameName(SimpleTestCase):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ cls.error_same_tags = Error(
+ E003.msg.format(
+ "'same_tags'",
+ "'check_framework.template_test_apps.same_tags_app_1."
+ "templatetags.same_tags', "
+ "'check_framework.template_test_apps.same_tags_app_2."
+ "templatetags.same_tags'",
+ ),
+ id=E003.id,
+ )
+
+ @staticmethod
+ def get_settings(module_name, module_path):
+ return {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'OPTIONS': {
+ 'libraries': {
+ module_name: f'check_framework.template_test_apps.{module_path}',
+ },
+ },
+ }
+
+ @override_settings(INSTALLED_APPS=[
+ 'check_framework.template_test_apps.same_tags_app_1',
+ 'check_framework.template_test_apps.same_tags_app_2',
+ ])
+ def test_template_tags_with_same_name(self):
+ self.assertEqual(
+ check_for_template_tags_with_the_same_name(None),
+ [self.error_same_tags],
+ )
+
+ def test_template_tags_with_same_library_name(self):
+ with self.settings(TEMPLATES=[
+ self.get_settings('same_tags', 'same_tags_app_1.templatetags.same_tags'),
+ self.get_settings('same_tags', 'same_tags_app_2.templatetags.same_tags'),
+ ]):
+ self.assertEqual(
+ check_for_template_tags_with_the_same_name(None),
+ [self.error_same_tags],
+ )
+
+ @override_settings(INSTALLED_APPS=[
+ 'check_framework.template_test_apps.same_tags_app_1'
+ ])
+ def test_template_tags_with_same_library_name_and_module_name(self):
+ with self.settings(TEMPLATES=[
+ self.get_settings(
+ 'same_tags',
+ 'different_tags_app.templatetags.different_tags',
+ ),
+ ]):
+ self.assertEqual(check_for_template_tags_with_the_same_name(None), [Error(
+ E003.msg.format(
+ "'same_tags'",
+ "'check_framework.template_test_apps.different_tags_app."
+ "templatetags.different_tags', "
+ "'check_framework.template_test_apps.same_tags_app_1."
+ "templatetags.same_tags'",
+ ),
+ id=E003.id,
+ )])
+
+ def test_template_tags_with_different_library_name(self):
+ with self.settings(TEMPLATES=[
+ self.get_settings('same_tags', 'same_tags_app_1.templatetags.same_tags'),
+ self.get_settings('not_same_tags', 'same_tags_app_2.templatetags.same_tags'),
+ ]):
+ self.assertEqual(check_for_template_tags_with_the_same_name(None), [])
+
+ @override_settings(INSTALLED_APPS=[
+ 'check_framework.template_test_apps.same_tags_app_1',
+ 'check_framework.template_test_apps.different_tags_app',
+ ])
+ def test_template_tags_with_different_name(self):
+ self.assertEqual(check_for_template_tags_with_the_same_name(None), [])