summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid <david.anthony.lei@gmail.com>2018-09-03 18:43:55 +1000
committerCarlton Gibson <carlton.gibson@noumenal.es>2018-09-03 10:43:55 +0200
commit5db8d617c0a5b16fabe16d1d52b2f9db519d8bb6 (patch)
treef19bc95d9915224ca7522a3d4daeff0f2ee4856b
parentee52044a278885bd9455dd59b1e16c5d5e2d68ce (diff)
Fixed #29713 -- Added check that LANGUAGE_CODE uses standard language id format.
-rw-r--r--django/core/checks/__init__.py1
-rw-r--r--django/core/checks/registry.py1
-rw-r--r--django/core/checks/translation.py25
-rw-r--r--docs/ref/checks.txt13
-rw-r--r--tests/check_framework/test_translation.py39
-rw-r--r--tests/i18n/tests.py1
6 files changed, 80 insertions, 0 deletions
diff --git a/django/core/checks/__init__.py b/django/core/checks/__init__.py
index 8ef3f5db90..ededae38ba 100644
--- a/django/core/checks/__init__.py
+++ b/django/core/checks/__init__.py
@@ -12,6 +12,7 @@ import django.core.checks.security.base # NOQA isort:skip
import django.core.checks.security.csrf # NOQA isort:skip
import django.core.checks.security.sessions # NOQA isort:skip
import django.core.checks.templates # NOQA isort:skip
+import django.core.checks.translation # NOQA isort:skip
import django.core.checks.urls # NOQA isort:skip
diff --git a/django/core/checks/registry.py b/django/core/checks/registry.py
index 9660272d9b..51999bdf95 100644
--- a/django/core/checks/registry.py
+++ b/django/core/checks/registry.py
@@ -15,6 +15,7 @@ class Tags:
security = 'security'
signals = 'signals'
templates = 'templates'
+ translation = 'translation'
urls = 'urls'
diff --git a/django/core/checks/translation.py b/django/core/checks/translation.py
new file mode 100644
index 0000000000..5c183aad2d
--- /dev/null
+++ b/django/core/checks/translation.py
@@ -0,0 +1,25 @@
+import re
+
+from django.conf import settings
+from django.utils.translation.trans_real import language_code_re
+
+from . import Error, Tags, register
+
+
+@register(Tags.translation)
+def check_setting_language_code(app_configs, **kwargs):
+ """
+ Errors if language code is in the wrong format. Language codes specification outlined by
+ https://en.wikipedia.org/wiki/IETF_language_tag#Syntax_of_language_tags
+ """
+ match_result = re.match(language_code_re, settings.LANGUAGE_CODE)
+ errors = []
+ if not match_result:
+ errors.append(Error(
+ "LANGUAGE_CODE in settings.py is {}. It should be in the form ll or ll-cc where ll is the language and cc "
+ "is the country. Examples include: it, de-at, es, pt-br. The full set of language codes specifications is "
+ "outlined by https://en.wikipedia.org/wiki/IETF_language_tag#Syntax_of_language_tags".format(
+ settings.LANGUAGE_CODE),
+ id="translation.E001",
+ ))
+ return errors
diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt
index 42296f65c9..734381e2b8 100644
--- a/docs/ref/checks.txt
+++ b/docs/ref/checks.txt
@@ -86,6 +86,7 @@ Django's system checks are organized using the following tags:
* ``staticfiles``: Checks :mod:`django.contrib.staticfiles` configuration.
* ``templates``: Checks template related configuration.
* ``urls``: Checks URL configuration.
+* ``translation``: Checks language formats used for translation.
Some checks may be registered with multiple tags.
@@ -449,6 +450,18 @@ The following checks are performed on your URL configuration:
* **urls.E006**: The :setting:`MEDIA_URL`/ :setting:`STATIC_URL` setting must
end with a slash.
+Translation
+-----------
+
+The following checks are performed on your translation configuration:
+
+* **translation.E001**: LANGUAGE_CODE in settings.py is ``<language_code>``.
+ It should be in the form ll or ll-cc where ll is the language and cc is the
+ country. Examples include: ``it``, ``de-at``, ``es``, ``pt-br``. The full
+ set of language codes specifications is outlined by
+ https://en.wikipedia.org/wiki/IETF_language_tag#Syntax_of_language_tags
+
+
``contrib`` app checks
======================
diff --git a/tests/check_framework/test_translation.py b/tests/check_framework/test_translation.py
new file mode 100644
index 0000000000..9ff698c29f
--- /dev/null
+++ b/tests/check_framework/test_translation.py
@@ -0,0 +1,39 @@
+from django.core.checks.translation import check_setting_language_code
+from django.test import SimpleTestCase, override_settings
+
+
+class TranslationCheckTests(SimpleTestCase):
+
+ @override_settings(LANGUAGE_CODE="eu")
+ def test_valid_language_code_format_ll_only(self):
+ result = check_setting_language_code(None)
+ self.assertEqual(len(result), 0)
+
+ @override_settings(LANGUAGE_CODE="eü")
+ def test_invalid_language_code_format_ll_only(self):
+ result = check_setting_language_code(None)
+ self.assertEqual(len(result), 1)
+ error = result[0]
+ self.assertEqual(error.id, 'translation.E001')
+ self.assertEqual(error.msg, (
+ "LANGUAGE_CODE in settings.py is eü. It should be in the form ll or ll-cc where ll is the language and cc "
+ "is the country. Examples include: it, de-at, es, pt-br. The full set of language codes specifications is "
+ "outlined by https://en.wikipedia.org/wiki/IETF_language_tag#Syntax_of_language_tags"
+ ))
+
+ @override_settings(LANGUAGE_CODE="en-US")
+ def test_valid_language_code_format_ll_cc(self):
+ result = check_setting_language_code(None)
+ self.assertEqual(len(result), 0)
+
+ @override_settings(LANGUAGE_CODE="en_US")
+ def test_invalid_language_code_format_ll_cc(self):
+ result = check_setting_language_code(None)
+ self.assertEqual(len(result), 1)
+ error = result[0]
+ self.assertEqual(error.id, 'translation.E001')
+ self.assertEqual(error.msg, (
+ "LANGUAGE_CODE in settings.py is en_US. It should be in the form ll or ll-cc where ll is the language and "
+ "cc is the country. Examples include: it, de-at, es, pt-br. The full set of language codes specifications "
+ "is outlined by https://en.wikipedia.org/wiki/IETF_language_tag#Syntax_of_language_tags"
+ ))
diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py
index 5d76e26653..c9d4ecde28 100644
--- a/tests/i18n/tests.py
+++ b/tests/i18n/tests.py
@@ -1649,6 +1649,7 @@ class CountrySpecificLanguageTests(SimpleTestCase):
self.assertTrue(check_for_language('en'))
self.assertTrue(check_for_language('en-us'))
self.assertTrue(check_for_language('en-US'))
+ self.assertFalse(check_for_language('en_US'))
self.assertTrue(check_for_language('be'))
self.assertTrue(check_for_language('be@latin'))
self.assertTrue(check_for_language('sr-RS@latin'))