Skip to content
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

Merged
merged 1 commit into from Sep 3, 2018

Conversation

darvid7
Copy link
Contributor

@darvid7 darvid7 commented Aug 27, 2018

This PR adds a check to warn if the LANGUAGE_CODE in settings.py does not use the standard language id format. Ticket 29713

  • included test cases
  • updated docs

@darvid7 darvid7 force-pushed the pycon branch 8 times, most recently from ccfa84b to ffc605f Compare August 27, 2018 04:41
Copy link
Contributor

@LilyFoote LilyFoote left a 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.

match_result = re.match(LANGUAGE_CODE_PATTERN, settings.LANGUAGE_CODE)
errors = []
if not match_result:
errors.append(Warning(
Copy link
Contributor

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.

Copy link
Contributor Author

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"
Copy link
Contributor

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.

Copy link
Contributor Author

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:
Copy link
Contributor

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.

Copy link
Contributor Author

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')
Copy link
Contributor

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?

Copy link
Contributor Author

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.

@darvid7 darvid7 force-pushed the pycon branch 4 times, most recently from 0512d64 to d25cf53 Compare August 27, 2018 06:57
Copy link
Contributor

@LilyFoote LilyFoote left a 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):
Copy link
Contributor

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.

Copy link
Contributor Author

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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer self.assertIsNone(matches)

Copy link
Contributor Author

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"
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Contributor

@LilyFoote LilyFoote left a 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.

@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
Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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?

@darvid7 darvid7 force-pushed the pycon branch 4 times, most recently from 7f2c2ee to 0fefa15 Compare August 28, 2018 00:04
@darvid7
Copy link
Contributor Author

darvid7 commented Aug 28, 2018

@Ian-Foote Please take another look.
I've updated the regex to use language_code_re in utils.translations.trans_real.py that I think checks for a more comprehensive set of LANGUAGE_CODEs.

Copy link
Contributor

@LilyFoote LilyFoote left a 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.

Copy link
Member

@carltongibson carltongibson left a 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!)

@@ -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
Copy link
Member

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.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@@ -16,6 +16,7 @@ class Tags:
signals = 'signals'
templates = 'templates'
urls = 'urls'
translation = 'translation'
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@carltongibson
Copy link
Member

Super stuff. Thanks @darvid7! Welcome aboard. 🎉

@darvid7
Copy link
Contributor Author

darvid7 commented Sep 3, 2018

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
Copy link
Member

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 "
Copy link
Member

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)
Copy link
Member

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",
Copy link
Member

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),
Copy link
Member

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>``.
Copy link
Member

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

Copy link
Member

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")
Copy link
Member

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)
Copy link
Member

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')
Copy link
Member

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.

@ngnpope
Copy link
Member

ngnpope commented Sep 4, 2018

@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.

@darvid7
Copy link
Contributor Author

darvid7 commented Sep 4, 2018

@timgraham @pope1ni thanks for your feedback, should I make another PR to address the changes or should I leave it up to #10367

@ngnpope
Copy link
Member

ngnpope commented Sep 4, 2018

Hi David. I'd leave it up to #10367 as I believe everything is addressed there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants