Skip to content

Commit

Permalink
Fixed #29713 -- Added check that LANGUAGE_CODE uses standard language…
Browse files Browse the repository at this point in the history
… id format.
  • Loading branch information
darvid7 authored and carltongibson committed Sep 3, 2018
1 parent ee52044 commit 5db8d61
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 0 deletions.
1 change: 1 addition & 0 deletions django/core/checks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
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


Expand Down
1 change: 1 addition & 0 deletions django/core/checks/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class Tags:
security = 'security'
signals = 'signals'
templates = 'templates'
translation = 'translation'
urls = 'urls'


Expand Down
25 changes: 25 additions & 0 deletions django/core/checks/translation.py
Original file line number Diff line number Diff line change
@@ -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
13 changes: 13 additions & 0 deletions docs/ref/checks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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
======================

Expand Down
39 changes: 39 additions & 0 deletions tests/check_framework/test_translation.py
Original file line number Diff line number Diff line change
@@ -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"
))
1 change: 1 addition & 0 deletions tests/i18n/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1649,6 +1649,7 @@ def test_check_for_language(self):
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'))
Expand Down

0 comments on commit 5db8d61

Please sign in to comment.