diff --git a/django/core/checks/translation.py b/django/core/checks/translation.py index 5c183aad2d3..cf69a5c084a 100644 --- a/django/core/checks/translation.py +++ b/django/core/checks/translation.py @@ -1,25 +1,19 @@ -import re - from django.conf import settings from django.utils.translation.trans_real import language_code_re from . import Error, Tags, register +E001 = Error( + 'You have provided an invalid value for the LANGUAGE_CODE setting.', + id='translation.E001', +) + @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 + Errors if language code setting is invalid. """ - 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 + if not language_code_re.match(settings.LANGUAGE_CODE): + return [E001] + return [] diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index 734381e2b85..9c149d46507 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -85,8 +85,8 @@ Django's system checks are organized using the following tags: * ``signals``: Checks on signal declarations and handler registrations. * ``staticfiles``: Checks :mod:`django.contrib.staticfiles` configuration. * ``templates``: Checks template related configuration. +* ``translation``: Checks translation related configuration. * ``urls``: Checks URL configuration. -* ``translation``: Checks language formats used for translation. Some checks may be registered with multiple tags. @@ -427,6 +427,14 @@ configured: :setting:`OPTIONS ` must be a string but got: ``{value}`` (``{type}``). +Translation +----------- + +The following checks are performed on your translation configuration: + +* **translation.E001**: You have provided an invalid value for the + :setting:`LANGUAGE_CODE` setting. + URLs ---- @@ -450,18 +458,6 @@ 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 ````. - 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 index 9ff698c29fd..8b8757c54e6 100644 --- a/tests/check_framework/test_translation.py +++ b/tests/check_framework/test_translation.py @@ -1,39 +1,41 @@ -from django.core.checks.translation import check_setting_language_code +from django.core.checks.translation import E001, 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) + def test_valid_language_code(self): + tags = ( + 'en', # language + 'mas', # language + 'sgn-ase', # language+extlang + 'fr-CA', # language+region + 'es-419', # language+region + 'zh-Hans', # language+script + 'ca-ES-valencia', # language+region+variant + # FIXME: The following should be invalid: + 'sr@latin', # language+script + ) + for tag in tags: + with self.subTest(tag), override_settings(LANGUAGE_CODE=tag): + self.assertEqual(check_setting_language_code(None), []) - @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" - )) + def test_invalid_language_code(self): + tags = ( + 'eü', # non-latin characters. + 'en_US', # locale format. + 'en--us', # empty subtag. + '-en', # leading separator. + 'en-', # trailing separator. + 'en-US.UTF-8', # language tag w/ locale encoding. + 'en_US.UTF-8', # locale format - languate w/ region and encoding. + 'ca_ES@valencia', # locale format - language w/ region and variant. + # FIXME: The following should be invalid: + # 'sr@latin', # locale instead of language tag. + ) + for tag in tags: + with self.subTest(tag), override_settings(LANGUAGE_CODE=tag): + result = check_setting_language_code(None) + self.assertEqual(result, [E001]) + self.assertEqual(result[0].id, 'translation.E001') + self.assertEqual(result[0].msg, 'You have provided an invalid value for the LANGUAGE_CODE setting.')