New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed #29713 -- Added a check to warn if LANGUAGE_CODE does not use the standard language id format #10340
Conversation
ccfa84b
to
ffc605f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good start. There's a few things I think can be improved.
django/core/checks/translation.py
Outdated
match_result = re.match(LANGUAGE_CODE_PATTERN, settings.LANGUAGE_CODE) | ||
errors = [] | ||
if not match_result: | ||
errors.append(Warning( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd make this an Error
- I don't think translation works at all if this is wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done 👍
|
||
@override_settings(ROOT_URLCONF='check_framework.translation.valid_language_code_format_ll_only') | ||
def test_valid_language_code_format_ll_only(self): | ||
settings.LANGUAGE_CODE = "en" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it work if you use override_settings
for this too? That would be cleaner.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes test work fine without it.
@override_settings(ROOT_URLCONF='check_framework.translation.invalid_language_code_format_ll_only') | ||
def test_invalid_language_code_format_ll_only(self): | ||
invalid_codes = ["EN", "eN"] | ||
for code in invalid_codes: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure there's much value in testing two invalid codes instead of just one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair point, test one value in TranslationCheckTests
. Added TranslationLanguageCodeRegexTest
to test regex using subTest()
|
||
class TranslationCheckTests(SimpleTestCase): | ||
|
||
@override_settings(ROOT_URLCONF='check_framework.translation.valid_language_code_format_ll_only') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you override ROOT_URLCONF
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copied from other files, removed it.
0512d64
to
d25cf53
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a few more improvements that can still be made.
matches = re.match(LANGUAGE_CODE_PATTERN, lang_code) | ||
self.assertEqual(matches, None) | ||
|
||
def test_invalid_language_code_format_ll_cc(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can combine these tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
for lang_code in invalid_codes: | ||
with self.subTest(lang_code=lang_code): | ||
matches = re.match(LANGUAGE_CODE_PATTERN, lang_code) | ||
self.assertEqual(matches, None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer self.assertIsNone(matches)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
class TranslationCheckTests(SimpleTestCase): | ||
|
||
def test_valid_language_code_format_ll_only(self): | ||
settings.LANGUAGE_CODE = "en" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use override_settings
for this, to ensure we clean up after ourselves once the test is complete, avoiding breaking unrelated tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few nitpicks left. Looks good to me otherwise.
django/core/checks/translation.py
Outdated
@register(Tags.translation) | ||
def check_setting_language_code(app_configs, **kwargs): | ||
""" | ||
Warn if language code is in the wrong format. Language codes are generally represented in lower-case with a dash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The word generally
doesn't add any value in my opinion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not certain Warn
is the best word now that this is an Error
, but I'm not sure how to phrase it instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Errors if language code is in the wrong format
?
7f2c2ee
to
0fefa15
Compare
@Ian-Foote Please take another look. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still looks good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. Great. Thanks.
(Smallest of niggles... Ta!)
django/core/checks/__init__.py
Outdated
@@ -13,6 +13,7 @@ | |||
import django.core.checks.security.sessions # NOQA isort:skip | |||
import django.core.checks.templates # NOQA isort:skip | |||
import django.core.checks.urls # NOQA isort:skip | |||
import django.core.checks.translation # NOQA isort:skip |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move this above ...checks.urls
please?
(Presumably we're skipping isort here to stop it putting these imports amongst the other actual imports but they're alphabetical within that.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
django/core/checks/registry.py
Outdated
@@ -16,6 +16,7 @@ class Tags: | |||
signals = 'signals' | |||
templates = 'templates' | |||
urls = 'urls' | |||
translation = 'translation' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, I think keep alphabetical please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
standard language id format
Super stuff. Thanks @darvid7! Welcome aboard. 🎉 |
Thank you ^^ |
@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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please wrap docstrings at 79 characters. The second sentence is missing a period.
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 " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please wrap these lines at 79 characters.
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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure an intermediate variable is needed.
"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", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use single quotes (unless a string contains a single quote) as described in Python coding style.
"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), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
) goes on the next line.
|
||
The following checks are performed on your translation configuration: | ||
|
||
* **translation.E001**: LANGUAGE_CODE in settings.py is ``<language_code>``. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The :setting:`LANGUAGE_CODE` setting...
(not all projects use settings.py
)
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 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a single blank line between sections.
|
||
class TranslationCheckTests(SimpleTestCase): | ||
|
||
@override_settings(LANGUAGE_CODE="eu") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use single quotes.
@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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd go with assertEqual(check_setting_language_code(None), [])
. That's a bit easier to debug in the case of a failure since the error will be visible as opposed to just, e.g. 1 != 0.
result = check_setting_language_code(None) | ||
self.assertEqual(len(result), 1) | ||
error = result[0] | ||
self.assertEqual(error.id, 'translation.E001') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking it might be better to use the approach in test_caches.py
rather than repeating the error message here twice.
@timgraham - only just seen your review here. I worked on a follow up to this yesterday as I noticed many of the same issues highlighted in your review, but only just opened it this morning: #10367. Have updated it to incorporate some of the changes you requested that I missed. |
@timgraham @pope1ni thanks for your feedback, should I make another PR to address the changes or should I leave it up to #10367 |
Hi David. I'd leave it up to #10367 as I believe everything is addressed there. |
This PR adds a check to warn if the
LANGUAGE_CODE
insettings.py
does not use the standard language id format. Ticket 29713