summaryrefslogtreecommitdiff
path: root/tests/i18n
diff options
context:
space:
mode:
authordjango-bot <ops@djangoproject.com>2022-02-03 20:24:19 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-02-07 20:37:05 +0100
commit9c19aff7c7561e3a82978a272ecdaad40dda5c00 (patch)
treef0506b668a013d0063e5fba3dbf4863b466713ba /tests/i18n
parentf68fa8b45dfac545cfc4111d4e52804c86db68d3 (diff)
downloaddjango-9c19aff7c7561e3a82978a272ecdaad40dda5c00.tar.gz
Refs #33476 -- Reformatted code with Black.
Diffstat (limited to 'tests/i18n')
-rw-r--r--tests/i18n/commands/__init__.py9
-rw-r--r--tests/i18n/contenttypes/tests.py18
-rw-r--r--tests/i18n/forms.py2
-rw-r--r--tests/i18n/loading_app/apps.py2
-rw-r--r--tests/i18n/models.py4
-rw-r--r--tests/i18n/other/locale/fr/formats.py2
-rw-r--r--tests/i18n/patterns/tests.py376
-rw-r--r--tests/i18n/patterns/urls/default.py26
-rw-r--r--tests/i18n/patterns/urls/disabled.py4
-rw-r--r--tests/i18n/patterns/urls/included.py4
-rw-r--r--tests/i18n/patterns/urls/namespace.py10
-rw-r--r--tests/i18n/patterns/urls/path_unused.py4
-rw-r--r--tests/i18n/patterns/urls/wrong.py5
-rw-r--r--tests/i18n/patterns/urls/wrong_namespace.py6
-rwxr-xr-xtests/i18n/sampleproject/manage.py2
-rwxr-xr-xtests/i18n/sampleproject/update_catalogs.py12
-rw-r--r--tests/i18n/test_compilation.py214
-rw-r--r--tests/i18n/test_extraction.py657
-rw-r--r--tests/i18n/test_management.py30
-rw-r--r--tests/i18n/test_percents.py103
-rw-r--r--tests/i18n/tests.py1921
-rw-r--r--tests/i18n/unchanged/__init__.py4
-rw-r--r--tests/i18n/urls.py4
-rw-r--r--tests/i18n/urls_default_unprefixed.py6
-rw-r--r--tests/i18n/utils.py19
25 files changed, 2019 insertions, 1425 deletions
diff --git a/tests/i18n/commands/__init__.py b/tests/i18n/commands/__init__.py
index f0a06505de..e02ea47fff 100644
--- a/tests/i18n/commands/__init__.py
+++ b/tests/i18n/commands/__init__.py
@@ -1,4 +1,5 @@
-from django.utils.translation import gettext as _, ngettext
+from django.utils.translation import gettext as _
+from django.utils.translation import ngettext
# Translators: This comment should be extracted
dummy1 = _("This is a translatable string.")
@@ -9,9 +10,9 @@ dummy2 = _("This is another translatable string.")
# This file has a literal with plural forms. When processed first, makemessages
# shouldn't create a .po file with duplicate `Plural-Forms` headers
number = 3
-dummy3 = ngettext("%(number)s Foo", "%(number)s Foos", number) % {'number': number}
+dummy3 = ngettext("%(number)s Foo", "%(number)s Foos", number) % {"number": number}
-dummy4 = _('Size')
+dummy4 = _("Size")
# This string is intentionally duplicated in test.html
-dummy5 = _('This literal should be included.')
+dummy5 = _("This literal should be included.")
diff --git a/tests/i18n/contenttypes/tests.py b/tests/i18n/contenttypes/tests.py
index d23e2bdf56..22bbb5d834 100644
--- a/tests/i18n/contenttypes/tests.py
+++ b/tests/i18n/contenttypes/tests.py
@@ -8,18 +8,18 @@ from django.utils import translation
@override_settings(
USE_I18N=True,
LOCALE_PATHS=[
- os.path.join(os.path.dirname(__file__), 'locale'),
+ os.path.join(os.path.dirname(__file__), "locale"),
],
- LANGUAGE_CODE='en',
+ LANGUAGE_CODE="en",
LANGUAGES=[
- ('en', 'English'),
- ('fr', 'French'),
+ ("en", "English"),
+ ("fr", "French"),
],
)
class ContentTypeTests(TestCase):
def test_verbose_name(self):
- company_type = ContentType.objects.get(app_label='i18n', model='company')
- with translation.override('en'):
- self.assertEqual(str(company_type), 'i18n | Company')
- with translation.override('fr'):
- self.assertEqual(str(company_type), 'i18n | Société')
+ company_type = ContentType.objects.get(app_label="i18n", model="company")
+ with translation.override("en"):
+ self.assertEqual(str(company_type), "i18n | Company")
+ with translation.override("fr"):
+ self.assertEqual(str(company_type), "i18n | Société")
diff --git a/tests/i18n/forms.py b/tests/i18n/forms.py
index 8c290bf664..207ab9403a 100644
--- a/tests/i18n/forms.py
+++ b/tests/i18n/forms.py
@@ -23,4 +23,4 @@ class CompanyForm(forms.ModelForm):
class Meta:
model = Company
- fields = '__all__'
+ fields = "__all__"
diff --git a/tests/i18n/loading_app/apps.py b/tests/i18n/loading_app/apps.py
index 14cfdf776f..855862ec9a 100644
--- a/tests/i18n/loading_app/apps.py
+++ b/tests/i18n/loading_app/apps.py
@@ -2,4 +2,4 @@ from django.apps import AppConfig
class LoadingAppConfig(AppConfig):
- name = 'i18n.loading_app'
+ name = "i18n.loading_app"
diff --git a/tests/i18n/models.py b/tests/i18n/models.py
index 15b4de57b6..8343276bf2 100644
--- a/tests/i18n/models.py
+++ b/tests/i18n/models.py
@@ -5,7 +5,7 @@ from django.utils.translation import gettext_lazy as _
class TestModel(models.Model):
- text = models.CharField(max_length=10, default=_('Anything'))
+ text = models.CharField(max_length=10, default=_("Anything"))
class Company(models.Model):
@@ -15,4 +15,4 @@ class Company(models.Model):
products_delivered = models.IntegerField()
class Meta:
- verbose_name = _('Company')
+ verbose_name = _("Company")
diff --git a/tests/i18n/other/locale/fr/formats.py b/tests/i18n/other/locale/fr/formats.py
index d13e245c30..81f2f70886 100644
--- a/tests/i18n/other/locale/fr/formats.py
+++ b/tests/i18n/other/locale/fr/formats.py
@@ -1,2 +1,2 @@
# A user-defined format
-CUSTOM_DAY_FORMAT = 'd/m/Y CUSTOM'
+CUSTOM_DAY_FORMAT = "d/m/Y CUSTOM"
diff --git a/tests/i18n/patterns/tests.py b/tests/i18n/patterns/tests.py
index ebd2430428..eeb41e7d27 100644
--- a/tests/i18n/patterns/tests.py
+++ b/tests/i18n/patterns/tests.py
@@ -19,28 +19,30 @@ class PermanentRedirectLocaleMiddleWare(LocaleMiddleware):
@override_settings(
USE_I18N=True,
LOCALE_PATHS=[
- os.path.join(os.path.dirname(__file__), 'locale'),
+ os.path.join(os.path.dirname(__file__), "locale"),
],
- LANGUAGE_CODE='en-us',
+ LANGUAGE_CODE="en-us",
LANGUAGES=[
- ('nl', 'Dutch'),
- ('en', 'English'),
- ('pt-br', 'Brazilian Portuguese'),
+ ("nl", "Dutch"),
+ ("en", "English"),
+ ("pt-br", "Brazilian Portuguese"),
],
MIDDLEWARE=[
- 'django.middleware.locale.LocaleMiddleware',
- 'django.middleware.common.CommonMiddleware',
+ "django.middleware.locale.LocaleMiddleware",
+ "django.middleware.common.CommonMiddleware",
+ ],
+ ROOT_URLCONF="i18n.patterns.urls.default",
+ TEMPLATES=[
+ {
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "DIRS": [os.path.join(os.path.dirname(__file__), "templates")],
+ "OPTIONS": {
+ "context_processors": [
+ "django.template.context_processors.i18n",
+ ],
+ },
+ }
],
- ROOT_URLCONF='i18n.patterns.urls.default',
- TEMPLATES=[{
- 'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'DIRS': [os.path.join(os.path.dirname(__file__), 'templates')],
- 'OPTIONS': {
- 'context_processors': [
- 'django.template.context_processors.i18n',
- ],
- },
- }],
)
class URLTestCaseBase(SimpleTestCase):
"""
@@ -60,53 +62,58 @@ class URLPrefixTests(URLTestCaseBase):
"""
Tests if the `i18n_patterns` is adding the prefix correctly.
"""
+
def test_not_prefixed(self):
- with translation.override('en'):
- self.assertEqual(reverse('not-prefixed'), '/not-prefixed/')
- self.assertEqual(reverse('not-prefixed-included-url'), '/not-prefixed-include/foo/')
- with translation.override('nl'):
- self.assertEqual(reverse('not-prefixed'), '/not-prefixed/')
- self.assertEqual(reverse('not-prefixed-included-url'), '/not-prefixed-include/foo/')
+ with translation.override("en"):
+ self.assertEqual(reverse("not-prefixed"), "/not-prefixed/")
+ self.assertEqual(
+ reverse("not-prefixed-included-url"), "/not-prefixed-include/foo/"
+ )
+ with translation.override("nl"):
+ self.assertEqual(reverse("not-prefixed"), "/not-prefixed/")
+ self.assertEqual(
+ reverse("not-prefixed-included-url"), "/not-prefixed-include/foo/"
+ )
def test_prefixed(self):
- with translation.override('en'):
- self.assertEqual(reverse('prefixed'), '/en/prefixed/')
- with translation.override('nl'):
- self.assertEqual(reverse('prefixed'), '/nl/prefixed/')
+ with translation.override("en"):
+ self.assertEqual(reverse("prefixed"), "/en/prefixed/")
+ with translation.override("nl"):
+ self.assertEqual(reverse("prefixed"), "/nl/prefixed/")
with translation.override(None):
- self.assertEqual(reverse('prefixed'), '/%s/prefixed/' % settings.LANGUAGE_CODE)
+ self.assertEqual(
+ reverse("prefixed"), "/%s/prefixed/" % settings.LANGUAGE_CODE
+ )
- @override_settings(ROOT_URLCONF='i18n.patterns.urls.wrong')
+ @override_settings(ROOT_URLCONF="i18n.patterns.urls.wrong")
def test_invalid_prefix_use(self):
- msg = 'Using i18n_patterns in an included URLconf is not allowed.'
+ msg = "Using i18n_patterns in an included URLconf is not allowed."
with self.assertRaisesMessage(ImproperlyConfigured, msg):
- reverse('account:register')
+ reverse("account:register")
-@override_settings(ROOT_URLCONF='i18n.patterns.urls.disabled')
+@override_settings(ROOT_URLCONF="i18n.patterns.urls.disabled")
class URLDisabledTests(URLTestCaseBase):
-
@override_settings(USE_I18N=False)
def test_prefixed_i18n_disabled(self):
- with translation.override('en'):
- self.assertEqual(reverse('prefixed'), '/prefixed/')
- with translation.override('nl'):
- self.assertEqual(reverse('prefixed'), '/prefixed/')
+ with translation.override("en"):
+ self.assertEqual(reverse("prefixed"), "/prefixed/")
+ with translation.override("nl"):
+ self.assertEqual(reverse("prefixed"), "/prefixed/")
class RequestURLConfTests(SimpleTestCase):
-
- @override_settings(ROOT_URLCONF='i18n.patterns.urls.path_unused')
+ @override_settings(ROOT_URLCONF="i18n.patterns.urls.path_unused")
def test_request_urlconf_considered(self):
- request = RequestFactory().get('/nl/')
- request.urlconf = 'i18n.patterns.urls.default'
+ request = RequestFactory().get("/nl/")
+ request.urlconf = "i18n.patterns.urls.default"
middleware = LocaleMiddleware(lambda req: HttpResponse())
- with translation.override('nl'):
+ with translation.override("nl"):
middleware.process_request(request)
- self.assertEqual(request.LANGUAGE_CODE, 'nl')
+ self.assertEqual(request.LANGUAGE_CODE, "nl")
-@override_settings(ROOT_URLCONF='i18n.patterns.urls.path_unused')
+@override_settings(ROOT_URLCONF="i18n.patterns.urls.path_unused")
class PathUnusedTests(URLTestCaseBase):
"""
If no i18n_patterns is used in root URLconfs, then no language activation
@@ -114,10 +121,10 @@ class PathUnusedTests(URLTestCaseBase):
"""
def test_no_lang_activate(self):
- response = self.client.get('/nl/foo/')
+ response = self.client.get("/nl/foo/")
self.assertEqual(response.status_code, 200)
- self.assertEqual(response.headers['content-language'], 'en')
- self.assertEqual(response.context['LANGUAGE_CODE'], 'en')
+ self.assertEqual(response.headers["content-language"], "en")
+ self.assertEqual(response.context["LANGUAGE_CODE"], "en")
class URLTranslationTests(URLTestCaseBase):
@@ -125,66 +132,90 @@ class URLTranslationTests(URLTestCaseBase):
Tests if the pattern-strings are translated correctly (within the
`i18n_patterns` and the normal `patterns` function).
"""
+
def test_no_prefix_translated(self):
- with translation.override('en'):
- self.assertEqual(reverse('no-prefix-translated'), '/translated/')
- self.assertEqual(reverse('no-prefix-translated-slug', kwargs={'slug': 'yeah'}), '/translated/yeah/')
+ with translation.override("en"):
+ self.assertEqual(reverse("no-prefix-translated"), "/translated/")
+ self.assertEqual(
+ reverse("no-prefix-translated-slug", kwargs={"slug": "yeah"}),
+ "/translated/yeah/",
+ )
- with translation.override('nl'):
- self.assertEqual(reverse('no-prefix-translated'), '/vertaald/')
- self.assertEqual(reverse('no-prefix-translated-slug', kwargs={'slug': 'yeah'}), '/vertaald/yeah/')
+ with translation.override("nl"):
+ self.assertEqual(reverse("no-prefix-translated"), "/vertaald/")
+ self.assertEqual(
+ reverse("no-prefix-translated-slug", kwargs={"slug": "yeah"}),
+ "/vertaald/yeah/",
+ )
- with translation.override('pt-br'):
- self.assertEqual(reverse('no-prefix-translated'), '/traduzidos/')
- self.assertEqual(reverse('no-prefix-translated-slug', kwargs={'slug': 'yeah'}), '/traduzidos/yeah/')
+ with translation.override("pt-br"):
+ self.assertEqual(reverse("no-prefix-translated"), "/traduzidos/")
+ self.assertEqual(
+ reverse("no-prefix-translated-slug", kwargs={"slug": "yeah"}),
+ "/traduzidos/yeah/",
+ )
def test_users_url(self):
- with translation.override('en'):
- self.assertEqual(reverse('users'), '/en/users/')
+ with translation.override("en"):
+ self.assertEqual(reverse("users"), "/en/users/")
- with translation.override('nl'):
- self.assertEqual(reverse('users'), '/nl/gebruikers/')
- self.assertEqual(reverse('prefixed_xml'), '/nl/prefixed.xml')
+ with translation.override("nl"):
+ self.assertEqual(reverse("users"), "/nl/gebruikers/")
+ self.assertEqual(reverse("prefixed_xml"), "/nl/prefixed.xml")
- with translation.override('pt-br'):
- self.assertEqual(reverse('users'), '/pt-br/usuarios/')
+ with translation.override("pt-br"):
+ self.assertEqual(reverse("users"), "/pt-br/usuarios/")
def test_translate_url_utility(self):
- with translation.override('en'):
- self.assertEqual(translate_url('/en/nonexistent/', 'nl'), '/en/nonexistent/')
- self.assertEqual(translate_url('/en/users/', 'nl'), '/nl/gebruikers/')
+ with translation.override("en"):
+ self.assertEqual(
+ translate_url("/en/nonexistent/", "nl"), "/en/nonexistent/"
+ )
+ self.assertEqual(translate_url("/en/users/", "nl"), "/nl/gebruikers/")
# Namespaced URL
- self.assertEqual(translate_url('/en/account/register/', 'nl'), '/nl/profiel/registreren/')
+ self.assertEqual(
+ translate_url("/en/account/register/", "nl"), "/nl/profiel/registreren/"
+ )
# path() URL pattern
- self.assertEqual(translate_url('/en/account/register-as-path/', 'nl'), '/nl/profiel/registreren-als-pad/')
- self.assertEqual(translation.get_language(), 'en')
+ self.assertEqual(
+ translate_url("/en/account/register-as-path/", "nl"),
+ "/nl/profiel/registreren-als-pad/",
+ )
+ self.assertEqual(translation.get_language(), "en")
# URL with parameters.
self.assertEqual(
- translate_url('/en/with-arguments/regular-argument/', 'nl'),
- '/nl/with-arguments/regular-argument/',
+ translate_url("/en/with-arguments/regular-argument/", "nl"),
+ "/nl/with-arguments/regular-argument/",
)
self.assertEqual(
- translate_url('/en/with-arguments/regular-argument/optional.html', 'nl'),
- '/nl/with-arguments/regular-argument/optional.html',
+ translate_url(
+ "/en/with-arguments/regular-argument/optional.html", "nl"
+ ),
+ "/nl/with-arguments/regular-argument/optional.html",
)
- with translation.override('nl'):
- self.assertEqual(translate_url('/nl/gebruikers/', 'en'), '/en/users/')
- self.assertEqual(translation.get_language(), 'nl')
+ with translation.override("nl"):
+ self.assertEqual(translate_url("/nl/gebruikers/", "en"), "/en/users/")
+ self.assertEqual(translation.get_language(), "nl")
class URLNamespaceTests(URLTestCaseBase):
"""
Tests if the translations are still working within namespaces.
"""
+
def test_account_register(self):
- with translation.override('en'):
- self.assertEqual(reverse('account:register'), '/en/account/register/')
- self.assertEqual(reverse('account:register-as-path'), '/en/account/register-as-path/')
+ with translation.override("en"):
+ self.assertEqual(reverse("account:register"), "/en/account/register/")
+ self.assertEqual(
+ reverse("account:register-as-path"), "/en/account/register-as-path/"
+ )
- with translation.override('nl'):
- self.assertEqual(reverse('account:register'), '/nl/profiel/registreren/')
- self.assertEqual(reverse('account:register-as-path'), '/nl/profiel/registreren-als-pad/')
+ with translation.override("nl"):
+ self.assertEqual(reverse("account:register"), "/nl/profiel/registreren/")
+ self.assertEqual(
+ reverse("account:register-as-path"), "/nl/profiel/registreren-als-pad/"
+ )
class URLRedirectTests(URLTestCaseBase):
@@ -192,79 +223,81 @@ class URLRedirectTests(URLTestCaseBase):
Tests if the user gets redirected to the right URL when there is no
language-prefix in the request URL.
"""
+
def test_no_prefix_response(self):
- response = self.client.get('/not-prefixed/')
+ response = self.client.get("/not-prefixed/")
self.assertEqual(response.status_code, 200)
def test_en_redirect(self):
- response = self.client.get('/account/register/', HTTP_ACCEPT_LANGUAGE='en')
- self.assertRedirects(response, '/en/account/register/')
+ response = self.client.get("/account/register/", HTTP_ACCEPT_LANGUAGE="en")
+ self.assertRedirects(response, "/en/account/register/")
- response = self.client.get(response.headers['location'])
+ response = self.client.get(response.headers["location"])
self.assertEqual(response.status_code, 200)
def test_en_redirect_wrong_url(self):
- response = self.client.get('/profiel/registreren/', HTTP_ACCEPT_LANGUAGE='en')
+ response = self.client.get("/profiel/registreren/", HTTP_ACCEPT_LANGUAGE="en")
self.assertEqual(response.status_code, 404)
def test_nl_redirect(self):
- response = self.client.get('/profiel/registreren/', HTTP_ACCEPT_LANGUAGE='nl')
- self.assertRedirects(response, '/nl/profiel/registreren/')
+ response = self.client.get("/profiel/registreren/", HTTP_ACCEPT_LANGUAGE="nl")
+ self.assertRedirects(response, "/nl/profiel/registreren/")
- response = self.client.get(response.headers['location'])
+ response = self.client.get(response.headers["location"])
self.assertEqual(response.status_code, 200)
def test_nl_redirect_wrong_url(self):
- response = self.client.get('/account/register/', HTTP_ACCEPT_LANGUAGE='nl')
+ response = self.client.get("/account/register/", HTTP_ACCEPT_LANGUAGE="nl")
self.assertEqual(response.status_code, 404)
def test_pt_br_redirect(self):
- response = self.client.get('/conta/registre-se/', HTTP_ACCEPT_LANGUAGE='pt-br')
- self.assertRedirects(response, '/pt-br/conta/registre-se/')
+ response = self.client.get("/conta/registre-se/", HTTP_ACCEPT_LANGUAGE="pt-br")
+ self.assertRedirects(response, "/pt-br/conta/registre-se/")
- response = self.client.get(response.headers['location'])
+ response = self.client.get(response.headers["location"])
self.assertEqual(response.status_code, 200)
def test_pl_pl_redirect(self):
# language from outside of the supported LANGUAGES list
- response = self.client.get('/account/register/', HTTP_ACCEPT_LANGUAGE='pl-pl')
- self.assertRedirects(response, '/en/account/register/')
+ response = self.client.get("/account/register/", HTTP_ACCEPT_LANGUAGE="pl-pl")
+ self.assertRedirects(response, "/en/account/register/")
- response = self.client.get(response.headers['location'])
+ response = self.client.get(response.headers["location"])
self.assertEqual(response.status_code, 200)
@override_settings(
MIDDLEWARE=[
- 'i18n.patterns.tests.PermanentRedirectLocaleMiddleWare',
- 'django.middleware.common.CommonMiddleware',
+ "i18n.patterns.tests.PermanentRedirectLocaleMiddleWare",
+ "django.middleware.common.CommonMiddleware",
],
)
def test_custom_redirect_class(self):
- response = self.client.get('/account/register/', HTTP_ACCEPT_LANGUAGE='en')
- self.assertRedirects(response, '/en/account/register/', 301)
+ response = self.client.get("/account/register/", HTTP_ACCEPT_LANGUAGE="en")
+ self.assertRedirects(response, "/en/account/register/", 301)
class URLVaryAcceptLanguageTests(URLTestCaseBase):
"""
'Accept-Language' is not added to the Vary header when using prefixed URLs.
"""
+
def test_no_prefix_response(self):
- response = self.client.get('/not-prefixed/')
+ response = self.client.get("/not-prefixed/")
self.assertEqual(response.status_code, 200)
- self.assertEqual(response.get('Vary'), 'Accept-Language')
+ self.assertEqual(response.get("Vary"), "Accept-Language")
def test_en_redirect(self):
"""
The redirect to a prefixed URL depends on 'Accept-Language' and
'Cookie', but once prefixed no header is set.
"""
- response = self.client.get('/account/register/', HTTP_ACCEPT_LANGUAGE='en')
- self.assertRedirects(response, '/en/account/register/')
- self.assertEqual(response.get('Vary'), 'Accept-Language, Cookie')
+ response = self.client.get("/account/register/", HTTP_ACCEPT_LANGUAGE="en")
+ self.assertRedirects(response, "/en/account/register/")
+ self.assertEqual(response.get("Vary"), "Accept-Language, Cookie")
- response = self.client.get(response.headers['location'])
+ response = self.client.get(response.headers["location"])
self.assertEqual(response.status_code, 200)
- self.assertFalse(response.get('Vary'))
+ self.assertFalse(response.get("Vary"))
class URLRedirectWithoutTrailingSlashTests(URLTestCaseBase):
@@ -272,18 +305,23 @@ class URLRedirectWithoutTrailingSlashTests(URLTestCaseBase):
Tests the redirect when the requested URL doesn't end with a slash
(`settings.APPEND_SLASH=True`).
"""
+
def test_not_prefixed_redirect(self):
- response = self.client.get('/not-prefixed', HTTP_ACCEPT_LANGUAGE='en')
- self.assertRedirects(response, '/not-prefixed/', 301)
+ response = self.client.get("/not-prefixed", HTTP_ACCEPT_LANGUAGE="en")
+ self.assertRedirects(response, "/not-prefixed/", 301)
def test_en_redirect(self):
- response = self.client.get('/account/register', HTTP_ACCEPT_LANGUAGE='en', follow=True)
+ response = self.client.get(
+ "/account/register", HTTP_ACCEPT_LANGUAGE="en", follow=True
+ )
# We only want one redirect, bypassing CommonMiddleware
- self.assertEqual(response.redirect_chain, [('/en/account/register/', 302)])
- self.assertRedirects(response, '/en/account/register/', 302)
+ self.assertEqual(response.redirect_chain, [("/en/account/register/", 302)])
+ self.assertRedirects(response, "/en/account/register/", 302)
- response = self.client.get('/prefixed.xml', HTTP_ACCEPT_LANGUAGE='en', follow=True)
- self.assertRedirects(response, '/en/prefixed.xml', 302)
+ response = self.client.get(
+ "/prefixed.xml", HTTP_ACCEPT_LANGUAGE="en", follow=True
+ )
+ self.assertRedirects(response, "/en/prefixed.xml", 302)
class URLRedirectWithoutTrailingSlashSettingTests(URLTestCaseBase):
@@ -291,105 +329,129 @@ class URLRedirectWithoutTrailingSlashSettingTests(URLTestCaseBase):
Tests the redirect when the requested URL doesn't end with a slash
(`settings.APPEND_SLASH=False`).
"""
+
@override_settings(APPEND_SLASH=False)
def test_not_prefixed_redirect(self):
- response = self.client.get('/not-prefixed', HTTP_ACCEPT_LANGUAGE='en')
+ response = self.client.get("/not-prefixed", HTTP_ACCEPT_LANGUAGE="en")
self.assertEqual(response.status_code, 404)
@override_settings(APPEND_SLASH=False)
def test_en_redirect(self):
- response = self.client.get('/account/register-without-slash', HTTP_ACCEPT_LANGUAGE='en')
- self.assertRedirects(response, '/en/account/register-without-slash', 302)
+ response = self.client.get(
+ "/account/register-without-slash", HTTP_ACCEPT_LANGUAGE="en"
+ )
+ self.assertRedirects(response, "/en/account/register-without-slash", 302)
- response = self.client.get(response.headers['location'])
+ response = self.client.get(response.headers["location"])
self.assertEqual(response.status_code, 200)
class URLResponseTests(URLTestCaseBase):
"""Tests if the response has the correct language code."""
+
def test_not_prefixed_with_prefix(self):
- response = self.client.get('/en/not-prefixed/')
+ response = self.client.get("/en/not-prefixed/")
self.assertEqual(response.status_code, 404)
def test_en_url(self):
- response = self.client.get('/en/account/register/')
+ response = self.client.get("/en/account/register/")
self.assertEqual(response.status_code, 200)
- self.assertEqual(response.headers['content-language'], 'en')
- self.assertEqual(response.context['LANGUAGE_CODE'], 'en')
+ self.assertEqual(response.headers["content-language"], "en")
+ self.assertEqual(response.context["LANGUAGE_CODE"], "en")
def test_nl_url(self):
- response = self.client.get('/nl/profiel/registreren/')
+ response = self.client.get("/nl/profiel/registreren/")
self.assertEqual(response.status_code, 200)
- self.assertEqual(response.headers['content-language'], 'nl')
- self.assertEqual(response.context['LANGUAGE_CODE'], 'nl')
+ self.assertEqual(response.headers["content-language"], "nl")
+ self.assertEqual(response.context["LANGUAGE_CODE"], "nl")
def test_wrong_en_prefix(self):
- response = self.client.get('/en/profiel/registreren/')
+ response = self.client.get("/en/profiel/registreren/")
self.assertEqual(response.status_code, 404)
def test_wrong_nl_prefix(self):
- response = self.client.get('/nl/account/register/')
+ response = self.client.get("/nl/account/register/")
self.assertEqual(response.status_code, 404)
def test_pt_br_url(self):
- response = self.client.get('/pt-br/conta/registre-se/')
+ response = self.client.get("/pt-br/conta/registre-se/")
self.assertEqual(response.status_code, 200)
- self.assertEqual(response.headers['content-language'], 'pt-br')
- self.assertEqual(response.context['LANGUAGE_CODE'], 'pt-br')
+ self.assertEqual(response.headers["content-language"], "pt-br")
+ self.assertEqual(response.context["LANGUAGE_CODE"], "pt-br")
def test_en_path(self):
- response = self.client.get('/en/account/register-as-path/')
+ response = self.client.get("/en/account/register-as-path/")
self.assertEqual(response.status_code, 200)
- self.assertEqual(response.headers['content-language'], 'en')
- self.assertEqual(response.context['LANGUAGE_CODE'], 'en')
+ self.assertEqual(response.headers["content-language"], "en")
+ self.assertEqual(response.context["LANGUAGE_CODE"], "en")
def test_nl_path(self):
- response = self.client.get('/nl/profiel/registreren-als-pad/')
+ response = self.client.get("/nl/profiel/registreren-als-pad/")
self.assertEqual(response.status_code, 200)
- self.assertEqual(response.headers['content-language'], 'nl')
- self.assertEqual(response.context['LANGUAGE_CODE'], 'nl')
+ self.assertEqual(response.headers["content-language"], "nl")
+ self.assertEqual(response.context["LANGUAGE_CODE"], "nl")
class URLRedirectWithScriptAliasTests(URLTestCaseBase):
"""
#21579 - LocaleMiddleware should respect the script prefix.
"""
+
def test_language_prefix_with_script_prefix(self):
- prefix = '/script_prefix'
+ prefix = "/script_prefix"
with override_script_prefix(prefix):
- response = self.client.get('/prefixed/', HTTP_ACCEPT_LANGUAGE='en', SCRIPT_NAME=prefix)
- self.assertRedirects(response, '%s/en/prefixed/' % prefix, target_status_code=404)
+ response = self.client.get(
+ "/prefixed/", HTTP_ACCEPT_LANGUAGE="en", SCRIPT_NAME=prefix
+ )
+ self.assertRedirects(
+ response, "%s/en/prefixed/" % prefix, target_status_code=404
+ )
class URLTagTests(URLTestCaseBase):
"""
Test if the language tag works.
"""
+
def test_strings_only(self):
- t = Template("""{% load i18n %}
+ t = Template(
+ """{% load i18n %}
{% language 'nl' %}{% url 'no-prefix-translated' %}{% endlanguage %}
- {% language 'pt-br' %}{% url 'no-prefix-translated' %}{% endlanguage %}""")
- self.assertEqual(t.render(Context({})).strip().split(),
- ['/vertaald/', '/traduzidos/'])
+ {% language 'pt-br' %}{% url 'no-prefix-translated' %}{% endlanguage %}"""
+ )
+ self.assertEqual(
+ t.render(Context({})).strip().split(), ["/vertaald/", "/traduzidos/"]
+ )
def test_context(self):
- ctx = Context({'lang1': 'nl', 'lang2': 'pt-br'})
- tpl = Template("""{% load i18n %}
+ ctx = Context({"lang1": "nl", "lang2": "pt-br"})
+ tpl = Template(
+ """{% load i18n %}
{% language lang1 %}{% url 'no-prefix-translated' %}{% endlanguage %}
- {% language lang2 %}{% url 'no-prefix-translated' %}{% endlanguage %}""")
- self.assertEqual(tpl.render(ctx).strip().split(),
- ['/vertaald/', '/traduzidos/'])
+ {% language lang2 %}{% url 'no-prefix-translated' %}{% endlanguage %}"""
+ )
+ self.assertEqual(
+ tpl.render(ctx).strip().split(), ["/vertaald/", "/traduzidos/"]
+ )
def test_args(self):
- tpl = Template("""{% load i18n %}
+ tpl = Template(
+ """{% load i18n %}
{% language 'nl' %}{% url 'no-prefix-translated-slug' 'apo' %}{% endlanguage %}
- {% language 'pt-br' %}{% url 'no-prefix-translated-slug' 'apo' %}{% endlanguage %}""")
- self.assertEqual(tpl.render(Context({})).strip().split(),
- ['/vertaald/apo/', '/traduzidos/apo/'])
+ {% language 'pt-br' %}{% url 'no-prefix-translated-slug' 'apo' %}{% endlanguage %}"""
+ )
+ self.assertEqual(
+ tpl.render(Context({})).strip().split(),
+ ["/vertaald/apo/", "/traduzidos/apo/"],
+ )
def test_kwargs(self):
- tpl = Template("""{% load i18n %}
+ tpl = Template(
+ """{% load i18n %}
{% language 'nl' %}{% url 'no-prefix-translated-slug' slug='apo' %}{% endlanguage %}
- {% language 'pt-br' %}{% url 'no-prefix-translated-slug' slug='apo' %}{% endlanguage %}""")
- self.assertEqual(tpl.render(Context({})).strip().split(),
- ['/vertaald/apo/', '/traduzidos/apo/'])
+ {% language 'pt-br' %}{% url 'no-prefix-translated-slug' slug='apo' %}{% endlanguage %}"""
+ )
+ self.assertEqual(
+ tpl.render(Context({})).strip().split(),
+ ["/vertaald/apo/", "/traduzidos/apo/"],
+ )
diff --git a/tests/i18n/patterns/urls/default.py b/tests/i18n/patterns/urls/default.py
index 22fff166b3..c77bf98c73 100644
--- a/tests/i18n/patterns/urls/default.py
+++ b/tests/i18n/patterns/urls/default.py
@@ -3,23 +3,27 @@ from django.urls import include, path, re_path
from django.utils.translation import gettext_lazy as _
from django.views.generic import TemplateView
-view = TemplateView.as_view(template_name='dummy.html')
+view = TemplateView.as_view(template_name="dummy.html")
urlpatterns = [
- path('not-prefixed/', view, name='not-prefixed'),
- path('not-prefixed-include/', include('i18n.patterns.urls.included')),
- re_path(_(r'^translated/$'), view, name='no-prefix-translated'),
- re_path(_(r'^translated/(?P<slug>[\w-]+)/$'), view, name='no-prefix-translated-slug'),
+ path("not-prefixed/", view, name="not-prefixed"),
+ path("not-prefixed-include/", include("i18n.patterns.urls.included")),
+ re_path(_(r"^translated/$"), view, name="no-prefix-translated"),
+ re_path(
+ _(r"^translated/(?P<slug>[\w-]+)/$"), view, name="no-prefix-translated-slug"
+ ),
]
urlpatterns += i18n_patterns(
- path('prefixed/', view, name='prefixed'),
- path('prefixed.xml', view, name='prefixed_xml'),
+ path("prefixed/", view, name="prefixed"),
+ path("prefixed.xml", view, name="prefixed_xml"),
re_path(
- _(r'^with-arguments/(?P<argument>[\w-]+)/(?:(?P<optional>[\w-]+).html)?$'),
+ _(r"^with-arguments/(?P<argument>[\w-]+)/(?:(?P<optional>[\w-]+).html)?$"),
view,
- name='with-arguments',
+ name="with-arguments",
+ ),
+ re_path(_(r"^users/$"), view, name="users"),
+ re_path(
+ _(r"^account/"), include("i18n.patterns.urls.namespace", namespace="account")
),
- re_path(_(r'^users/$'), view, name='users'),
- re_path(_(r'^account/'), include('i18n.patterns.urls.namespace', namespace='account')),
)
diff --git a/tests/i18n/patterns/urls/disabled.py b/tests/i18n/patterns/urls/disabled.py
index 48b0201fe3..11dfe320b0 100644
--- a/tests/i18n/patterns/urls/disabled.py
+++ b/tests/i18n/patterns/urls/disabled.py
@@ -2,8 +2,8 @@ from django.conf.urls.i18n import i18n_patterns
from django.urls import path
from django.views.generic import TemplateView
-view = TemplateView.as_view(template_name='dummy.html')
+view = TemplateView.as_view(template_name="dummy.html")
urlpatterns = i18n_patterns(
- path('prefixed/', view, name='prefixed'),
+ path("prefixed/", view, name="prefixed"),
)
diff --git a/tests/i18n/patterns/urls/included.py b/tests/i18n/patterns/urls/included.py
index 75658dc961..733e38962a 100644
--- a/tests/i18n/patterns/urls/included.py
+++ b/tests/i18n/patterns/urls/included.py
@@ -1,8 +1,8 @@
from django.urls import path
from django.views.generic import TemplateView
-view = TemplateView.as_view(template_name='dummy.html')
+view = TemplateView.as_view(template_name="dummy.html")
urlpatterns = [
- path('foo/', view, name='not-prefixed-included-url'),
+ path("foo/", view, name="not-prefixed-included-url"),
]
diff --git a/tests/i18n/patterns/urls/namespace.py b/tests/i18n/patterns/urls/namespace.py
index 19cd5694da..466303ac6d 100644
--- a/tests/i18n/patterns/urls/namespace.py
+++ b/tests/i18n/patterns/urls/namespace.py
@@ -2,11 +2,11 @@ from django.urls import path, re_path
from django.utils.translation import gettext_lazy as _
from django.views.generic import TemplateView
-view = TemplateView.as_view(template_name='dummy.html')
+view = TemplateView.as_view(template_name="dummy.html")
-app_name = 'account'
+app_name = "account"
urlpatterns = [
- re_path(_(r'^register/$'), view, name='register'),
- re_path(_(r'^register-without-slash$'), view, name='register-without-slash'),
- path(_('register-as-path/'), view, name='register-as-path'),
+ re_path(_(r"^register/$"), view, name="register"),
+ re_path(_(r"^register-without-slash$"), view, name="register-without-slash"),
+ path(_("register-as-path/"), view, name="register-as-path"),
]
diff --git a/tests/i18n/patterns/urls/path_unused.py b/tests/i18n/patterns/urls/path_unused.py
index 2784d286a1..3df4b46c4c 100644
--- a/tests/i18n/patterns/urls/path_unused.py
+++ b/tests/i18n/patterns/urls/path_unused.py
@@ -1,8 +1,8 @@
from django.urls import re_path
from django.views.generic import TemplateView
-view = TemplateView.as_view(template_name='dummy.html')
+view = TemplateView.as_view(template_name="dummy.html")
urlpatterns = [
- re_path('^nl/foo/', view, name='not-translated'),
+ re_path("^nl/foo/", view, name="not-translated"),
]
diff --git a/tests/i18n/patterns/urls/wrong.py b/tests/i18n/patterns/urls/wrong.py
index 46b4b69718..b4a2e0e16b 100644
--- a/tests/i18n/patterns/urls/wrong.py
+++ b/tests/i18n/patterns/urls/wrong.py
@@ -3,5 +3,8 @@ from django.urls import include, re_path
from django.utils.translation import gettext_lazy as _
urlpatterns = i18n_patterns(
- re_path(_(r'^account/'), include('i18n.patterns.urls.wrong_namespace', namespace='account')),
+ re_path(
+ _(r"^account/"),
+ include("i18n.patterns.urls.wrong_namespace", namespace="account"),
+ ),
)
diff --git a/tests/i18n/patterns/urls/wrong_namespace.py b/tests/i18n/patterns/urls/wrong_namespace.py
index 7800d90e3c..527dff4543 100644
--- a/tests/i18n/patterns/urls/wrong_namespace.py
+++ b/tests/i18n/patterns/urls/wrong_namespace.py
@@ -3,9 +3,9 @@ from django.urls import re_path
from django.utils.translation import gettext_lazy as _
from django.views.generic import TemplateView
-view = TemplateView.as_view(template_name='dummy.html')
+view = TemplateView.as_view(template_name="dummy.html")
-app_name = 'account'
+app_name = "account"
urlpatterns = i18n_patterns(
- re_path(_(r'^register/$'), view, name='register'),
+ re_path(_(r"^register/$"), view, name="register"),
)
diff --git a/tests/i18n/sampleproject/manage.py b/tests/i18n/sampleproject/manage.py
index 87a0ec369a..717bf4e28f 100755
--- a/tests/i18n/sampleproject/manage.py
+++ b/tests/i18n/sampleproject/manage.py
@@ -2,7 +2,7 @@
import os
import sys
-sys.path.append(os.path.abspath(os.path.join('..', '..', '..')))
+sys.path.append(os.path.abspath(os.path.join("..", "..", "..")))
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sampleproject.settings")
diff --git a/tests/i18n/sampleproject/update_catalogs.py b/tests/i18n/sampleproject/update_catalogs.py
index 55bf1656a2..8780f629e4 100755
--- a/tests/i18n/sampleproject/update_catalogs.py
+++ b/tests/i18n/sampleproject/update_catalogs.py
@@ -31,7 +31,7 @@ import re
import sys
proj_dir = os.path.dirname(os.path.abspath(__file__))
-sys.path.append(os.path.abspath(os.path.join(proj_dir, '..', '..', '..')))
+sys.path.append(os.path.abspath(os.path.join(proj_dir, "..", "..", "..")))
def update_translation_catalogs():
@@ -41,16 +41,16 @@ def update_translation_catalogs():
prev_cwd = os.getcwd()
os.chdir(proj_dir)
- call_command('makemessages')
- call_command('compilemessages')
+ call_command("makemessages")
+ call_command("compilemessages")
# keep the diff friendly - remove 'POT-Creation-Date'
- pofile = os.path.join(proj_dir, 'locale', 'fr', 'LC_MESSAGES', 'django.po')
+ pofile = os.path.join(proj_dir, "locale", "fr", "LC_MESSAGES", "django.po")
with open(pofile) as f:
content = f.read()
- content = re.sub(r'^"POT-Creation-Date.+$\s', '', content, flags=re.MULTILINE)
- with open(pofile, 'w') as f:
+ content = re.sub(r'^"POT-Creation-Date.+$\s', "", content, flags=re.MULTILINE)
+ with open(pofile, "w") as f:
f.write(content)
os.chdir(prev_cwd)
diff --git a/tests/i18n/test_compilation.py b/tests/i18n/test_compilation.py
index 299c07a93f..259a9668b8 100644
--- a/tests/i18n/test_compilation.py
+++ b/tests/i18n/test_compilation.py
@@ -7,12 +7,8 @@ from pathlib import Path
from subprocess import run
from unittest import mock
-from django.core.management import (
- CommandError, call_command, execute_from_command_line,
-)
-from django.core.management.commands.makemessages import (
- Command as MakeMessagesCommand,
-)
+from django.core.management import CommandError, call_command, execute_from_command_line
+from django.core.management.commands.makemessages import Command as MakeMessagesCommand
from django.core.management.utils import find_command
from django.test import SimpleTestCase, override_settings
from django.test.utils import captured_stderr, captured_stdout
@@ -21,26 +17,30 @@ from django.utils.translation import gettext
from .utils import RunInTmpDirMixin, copytree
-has_msgfmt = find_command('msgfmt')
+has_msgfmt = find_command("msgfmt")
-@unittest.skipUnless(has_msgfmt, 'msgfmt is mandatory for compilation tests')
+@unittest.skipUnless(has_msgfmt, "msgfmt is mandatory for compilation tests")
class MessageCompilationTests(RunInTmpDirMixin, SimpleTestCase):
- work_subdir = 'commands'
+ work_subdir = "commands"
class PoFileTests(MessageCompilationTests):
- LOCALE = 'es_AR'
- MO_FILE = 'locale/%s/LC_MESSAGES/django.mo' % LOCALE
- MO_FILE_EN = 'locale/en/LC_MESSAGES/django.mo'
+ LOCALE = "es_AR"
+ MO_FILE = "locale/%s/LC_MESSAGES/django.mo" % LOCALE
+ MO_FILE_EN = "locale/en/LC_MESSAGES/django.mo"
def test_bom_rejection(self):
stderr = StringIO()
- with self.assertRaisesMessage(CommandError, 'compilemessages generated one or more errors.'):
- call_command('compilemessages', locale=[self.LOCALE], verbosity=0, stderr=stderr)
- self.assertIn('file has a BOM (Byte Order Mark)', stderr.getvalue())
+ with self.assertRaisesMessage(
+ CommandError, "compilemessages generated one or more errors."
+ ):
+ call_command(
+ "compilemessages", locale=[self.LOCALE], verbosity=0, stderr=stderr
+ )
+ self.assertIn("file has a BOM (Byte Order Mark)", stderr.getvalue())
self.assertFalse(os.path.exists(self.MO_FILE))
def test_no_write_access(self):
@@ -50,11 +50,15 @@ class PoFileTests(MessageCompilationTests):
old_mode = mo_file_en.stat().st_mode
mo_file_en.chmod(stat.S_IREAD)
# Ensure .po file is more recent than .mo file.
- mo_file_en.with_suffix('.po').touch()
+ mo_file_en.with_suffix(".po").touch()
try:
- with self.assertRaisesMessage(CommandError, 'compilemessages generated one or more errors.'):
- call_command('compilemessages', locale=['en'], stderr=err_buffer, verbosity=0)
- self.assertIn('not writable location', err_buffer.getvalue())
+ with self.assertRaisesMessage(
+ CommandError, "compilemessages generated one or more errors."
+ ):
+ call_command(
+ "compilemessages", locale=["en"], stderr=err_buffer, verbosity=0
+ )
+ self.assertIn("not writable location", err_buffer.getvalue())
finally:
mo_file_en.chmod(old_mode)
@@ -62,19 +66,19 @@ class PoFileTests(MessageCompilationTests):
mo_file_en = Path(self.MO_FILE_EN)
mo_file_en.touch()
stdout = StringIO()
- call_command('compilemessages', locale=['en'], stdout=stdout, verbosity=1)
- msg = '%s” is already compiled and up to date.' % mo_file_en.with_suffix('.po')
+ call_command("compilemessages", locale=["en"], stdout=stdout, verbosity=1)
+ msg = "%s” is already compiled and up to date." % mo_file_en.with_suffix(".po")
self.assertIn(msg, stdout.getvalue())
class PoFileContentsTests(MessageCompilationTests):
# Ticket #11240
- LOCALE = 'fr'
- MO_FILE = 'locale/%s/LC_MESSAGES/django.mo' % LOCALE
+ LOCALE = "fr"
+ MO_FILE = "locale/%s/LC_MESSAGES/django.mo" % LOCALE
def test_percent_symbol_in_po_file(self):
- call_command('compilemessages', locale=[self.LOCALE], verbosity=0)
+ call_command("compilemessages", locale=[self.LOCALE], verbosity=0)
self.assertTrue(os.path.exists(self.MO_FILE))
@@ -85,19 +89,19 @@ class MultipleLocaleCompilationTests(MessageCompilationTests):
def setUp(self):
super().setUp()
- localedir = os.path.join(self.test_dir, 'locale')
- self.MO_FILE_HR = os.path.join(localedir, 'hr/LC_MESSAGES/django.mo')
- self.MO_FILE_FR = os.path.join(localedir, 'fr/LC_MESSAGES/django.mo')
+ localedir = os.path.join(self.test_dir, "locale")
+ self.MO_FILE_HR = os.path.join(localedir, "hr/LC_MESSAGES/django.mo")
+ self.MO_FILE_FR = os.path.join(localedir, "fr/LC_MESSAGES/django.mo")
def test_one_locale(self):
- with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, 'locale')]):
- call_command('compilemessages', locale=['hr'], verbosity=0)
+ with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, "locale")]):
+ call_command("compilemessages", locale=["hr"], verbosity=0)
self.assertTrue(os.path.exists(self.MO_FILE_HR))
def test_multiple_locales(self):
- with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, 'locale')]):
- call_command('compilemessages', locale=['hr', 'fr'], verbosity=0)
+ with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, "locale")]):
+ call_command("compilemessages", locale=["hr", "fr"], verbosity=0)
self.assertTrue(os.path.exists(self.MO_FILE_HR))
self.assertTrue(os.path.exists(self.MO_FILE_FR))
@@ -105,144 +109,164 @@ class MultipleLocaleCompilationTests(MessageCompilationTests):
class ExcludedLocaleCompilationTests(MessageCompilationTests):
- work_subdir = 'exclude'
+ work_subdir = "exclude"
- MO_FILE = 'locale/%s/LC_MESSAGES/django.mo'
+ MO_FILE = "locale/%s/LC_MESSAGES/django.mo"
def setUp(self):
super().setUp()
- copytree('canned_locale', 'locale')
+ copytree("canned_locale", "locale")
def test_command_help(self):
with captured_stdout(), captured_stderr():
# `call_command` bypasses the parser; by calling
# `execute_from_command_line` with the help subcommand we
# ensure that there are no issues with the parser itself.
- execute_from_command_line(['django-admin', 'help', 'compilemessages'])
+ execute_from_command_line(["django-admin", "help", "compilemessages"])
def test_one_locale_excluded(self):
- call_command('compilemessages', exclude=['it'], verbosity=0)
- self.assertTrue(os.path.exists(self.MO_FILE % 'en'))
- self.assertTrue(os.path.exists(self.MO_FILE % 'fr'))
- self.assertFalse(os.path.exists(self.MO_FILE % 'it'))
+ call_command("compilemessages", exclude=["it"], verbosity=0)
+ self.assertTrue(os.path.exists(self.MO_FILE % "en"))
+ self.assertTrue(os.path.exists(self.MO_FILE % "fr"))
+ self.assertFalse(os.path.exists(self.MO_FILE % "it"))
def test_multiple_locales_excluded(self):
- call_command('compilemessages', exclude=['it', 'fr'], verbosity=0)
- self.assertTrue(os.path.exists(self.MO_FILE % 'en'))
- self.assertFalse(os.path.exists(self.MO_FILE % 'fr'))
- self.assertFalse(os.path.exists(self.MO_FILE % 'it'))
+ call_command("compilemessages", exclude=["it", "fr"], verbosity=0)
+ self.assertTrue(os.path.exists(self.MO_FILE % "en"))
+ self.assertFalse(os.path.exists(self.MO_FILE % "fr"))
+ self.assertFalse(os.path.exists(self.MO_FILE % "it"))
def test_one_locale_excluded_with_locale(self):
- call_command('compilemessages', locale=['en', 'fr'], exclude=['fr'], verbosity=0)
- self.assertTrue(os.path.exists(self.MO_FILE % 'en'))
- self.assertFalse(os.path.exists(self.MO_FILE % 'fr'))
- self.assertFalse(os.path.exists(self.MO_FILE % 'it'))
+ call_command(
+ "compilemessages", locale=["en", "fr"], exclude=["fr"], verbosity=0
+ )
+ self.assertTrue(os.path.exists(self.MO_FILE % "en"))
+ self.assertFalse(os.path.exists(self.MO_FILE % "fr"))
+ self.assertFalse(os.path.exists(self.MO_FILE % "it"))
def test_multiple_locales_excluded_with_locale(self):
- call_command('compilemessages', locale=['en', 'fr', 'it'], exclude=['fr', 'it'], verbosity=0)
- self.assertTrue(os.path.exists(self.MO_FILE % 'en'))
- self.assertFalse(os.path.exists(self.MO_FILE % 'fr'))
- self.assertFalse(os.path.exists(self.MO_FILE % 'it'))
+ call_command(
+ "compilemessages",
+ locale=["en", "fr", "it"],
+ exclude=["fr", "it"],
+ verbosity=0,
+ )
+ self.assertTrue(os.path.exists(self.MO_FILE % "en"))
+ self.assertFalse(os.path.exists(self.MO_FILE % "fr"))
+ self.assertFalse(os.path.exists(self.MO_FILE % "it"))
class IgnoreDirectoryCompilationTests(MessageCompilationTests):
# Reuse the exclude directory since it contains some locale fixtures.
- work_subdir = 'exclude'
- MO_FILE = '%s/%s/LC_MESSAGES/django.mo'
- CACHE_DIR = Path('cache') / 'locale'
- NESTED_DIR = Path('outdated') / 'v1' / 'locale'
+ work_subdir = "exclude"
+ MO_FILE = "%s/%s/LC_MESSAGES/django.mo"
+ CACHE_DIR = Path("cache") / "locale"
+ NESTED_DIR = Path("outdated") / "v1" / "locale"
def setUp(self):
super().setUp()
- copytree('canned_locale', 'locale')
- copytree('canned_locale', self.CACHE_DIR)
- copytree('canned_locale', self.NESTED_DIR)
+ copytree("canned_locale", "locale")
+ copytree("canned_locale", self.CACHE_DIR)
+ copytree("canned_locale", self.NESTED_DIR)
def assertAllExist(self, dir, langs):
- self.assertTrue(all(Path(self.MO_FILE % (dir, lang)).exists() for lang in langs))
+ self.assertTrue(
+ all(Path(self.MO_FILE % (dir, lang)).exists() for lang in langs)
+ )
def assertNoneExist(self, dir, langs):
- self.assertTrue(all(Path(self.MO_FILE % (dir, lang)).exists() is False for lang in langs))
+ self.assertTrue(
+ all(Path(self.MO_FILE % (dir, lang)).exists() is False for lang in langs)
+ )
def test_one_locale_dir_ignored(self):
- call_command('compilemessages', ignore=['cache'], verbosity=0)
- self.assertAllExist('locale', ['en', 'fr', 'it'])
- self.assertNoneExist(self.CACHE_DIR, ['en', 'fr', 'it'])
- self.assertAllExist(self.NESTED_DIR, ['en', 'fr', 'it'])
+ call_command("compilemessages", ignore=["cache"], verbosity=0)
+ self.assertAllExist("locale", ["en", "fr", "it"])
+ self.assertNoneExist(self.CACHE_DIR, ["en", "fr", "it"])
+ self.assertAllExist(self.NESTED_DIR, ["en", "fr", "it"])
def test_multiple_locale_dirs_ignored(self):
- call_command('compilemessages', ignore=['cache/locale', 'outdated'], verbosity=0)
- self.assertAllExist('locale', ['en', 'fr', 'it'])
- self.assertNoneExist(self.CACHE_DIR, ['en', 'fr', 'it'])
- self.assertNoneExist(self.NESTED_DIR, ['en', 'fr', 'it'])
+ call_command(
+ "compilemessages", ignore=["cache/locale", "outdated"], verbosity=0
+ )
+ self.assertAllExist("locale", ["en", "fr", "it"])
+ self.assertNoneExist(self.CACHE_DIR, ["en", "fr", "it"])
+ self.assertNoneExist(self.NESTED_DIR, ["en", "fr", "it"])
def test_ignores_based_on_pattern(self):
- call_command('compilemessages', ignore=['*/locale'], verbosity=0)
- self.assertAllExist('locale', ['en', 'fr', 'it'])
- self.assertNoneExist(self.CACHE_DIR, ['en', 'fr', 'it'])
- self.assertNoneExist(self.NESTED_DIR, ['en', 'fr', 'it'])
+ call_command("compilemessages", ignore=["*/locale"], verbosity=0)
+ self.assertAllExist("locale", ["en", "fr", "it"])
+ self.assertNoneExist(self.CACHE_DIR, ["en", "fr", "it"])
+ self.assertNoneExist(self.NESTED_DIR, ["en", "fr", "it"])
class CompilationErrorHandling(MessageCompilationTests):
def test_error_reported_by_msgfmt(self):
# po file contains wrong po formatting.
with self.assertRaises(CommandError):
- call_command('compilemessages', locale=['ja'], verbosity=0)
+ call_command("compilemessages", locale=["ja"], verbosity=0)
def test_msgfmt_error_including_non_ascii(self):
# po file contains invalid msgstr content (triggers non-ascii error content).
# Make sure the output of msgfmt is unaffected by the current locale.
env = os.environ.copy()
- env.update({'LC_ALL': 'C'})
- with mock.patch('django.core.management.utils.run', lambda *args, **kwargs: run(*args, env=env, **kwargs)):
+ env.update({"LC_ALL": "C"})
+ with mock.patch(
+ "django.core.management.utils.run",
+ lambda *args, **kwargs: run(*args, env=env, **kwargs),
+ ):
cmd = MakeMessagesCommand()
if cmd.gettext_version < (0, 18, 3):
self.skipTest("python-brace-format is a recent gettext addition.")
stderr = StringIO()
- with self.assertRaisesMessage(CommandError, 'compilemessages generated one or more errors'):
- call_command('compilemessages', locale=['ko'], stdout=StringIO(), stderr=stderr)
+ with self.assertRaisesMessage(
+ CommandError, "compilemessages generated one or more errors"
+ ):
+ call_command(
+ "compilemessages", locale=["ko"], stdout=StringIO(), stderr=stderr
+ )
self.assertIn("' cannot start a field name", stderr.getvalue())
class ProjectAndAppTests(MessageCompilationTests):
- LOCALE = 'ru'
- PROJECT_MO_FILE = 'locale/%s/LC_MESSAGES/django.mo' % LOCALE
- APP_MO_FILE = 'app_with_locale/locale/%s/LC_MESSAGES/django.mo' % LOCALE
+ LOCALE = "ru"
+ PROJECT_MO_FILE = "locale/%s/LC_MESSAGES/django.mo" % LOCALE
+ APP_MO_FILE = "app_with_locale/locale/%s/LC_MESSAGES/django.mo" % LOCALE
class FuzzyTranslationTest(ProjectAndAppTests):
-
def setUp(self):
super().setUp()
gettext_module._translations = {} # flush cache or test will be useless
def test_nofuzzy_compiling(self):
- with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, 'locale')]):
- call_command('compilemessages', locale=[self.LOCALE], verbosity=0)
+ with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, "locale")]):
+ call_command("compilemessages", locale=[self.LOCALE], verbosity=0)
with translation.override(self.LOCALE):
- self.assertEqual(gettext('Lenin'), 'Ленин')
- self.assertEqual(gettext('Vodka'), 'Vodka')
+ self.assertEqual(gettext("Lenin"), "Ленин")
+ self.assertEqual(gettext("Vodka"), "Vodka")
def test_fuzzy_compiling(self):
- with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, 'locale')]):
- call_command('compilemessages', locale=[self.LOCALE], fuzzy=True, verbosity=0)
+ with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, "locale")]):
+ call_command(
+ "compilemessages", locale=[self.LOCALE], fuzzy=True, verbosity=0
+ )
with translation.override(self.LOCALE):
- self.assertEqual(gettext('Lenin'), 'Ленин')
- self.assertEqual(gettext('Vodka'), 'Водка')
+ self.assertEqual(gettext("Lenin"), "Ленин")
+ self.assertEqual(gettext("Vodka"), "Водка")
class AppCompilationTest(ProjectAndAppTests):
-
def test_app_locale_compiled(self):
- call_command('compilemessages', locale=[self.LOCALE], verbosity=0)
+ call_command("compilemessages", locale=[self.LOCALE], verbosity=0)
self.assertTrue(os.path.exists(self.PROJECT_MO_FILE))
self.assertTrue(os.path.exists(self.APP_MO_FILE))
class PathLibLocaleCompilationTests(MessageCompilationTests):
- work_subdir = 'exclude'
+ work_subdir = "exclude"
def test_locale_paths_pathlib(self):
- with override_settings(LOCALE_PATHS=[Path(self.test_dir) / 'canned_locale']):
- call_command('compilemessages', locale=['fr'], verbosity=0)
- self.assertTrue(os.path.exists('canned_locale/fr/LC_MESSAGES/django.mo'))
+ with override_settings(LOCALE_PATHS=[Path(self.test_dir) / "canned_locale"]):
+ call_command("compilemessages", locale=["fr"], verbosity=0)
+ self.assertTrue(os.path.exists("canned_locale/fr/LC_MESSAGES/django.mo"))
diff --git a/tests/i18n/test_extraction.py b/tests/i18n/test_extraction.py
index 98932fdcbb..c4aeef7339 100644
--- a/tests/i18n/test_extraction.py
+++ b/tests/i18n/test_extraction.py
@@ -13,9 +13,8 @@ from admin_scripts.tests import AdminScriptTestCase
from django.core import management
from django.core.management import execute_from_command_line
from django.core.management.base import CommandError
-from django.core.management.commands.makemessages import (
- Command as MakeMessagesCommand, write_pot_file,
-)
+from django.core.management.commands.makemessages import Command as MakeMessagesCommand
+from django.core.management.commands.makemessages import write_pot_file
from django.core.management.utils import find_command
from django.test import SimpleTestCase, override_settings
from django.test.utils import captured_stderr, captured_stdout
@@ -24,22 +23,26 @@ from django.utils.translation import TranslatorCommentWarning
from .utils import POFileAssertionMixin, RunInTmpDirMixin, copytree
-LOCALE = 'de'
-has_xgettext = find_command('xgettext')
+LOCALE = "de"
+has_xgettext = find_command("xgettext")
gettext_version = MakeMessagesCommand().gettext_version if has_xgettext else None
-requires_gettext_019 = skipIf(has_xgettext and gettext_version < (0, 19), 'gettext 0.19 required')
+requires_gettext_019 = skipIf(
+ has_xgettext and gettext_version < (0, 19), "gettext 0.19 required"
+)
-@skipUnless(has_xgettext, 'xgettext is mandatory for extraction tests')
+@skipUnless(has_xgettext, "xgettext is mandatory for extraction tests")
class ExtractorTests(POFileAssertionMixin, RunInTmpDirMixin, SimpleTestCase):
- work_subdir = 'commands'
+ work_subdir = "commands"
- PO_FILE = 'locale/%s/LC_MESSAGES/django.po' % LOCALE
+ PO_FILE = "locale/%s/LC_MESSAGES/django.po" % LOCALE
def _run_makemessages(self, **options):
out = StringIO()
- management.call_command('makemessages', locale=[LOCALE], verbosity=2, stdout=out, **options)
+ management.call_command(
+ "makemessages", locale=[LOCALE], verbosity=2, stdout=out, **options
+ )
output = out.getvalue()
self.assertTrue(os.path.exists(self.PO_FILE))
with open(self.PO_FILE) as fp:
@@ -47,26 +50,30 @@ class ExtractorTests(POFileAssertionMixin, RunInTmpDirMixin, SimpleTestCase):
return output, po_contents
def assertMsgIdPlural(self, msgid, haystack, use_quotes=True):
- return self._assertPoKeyword('msgid_plural', msgid, haystack, use_quotes=use_quotes)
+ return self._assertPoKeyword(
+ "msgid_plural", msgid, haystack, use_quotes=use_quotes
+ )
def assertMsgStr(self, msgstr, haystack, use_quotes=True):
- return self._assertPoKeyword('msgstr', msgstr, haystack, use_quotes=use_quotes)
+ return self._assertPoKeyword("msgstr", msgstr, haystack, use_quotes=use_quotes)
def assertNotMsgId(self, msgid, s, use_quotes=True):
if use_quotes:
msgid = '"%s"' % msgid
msgid = re.escape(msgid)
- return self.assertTrue(not re.search('^msgid %s' % msgid, s, re.MULTILINE))
+ return self.assertTrue(not re.search("^msgid %s" % msgid, s, re.MULTILINE))
- def _assertPoLocComment(self, assert_presence, po_filename, line_number, *comment_parts):
+ def _assertPoLocComment(
+ self, assert_presence, po_filename, line_number, *comment_parts
+ ):
with open(po_filename) as fp:
po_contents = fp.read()
- if os.name == 'nt':
+ if os.name == "nt":
# #: .\path\to\file.html:123
- cwd_prefix = '%s%s' % (os.curdir, os.sep)
+ cwd_prefix = "%s%s" % (os.curdir, os.sep)
else:
# #: path/to/file.html:123
- cwd_prefix = ''
+ cwd_prefix = ""
path = os.path.join(cwd_prefix, *comment_parts)
parts = [path]
@@ -74,21 +81,28 @@ class ExtractorTests(POFileAssertionMixin, RunInTmpDirMixin, SimpleTestCase):
if isinstance(line_number, str):
line_number = self._get_token_line_number(path, line_number)
if line_number is not None:
- parts.append(':%d' % line_number)
+ parts.append(":%d" % line_number)
- needle = ''.join(parts)
- pattern = re.compile(r'^\#\:.*' + re.escape(needle), re.MULTILINE)
+ needle = "".join(parts)
+ pattern = re.compile(r"^\#\:.*" + re.escape(needle), re.MULTILINE)
if assert_presence:
- return self.assertRegex(po_contents, pattern, '"%s" not found in final .po file.' % needle)
+ return self.assertRegex(
+ po_contents, pattern, '"%s" not found in final .po file.' % needle
+ )
else:
- return self.assertNotRegex(po_contents, pattern, '"%s" shouldn\'t be in final .po file.' % needle)
+ return self.assertNotRegex(
+ po_contents, pattern, '"%s" shouldn\'t be in final .po file.' % needle
+ )
def _get_token_line_number(self, path, token):
with open(path) as f:
for line, content in enumerate(f, 1):
if token in content:
return line
- self.fail("The token '%s' could not be found in %s, please check the test config" % (token, path))
+ self.fail(
+ "The token '%s' could not be found in %s, please check the test config"
+ % (token, path)
+ )
def assertLocationCommentPresent(self, po_filename, line_number, *comment_parts):
r"""
@@ -128,123 +142,147 @@ class ExtractorTests(POFileAssertionMixin, RunInTmpDirMixin, SimpleTestCase):
class BasicExtractorTests(ExtractorTests):
-
@override_settings(USE_I18N=False)
def test_use_i18n_false(self):
"""
makemessages also runs successfully when USE_I18N is False.
"""
- management.call_command('makemessages', locale=[LOCALE], verbosity=0)
+ management.call_command("makemessages", locale=[LOCALE], verbosity=0)
self.assertTrue(os.path.exists(self.PO_FILE))
- with open(self.PO_FILE, encoding='utf-8') as fp:
+ with open(self.PO_FILE, encoding="utf-8") as fp:
po_contents = fp.read()
# Check two random strings
- self.assertIn('#. Translators: One-line translator comment #1', po_contents)
+ self.assertIn("#. Translators: One-line translator comment #1", po_contents)
self.assertIn('msgctxt "Special trans context #1"', po_contents)
def test_no_option(self):
# One of either the --locale, --exclude, or --all options is required.
msg = "Type 'manage.py help makemessages' for usage information."
with mock.patch(
- 'django.core.management.commands.makemessages.sys.argv',
- ['manage.py', 'makemessages'],
+ "django.core.management.commands.makemessages.sys.argv",
+ ["manage.py", "makemessages"],
):
with self.assertRaisesRegex(CommandError, msg):
- management.call_command('makemessages')
+ management.call_command("makemessages")
def test_valid_locale(self):
out = StringIO()
- management.call_command('makemessages', locale=['de'], stdout=out, verbosity=1)
- self.assertNotIn('invalid locale de', out.getvalue())
- self.assertIn('processing locale de', out.getvalue())
+ management.call_command("makemessages", locale=["de"], stdout=out, verbosity=1)
+ self.assertNotIn("invalid locale de", out.getvalue())
+ self.assertIn("processing locale de", out.getvalue())
self.assertIs(Path(self.PO_FILE).exists(), True)
def test_invalid_locale(self):
out = StringIO()
- management.call_command('makemessages', locale=['pl-PL'], stdout=out, verbosity=1)
- self.assertIn('invalid locale pl-PL, did you mean pl_PL?', out.getvalue())
- self.assertNotIn('processing locale pl-PL', out.getvalue())
- self.assertIs(Path('locale/pl-PL/LC_MESSAGES/django.po').exists(), False)
+ management.call_command(
+ "makemessages", locale=["pl-PL"], stdout=out, verbosity=1
+ )
+ self.assertIn("invalid locale pl-PL, did you mean pl_PL?", out.getvalue())
+ self.assertNotIn("processing locale pl-PL", out.getvalue())
+ self.assertIs(Path("locale/pl-PL/LC_MESSAGES/django.po").exists(), False)
def test_comments_extractor(self):
- management.call_command('makemessages', locale=[LOCALE], verbosity=0)
+ management.call_command("makemessages", locale=[LOCALE], verbosity=0)
self.assertTrue(os.path.exists(self.PO_FILE))
- with open(self.PO_FILE, encoding='utf-8') as fp:
+ with open(self.PO_FILE, encoding="utf-8") as fp:
po_contents = fp.read()
- self.assertNotIn('This comment should not be extracted', po_contents)
+ self.assertNotIn("This comment should not be extracted", po_contents)
# Comments in templates
- self.assertIn('#. Translators: This comment should be extracted', po_contents)
+ self.assertIn(
+ "#. Translators: This comment should be extracted", po_contents
+ )
self.assertIn(
"#. Translators: Django comment block for translators\n#. "
"string's meaning unveiled",
- po_contents
+ po_contents,
+ )
+ self.assertIn("#. Translators: One-line translator comment #1", po_contents)
+ self.assertIn(
+ "#. Translators: Two-line translator comment #1\n#. continued here.",
+ po_contents,
+ )
+ self.assertIn("#. Translators: One-line translator comment #2", po_contents)
+ self.assertIn(
+ "#. Translators: Two-line translator comment #2\n#. continued here.",
+ po_contents,
+ )
+ self.assertIn("#. Translators: One-line translator comment #3", po_contents)
+ self.assertIn(
+ "#. Translators: Two-line translator comment #3\n#. continued here.",
+ po_contents,
+ )
+ self.assertIn("#. Translators: One-line translator comment #4", po_contents)
+ self.assertIn(
+ "#. Translators: Two-line translator comment #4\n#. continued here.",
+ po_contents,
)
- self.assertIn('#. Translators: One-line translator comment #1', po_contents)
- self.assertIn('#. Translators: Two-line translator comment #1\n#. continued here.', po_contents)
- self.assertIn('#. Translators: One-line translator comment #2', po_contents)
- self.assertIn('#. Translators: Two-line translator comment #2\n#. continued here.', po_contents)
- self.assertIn('#. Translators: One-line translator comment #3', po_contents)
- self.assertIn('#. Translators: Two-line translator comment #3\n#. continued here.', po_contents)
- self.assertIn('#. Translators: One-line translator comment #4', po_contents)
- self.assertIn('#. Translators: Two-line translator comment #4\n#. continued here.', po_contents)
self.assertIn(
- '#. Translators: One-line translator comment #5 -- with '
- 'non ASCII characters: áéíóúö',
- po_contents
+ "#. Translators: One-line translator comment #5 -- with "
+ "non ASCII characters: áéíóúö",
+ po_contents,
)
self.assertIn(
- '#. Translators: Two-line translator comment #5 -- with '
- 'non ASCII characters: áéíóúö\n#. continued here.',
- po_contents
+ "#. Translators: Two-line translator comment #5 -- with "
+ "non ASCII characters: áéíóúö\n#. continued here.",
+ po_contents,
)
def test_special_char_extracted(self):
- management.call_command('makemessages', locale=[LOCALE], verbosity=0)
+ management.call_command("makemessages", locale=[LOCALE], verbosity=0)
self.assertTrue(os.path.exists(self.PO_FILE))
- with open(self.PO_FILE, encoding='utf-8') as fp:
+ with open(self.PO_FILE, encoding="utf-8") as fp:
po_contents = fp.read()
self.assertMsgId("Non-breaking space\u00a0:", po_contents)
def test_blocktranslate_trimmed(self):
- management.call_command('makemessages', locale=[LOCALE], verbosity=0)
+ management.call_command("makemessages", locale=[LOCALE], verbosity=0)
self.assertTrue(os.path.exists(self.PO_FILE))
with open(self.PO_FILE) as fp:
po_contents = fp.read()
# should not be trimmed
- self.assertNotMsgId('Text with a few line breaks.', po_contents)
+ self.assertNotMsgId("Text with a few line breaks.", po_contents)
# should be trimmed
- self.assertMsgId("Again some text with a few line breaks, this time should be trimmed.", po_contents)
+ self.assertMsgId(
+ "Again some text with a few line breaks, this time should be trimmed.",
+ po_contents,
+ )
# #21406 -- Should adjust for eaten line numbers
self.assertMsgId("Get my line number", po_contents)
- self.assertLocationCommentPresent(self.PO_FILE, 'Get my line number', 'templates', 'test.html')
+ self.assertLocationCommentPresent(
+ self.PO_FILE, "Get my line number", "templates", "test.html"
+ )
def test_extraction_error(self):
msg = (
- 'Translation blocks must not include other block tags: blocktranslate '
- '(file %s, line 3)' % os.path.join('templates', 'template_with_error.tpl')
+ "Translation blocks must not include other block tags: blocktranslate "
+ "(file %s, line 3)" % os.path.join("templates", "template_with_error.tpl")
)
with self.assertRaisesMessage(SyntaxError, msg):
- management.call_command('makemessages', locale=[LOCALE], extensions=['tpl'], verbosity=0)
+ management.call_command(
+ "makemessages", locale=[LOCALE], extensions=["tpl"], verbosity=0
+ )
# The temporary files were cleaned up.
- self.assertFalse(os.path.exists('./templates/template_with_error.tpl.py'))
- self.assertFalse(os.path.exists('./templates/template_0_with_no_error.tpl.py'))
+ self.assertFalse(os.path.exists("./templates/template_with_error.tpl.py"))
+ self.assertFalse(os.path.exists("./templates/template_0_with_no_error.tpl.py"))
def test_unicode_decode_error(self):
- shutil.copyfile('./not_utf8.sample', './not_utf8.txt')
+ shutil.copyfile("./not_utf8.sample", "./not_utf8.txt")
out = StringIO()
- management.call_command('makemessages', locale=[LOCALE], stdout=out)
- self.assertIn("UnicodeDecodeError: skipped file not_utf8.txt in .", out.getvalue())
+ management.call_command("makemessages", locale=[LOCALE], stdout=out)
+ self.assertIn(
+ "UnicodeDecodeError: skipped file not_utf8.txt in .", out.getvalue()
+ )
def test_unicode_file_name(self):
- open(os.path.join(self.test_dir, 'vidéo.txt'), 'a').close()
- management.call_command('makemessages', locale=[LOCALE], verbosity=0)
+ open(os.path.join(self.test_dir, "vidéo.txt"), "a").close()
+ management.call_command("makemessages", locale=[LOCALE], verbosity=0)
def test_extraction_warning(self):
"""test xgettext warning about multiple bare interpolation placeholders"""
- shutil.copyfile('./code.sample', './code_sample.py')
+ shutil.copyfile("./code.sample", "./code_sample.py")
out = StringIO()
- management.call_command('makemessages', locale=[LOCALE], stdout=out)
+ management.call_command("makemessages", locale=[LOCALE], stdout=out)
self.assertIn("code_sample.py:4", out.getvalue())
def test_template_message_context_extractor(self):
@@ -252,7 +290,7 @@ class BasicExtractorTests(ExtractorTests):
Message contexts are correctly extracted for the {% translate %} and
{% blocktranslate %} template tags (#14806).
"""
- management.call_command('makemessages', locale=[LOCALE], verbosity=0)
+ management.call_command("makemessages", locale=[LOCALE], verbosity=0)
self.assertTrue(os.path.exists(self.PO_FILE))
with open(self.PO_FILE) as fp:
po_contents = fp.read()
@@ -265,9 +303,15 @@ class BasicExtractorTests(ExtractorTests):
self.assertMsgId("Translatable literal #7c", po_contents)
# {% translate %} with a filter
- for minor_part in 'abcdefgh': # Iterate from #7.1a to #7.1h template markers
- self.assertIn('msgctxt "context #7.1{}"'.format(minor_part), po_contents)
- self.assertMsgId('Translatable literal #7.1{}'.format(minor_part), po_contents)
+ for (
+ minor_part
+ ) in "abcdefgh": # Iterate from #7.1a to #7.1h template markers
+ self.assertIn(
+ 'msgctxt "context #7.1{}"'.format(minor_part), po_contents
+ )
+ self.assertMsgId(
+ "Translatable literal #7.1{}".format(minor_part), po_contents
+ )
# {% blocktranslate %}
self.assertIn('msgctxt "Special blocktranslate context #1"', po_contents)
@@ -282,11 +326,11 @@ class BasicExtractorTests(ExtractorTests):
self.assertMsgId("Translatable literal #8d %(a)s", po_contents)
# {% trans %} and {% blocktrans %}
- self.assertMsgId('trans text', po_contents)
- self.assertMsgId('blocktrans text', po_contents)
+ self.assertMsgId("trans text", po_contents)
+ self.assertMsgId("blocktrans text", po_contents)
def test_context_in_single_quotes(self):
- management.call_command('makemessages', locale=[LOCALE], verbosity=0)
+ management.call_command("makemessages", locale=[LOCALE], verbosity=0)
self.assertTrue(os.path.exists(self.PO_FILE))
with open(self.PO_FILE) as fp:
po_contents = fp.read()
@@ -295,16 +339,24 @@ class BasicExtractorTests(ExtractorTests):
self.assertIn('msgctxt "Context wrapped in single quotes"', po_contents)
# {% blocktranslate %}
- self.assertIn('msgctxt "Special blocktranslate context wrapped in double quotes"', po_contents)
- self.assertIn('msgctxt "Special blocktranslate context wrapped in single quotes"', po_contents)
+ self.assertIn(
+ 'msgctxt "Special blocktranslate context wrapped in double quotes"',
+ po_contents,
+ )
+ self.assertIn(
+ 'msgctxt "Special blocktranslate context wrapped in single quotes"',
+ po_contents,
+ )
def test_template_comments(self):
"""Template comment tags on the same line of other constructs (#19552)"""
# Test detection/end user reporting of old, incorrect templates
# translator comments syntax
with warnings.catch_warnings(record=True) as ws:
- warnings.simplefilter('always')
- management.call_command('makemessages', locale=[LOCALE], extensions=['thtml'], verbosity=0)
+ warnings.simplefilter("always")
+ management.call_command(
+ "makemessages", locale=[LOCALE], extensions=["thtml"], verbosity=0
+ )
self.assertEqual(len(ws), 3)
for w in ws:
self.assertTrue(issubclass(w.category, TranslatorCommentWarning))
@@ -312,55 +364,55 @@ class BasicExtractorTests(ExtractorTests):
str(ws[0].message),
r"The translator-targeted comment 'Translators: ignored i18n "
r"comment #1' \(file templates[/\\]comments.thtml, line 4\) "
- r"was ignored, because it wasn't the last item on the line\."
+ r"was ignored, because it wasn't the last item on the line\.",
)
self.assertRegex(
str(ws[1].message),
r"The translator-targeted comment 'Translators: ignored i18n "
r"comment #3' \(file templates[/\\]comments.thtml, line 6\) "
- r"was ignored, because it wasn't the last item on the line\."
+ r"was ignored, because it wasn't the last item on the line\.",
)
self.assertRegex(
str(ws[2].message),
r"The translator-targeted comment 'Translators: ignored i18n "
r"comment #4' \(file templates[/\\]comments.thtml, line 8\) "
- r"was ignored, because it wasn't the last item on the line\."
+ r"was ignored, because it wasn't the last item on the line\.",
)
# Now test .po file contents
self.assertTrue(os.path.exists(self.PO_FILE))
with open(self.PO_FILE) as fp:
po_contents = fp.read()
- self.assertMsgId('Translatable literal #9a', po_contents)
- self.assertNotIn('ignored comment #1', po_contents)
+ self.assertMsgId("Translatable literal #9a", po_contents)
+ self.assertNotIn("ignored comment #1", po_contents)
- self.assertNotIn('Translators: ignored i18n comment #1', po_contents)
+ self.assertNotIn("Translators: ignored i18n comment #1", po_contents)
self.assertMsgId("Translatable literal #9b", po_contents)
- self.assertNotIn('ignored i18n comment #2', po_contents)
- self.assertNotIn('ignored comment #2', po_contents)
- self.assertMsgId('Translatable literal #9c', po_contents)
+ self.assertNotIn("ignored i18n comment #2", po_contents)
+ self.assertNotIn("ignored comment #2", po_contents)
+ self.assertMsgId("Translatable literal #9c", po_contents)
- self.assertNotIn('ignored comment #3', po_contents)
- self.assertNotIn('ignored i18n comment #3', po_contents)
- self.assertMsgId('Translatable literal #9d', po_contents)
+ self.assertNotIn("ignored comment #3", po_contents)
+ self.assertNotIn("ignored i18n comment #3", po_contents)
+ self.assertMsgId("Translatable literal #9d", po_contents)
- self.assertNotIn('ignored comment #4', po_contents)
- self.assertMsgId('Translatable literal #9e', po_contents)
- self.assertNotIn('ignored comment #5', po_contents)
+ self.assertNotIn("ignored comment #4", po_contents)
+ self.assertMsgId("Translatable literal #9e", po_contents)
+ self.assertNotIn("ignored comment #5", po_contents)
- self.assertNotIn('ignored i18n comment #4', po_contents)
- self.assertMsgId('Translatable literal #9f', po_contents)
- self.assertIn('#. Translators: valid i18n comment #5', po_contents)
+ self.assertNotIn("ignored i18n comment #4", po_contents)
+ self.assertMsgId("Translatable literal #9f", po_contents)
+ self.assertIn("#. Translators: valid i18n comment #5", po_contents)
- self.assertMsgId('Translatable literal #9g', po_contents)
- self.assertIn('#. Translators: valid i18n comment #6', po_contents)
- self.assertMsgId('Translatable literal #9h', po_contents)
- self.assertIn('#. Translators: valid i18n comment #7', po_contents)
- self.assertMsgId('Translatable literal #9i', po_contents)
+ self.assertMsgId("Translatable literal #9g", po_contents)
+ self.assertIn("#. Translators: valid i18n comment #6", po_contents)
+ self.assertMsgId("Translatable literal #9h", po_contents)
+ self.assertIn("#. Translators: valid i18n comment #7", po_contents)
+ self.assertMsgId("Translatable literal #9i", po_contents)
- self.assertRegex(po_contents, r'#\..+Translators: valid i18n comment #8')
- self.assertRegex(po_contents, r'#\..+Translators: valid i18n comment #9')
+ self.assertRegex(po_contents, r"#\..+Translators: valid i18n comment #8")
+ self.assertRegex(po_contents, r"#\..+Translators: valid i18n comment #9")
self.assertMsgId("Translatable literal #9j", po_contents)
def test_makemessages_find_files(self):
@@ -368,24 +420,24 @@ class BasicExtractorTests(ExtractorTests):
find_files only discover files having the proper extensions.
"""
cmd = MakeMessagesCommand()
- cmd.ignore_patterns = ['CVS', '.*', '*~', '*.pyc']
+ cmd.ignore_patterns = ["CVS", ".*", "*~", "*.pyc"]
cmd.symlinks = False
- cmd.domain = 'django'
- cmd.extensions = ['html', 'txt', 'py']
+ cmd.domain = "django"
+ cmd.extensions = ["html", "txt", "py"]
cmd.verbosity = 0
cmd.locale_paths = []
- cmd.default_locale_path = os.path.join(self.test_dir, 'locale')
+ cmd.default_locale_path = os.path.join(self.test_dir, "locale")
found_files = cmd.find_files(self.test_dir)
found_exts = {os.path.splitext(tfile.file)[1] for tfile in found_files}
- self.assertEqual(found_exts.difference({'.py', '.html', '.txt'}), set())
+ self.assertEqual(found_exts.difference({".py", ".html", ".txt"}), set())
- cmd.extensions = ['js']
- cmd.domain = 'djangojs'
+ cmd.extensions = ["js"]
+ cmd.domain = "djangojs"
found_files = cmd.find_files(self.test_dir)
found_exts = {os.path.splitext(tfile.file)[1] for tfile in found_files}
- self.assertEqual(found_exts.difference({'.js'}), set())
+ self.assertEqual(found_exts.difference({".js"}), set())
- @mock.patch('django.core.management.commands.makemessages.popen_wrapper')
+ @mock.patch("django.core.management.commands.makemessages.popen_wrapper")
def test_makemessages_gettext_version(self, mocked_popen_wrapper):
# "Normal" output:
mocked_popen_wrapper.return_value = (
@@ -394,21 +446,28 @@ class BasicExtractorTests(ExtractorTests):
"License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n"
"This is free software: you are free to change and redistribute it.\n"
"There is NO WARRANTY, to the extent permitted by law.\n"
- "Written by Ulrich Drepper.\n", '', 0)
+ "Written by Ulrich Drepper.\n",
+ "",
+ 0,
+ )
cmd = MakeMessagesCommand()
self.assertEqual(cmd.gettext_version, (0, 18, 1))
# Version number with only 2 parts (#23788)
mocked_popen_wrapper.return_value = (
- "xgettext (GNU gettext-tools) 0.17\n", '', 0)
+ "xgettext (GNU gettext-tools) 0.17\n",
+ "",
+ 0,
+ )
cmd = MakeMessagesCommand()
self.assertEqual(cmd.gettext_version, (0, 17))
# Bad version output
- mocked_popen_wrapper.return_value = (
- "any other return value\n", '', 0)
+ mocked_popen_wrapper.return_value = ("any other return value\n", "", 0)
cmd = MakeMessagesCommand()
- with self.assertRaisesMessage(CommandError, "Unable to get gettext version. Is it installed?"):
+ with self.assertRaisesMessage(
+ CommandError, "Unable to get gettext version. Is it installed?"
+ ):
cmd.gettext_version
def test_po_file_encoding_when_updating(self):
@@ -416,50 +475,53 @@ class BasicExtractorTests(ExtractorTests):
Update of PO file doesn't corrupt it with non-UTF-8 encoding on Windows
(#23271).
"""
- BR_PO_BASE = 'locale/pt_BR/LC_MESSAGES/django'
- shutil.copyfile(BR_PO_BASE + '.pristine', BR_PO_BASE + '.po')
- management.call_command('makemessages', locale=['pt_BR'], verbosity=0)
- self.assertTrue(os.path.exists(BR_PO_BASE + '.po'))
- with open(BR_PO_BASE + '.po', encoding='utf-8') as fp:
+ BR_PO_BASE = "locale/pt_BR/LC_MESSAGES/django"
+ shutil.copyfile(BR_PO_BASE + ".pristine", BR_PO_BASE + ".po")
+ management.call_command("makemessages", locale=["pt_BR"], verbosity=0)
+ self.assertTrue(os.path.exists(BR_PO_BASE + ".po"))
+ with open(BR_PO_BASE + ".po", encoding="utf-8") as fp:
po_contents = fp.read()
self.assertMsgStr("Größe", po_contents)
def test_pot_charset_header_is_utf8(self):
"""Content-Type: ... charset=CHARSET is replaced with charset=UTF-8"""
msgs = (
- '# SOME DESCRIPTIVE TITLE.\n'
- '# (some lines truncated as they are not relevant)\n'
+ "# SOME DESCRIPTIVE TITLE.\n"
+ "# (some lines truncated as they are not relevant)\n"
'"Content-Type: text/plain; charset=CHARSET\\n"\n'
'"Content-Transfer-Encoding: 8bit\\n"\n'
- '\n'
- '#: somefile.py:8\n'
+ "\n"
+ "#: somefile.py:8\n"
'msgid "mañana; charset=CHARSET"\n'
'msgstr ""\n'
)
with tempfile.NamedTemporaryFile() as pot_file:
pot_filename = pot_file.name
write_pot_file(pot_filename, msgs)
- with open(pot_filename, encoding='utf-8') as fp:
+ with open(pot_filename, encoding="utf-8") as fp:
pot_contents = fp.read()
- self.assertIn('Content-Type: text/plain; charset=UTF-8', pot_contents)
- self.assertIn('mañana; charset=CHARSET', pot_contents)
+ self.assertIn("Content-Type: text/plain; charset=UTF-8", pot_contents)
+ self.assertIn("mañana; charset=CHARSET", pot_contents)
class JavaScriptExtractorTests(ExtractorTests):
- PO_FILE = 'locale/%s/LC_MESSAGES/djangojs.po' % LOCALE
+ PO_FILE = "locale/%s/LC_MESSAGES/djangojs.po" % LOCALE
def test_javascript_literals(self):
- _, po_contents = self._run_makemessages(domain='djangojs')
- self.assertMsgId('This literal should be included.', po_contents)
- self.assertMsgId('gettext_noop should, too.', po_contents)
- self.assertMsgId('This one as well.', po_contents)
- self.assertMsgId(r'He said, \"hello\".', po_contents)
+ _, po_contents = self._run_makemessages(domain="djangojs")
+ self.assertMsgId("This literal should be included.", po_contents)
+ self.assertMsgId("gettext_noop should, too.", po_contents)
+ self.assertMsgId("This one as well.", po_contents)
+ self.assertMsgId(r"He said, \"hello\".", po_contents)
self.assertMsgId("okkkk", po_contents)
self.assertMsgId("TEXT", po_contents)
self.assertMsgId("It's at http://example.com", po_contents)
self.assertMsgId("String", po_contents)
- self.assertMsgId("/* but this one will be too */ 'cause there is no way of telling...", po_contents)
+ self.assertMsgId(
+ "/* but this one will be too */ 'cause there is no way of telling...",
+ po_contents,
+ )
self.assertMsgId("foo", po_contents)
self.assertMsgId("bar", po_contents)
self.assertMsgId("baz", po_contents)
@@ -470,91 +532,115 @@ class JavaScriptExtractorTests(ExtractorTests):
"""
Regression test for #23583.
"""
- with override_settings(STATIC_ROOT=os.path.join(self.test_dir, 'static/'),
- MEDIA_ROOT=os.path.join(self.test_dir, 'media_root/')):
- _, po_contents = self._run_makemessages(domain='djangojs')
- self.assertMsgId("Static content inside app should be included.", po_contents)
- self.assertNotMsgId("Content from STATIC_ROOT should not be included", po_contents)
+ with override_settings(
+ STATIC_ROOT=os.path.join(self.test_dir, "static/"),
+ MEDIA_ROOT=os.path.join(self.test_dir, "media_root/"),
+ ):
+ _, po_contents = self._run_makemessages(domain="djangojs")
+ self.assertMsgId(
+ "Static content inside app should be included.", po_contents
+ )
+ self.assertNotMsgId(
+ "Content from STATIC_ROOT should not be included", po_contents
+ )
- @override_settings(STATIC_ROOT=None, MEDIA_ROOT='')
+ @override_settings(STATIC_ROOT=None, MEDIA_ROOT="")
def test_default_root_settings(self):
"""
Regression test for #23717.
"""
- _, po_contents = self._run_makemessages(domain='djangojs')
+ _, po_contents = self._run_makemessages(domain="djangojs")
self.assertMsgId("Static content inside app should be included.", po_contents)
class IgnoredExtractorTests(ExtractorTests):
-
def test_ignore_directory(self):
- out, po_contents = self._run_makemessages(ignore_patterns=[
- os.path.join('ignore_dir', '*'),
- ])
+ out, po_contents = self._run_makemessages(
+ ignore_patterns=[
+ os.path.join("ignore_dir", "*"),
+ ]
+ )
self.assertIn("ignoring directory ignore_dir", out)
- self.assertMsgId('This literal should be included.', po_contents)
- self.assertNotMsgId('This should be ignored.', po_contents)
+ self.assertMsgId("This literal should be included.", po_contents)
+ self.assertNotMsgId("This should be ignored.", po_contents)
def test_ignore_subdirectory(self):
- out, po_contents = self._run_makemessages(ignore_patterns=[
- 'templates/*/ignore.html',
- 'templates/subdir/*',
- ])
+ out, po_contents = self._run_makemessages(
+ ignore_patterns=[
+ "templates/*/ignore.html",
+ "templates/subdir/*",
+ ]
+ )
self.assertIn("ignoring directory subdir", out)
- self.assertNotMsgId('This subdir should be ignored too.', po_contents)
+ self.assertNotMsgId("This subdir should be ignored too.", po_contents)
def test_ignore_file_patterns(self):
- out, po_contents = self._run_makemessages(ignore_patterns=[
- 'xxx_*',
- ])
+ out, po_contents = self._run_makemessages(
+ ignore_patterns=[
+ "xxx_*",
+ ]
+ )
self.assertIn("ignoring file xxx_ignored.html", out)
- self.assertNotMsgId('This should be ignored too.', po_contents)
+ self.assertNotMsgId("This should be ignored too.", po_contents)
def test_media_static_dirs_ignored(self):
- with override_settings(STATIC_ROOT=os.path.join(self.test_dir, 'static/'),
- MEDIA_ROOT=os.path.join(self.test_dir, 'media_root/')):
+ with override_settings(
+ STATIC_ROOT=os.path.join(self.test_dir, "static/"),
+ MEDIA_ROOT=os.path.join(self.test_dir, "media_root/"),
+ ):
out, _ = self._run_makemessages()
self.assertIn("ignoring directory static", out)
self.assertIn("ignoring directory media_root", out)
class SymlinkExtractorTests(ExtractorTests):
-
def setUp(self):
super().setUp()
- self.symlinked_dir = os.path.join(self.test_dir, 'templates_symlinked')
+ self.symlinked_dir = os.path.join(self.test_dir, "templates_symlinked")
def test_symlink(self):
if symlinks_supported():
- os.symlink(os.path.join(self.test_dir, 'templates'), self.symlinked_dir)
+ os.symlink(os.path.join(self.test_dir, "templates"), self.symlinked_dir)
else:
- self.skipTest("os.symlink() not available on this OS + Python version combination.")
- management.call_command('makemessages', locale=[LOCALE], verbosity=0, symlinks=True)
+ self.skipTest(
+ "os.symlink() not available on this OS + Python version combination."
+ )
+ management.call_command(
+ "makemessages", locale=[LOCALE], verbosity=0, symlinks=True
+ )
self.assertTrue(os.path.exists(self.PO_FILE))
with open(self.PO_FILE) as fp:
po_contents = fp.read()
- self.assertMsgId('This literal should be included.', po_contents)
- self.assertLocationCommentPresent(self.PO_FILE, None, 'templates_symlinked', 'test.html')
+ self.assertMsgId("This literal should be included.", po_contents)
+ self.assertLocationCommentPresent(
+ self.PO_FILE, None, "templates_symlinked", "test.html"
+ )
class CopyPluralFormsExtractorTests(ExtractorTests):
- PO_FILE_ES = 'locale/es/LC_MESSAGES/django.po'
+ PO_FILE_ES = "locale/es/LC_MESSAGES/django.po"
def test_copy_plural_forms(self):
- management.call_command('makemessages', locale=[LOCALE], verbosity=0)
+ management.call_command("makemessages", locale=[LOCALE], verbosity=0)
self.assertTrue(os.path.exists(self.PO_FILE))
with open(self.PO_FILE) as fp:
po_contents = fp.read()
- self.assertIn('Plural-Forms: nplurals=2; plural=(n != 1)', po_contents)
+ self.assertIn("Plural-Forms: nplurals=2; plural=(n != 1)", po_contents)
def test_override_plural_forms(self):
"""Ticket #20311."""
- management.call_command('makemessages', locale=['es'], extensions=['djtpl'], verbosity=0)
+ management.call_command(
+ "makemessages", locale=["es"], extensions=["djtpl"], verbosity=0
+ )
self.assertTrue(os.path.exists(self.PO_FILE_ES))
- with open(self.PO_FILE_ES, encoding='utf-8') as fp:
+ with open(self.PO_FILE_ES, encoding="utf-8") as fp:
po_contents = fp.read()
- found = re.findall(r'^(?P<value>"Plural-Forms.+?\\n")\s*$', po_contents, re.MULTILINE | re.DOTALL)
+ found = re.findall(
+ r'^(?P<value>"Plural-Forms.+?\\n")\s*$',
+ po_contents,
+ re.MULTILINE | re.DOTALL,
+ )
self.assertEqual(1, len(found))
def test_translate_and_plural_blocktranslate_collision(self):
@@ -563,30 +649,42 @@ class CopyPluralFormsExtractorTests(ExtractorTests):
found inside a {% translate %} tag and also in another file inside a
{% blocktranslate %} with a plural (#17375).
"""
- management.call_command('makemessages', locale=[LOCALE], extensions=['html', 'djtpl'], verbosity=0)
+ management.call_command(
+ "makemessages", locale=[LOCALE], extensions=["html", "djtpl"], verbosity=0
+ )
self.assertTrue(os.path.exists(self.PO_FILE))
with open(self.PO_FILE) as fp:
po_contents = fp.read()
- self.assertNotIn("#-#-#-#-# django.pot (PACKAGE VERSION) #-#-#-#-#\\n", po_contents)
- self.assertMsgId('First `translate`, then `blocktranslate` with a plural', po_contents)
- self.assertMsgIdPlural('Plural for a `translate` and `blocktranslate` collision case', po_contents)
+ self.assertNotIn(
+ "#-#-#-#-# django.pot (PACKAGE VERSION) #-#-#-#-#\\n", po_contents
+ )
+ self.assertMsgId(
+ "First `translate`, then `blocktranslate` with a plural", po_contents
+ )
+ self.assertMsgIdPlural(
+ "Plural for a `translate` and `blocktranslate` collision case",
+ po_contents,
+ )
class NoWrapExtractorTests(ExtractorTests):
-
def test_no_wrap_enabled(self):
- management.call_command('makemessages', locale=[LOCALE], verbosity=0, no_wrap=True)
+ management.call_command(
+ "makemessages", locale=[LOCALE], verbosity=0, no_wrap=True
+ )
self.assertTrue(os.path.exists(self.PO_FILE))
with open(self.PO_FILE) as fp:
po_contents = fp.read()
self.assertMsgId(
- 'This literal should also be included wrapped or not wrapped '
- 'depending on the use of the --no-wrap option.',
- po_contents
+ "This literal should also be included wrapped or not wrapped "
+ "depending on the use of the --no-wrap option.",
+ po_contents,
)
def test_no_wrap_disabled(self):
- management.call_command('makemessages', locale=[LOCALE], verbosity=0, no_wrap=False)
+ management.call_command(
+ "makemessages", locale=[LOCALE], verbosity=0, no_wrap=False
+ )
self.assertTrue(os.path.exists(self.PO_FILE))
with open(self.PO_FILE) as fp:
po_contents = fp.read()
@@ -594,64 +692,82 @@ class NoWrapExtractorTests(ExtractorTests):
'""\n"This literal should also be included wrapped or not '
'wrapped depending on the "\n"use of the --no-wrap option."',
po_contents,
- use_quotes=False
+ use_quotes=False,
)
class LocationCommentsTests(ExtractorTests):
-
def test_no_location_enabled(self):
"""Behavior is correct if --no-location switch is specified. See #16903."""
- management.call_command('makemessages', locale=[LOCALE], verbosity=0, no_location=True)
+ management.call_command(
+ "makemessages", locale=[LOCALE], verbosity=0, no_location=True
+ )
self.assertTrue(os.path.exists(self.PO_FILE))
- self.assertLocationCommentNotPresent(self.PO_FILE, None, 'test.html')
+ self.assertLocationCommentNotPresent(self.PO_FILE, None, "test.html")
def test_no_location_disabled(self):
"""Behavior is correct if --no-location switch isn't specified."""
- management.call_command('makemessages', locale=[LOCALE], verbosity=0, no_location=False)
+ management.call_command(
+ "makemessages", locale=[LOCALE], verbosity=0, no_location=False
+ )
self.assertTrue(os.path.exists(self.PO_FILE))
# #16903 -- Standard comment with source file relative path should be present
- self.assertLocationCommentPresent(self.PO_FILE, 'Translatable literal #6b', 'templates', 'test.html')
+ self.assertLocationCommentPresent(
+ self.PO_FILE, "Translatable literal #6b", "templates", "test.html"
+ )
def test_location_comments_for_templatized_files(self):
"""
Ensure no leaky paths in comments, e.g. #: path\to\file.html.py:123
Refs #21209/#26341.
"""
- management.call_command('makemessages', locale=[LOCALE], verbosity=0)
+ management.call_command("makemessages", locale=[LOCALE], verbosity=0)
self.assertTrue(os.path.exists(self.PO_FILE))
with open(self.PO_FILE) as fp:
po_contents = fp.read()
- self.assertMsgId('#: templates/test.html.py', po_contents)
- self.assertLocationCommentNotPresent(self.PO_FILE, None, '.html.py')
- self.assertLocationCommentPresent(self.PO_FILE, 5, 'templates', 'test.html')
+ self.assertMsgId("#: templates/test.html.py", po_contents)
+ self.assertLocationCommentNotPresent(self.PO_FILE, None, ".html.py")
+ self.assertLocationCommentPresent(self.PO_FILE, 5, "templates", "test.html")
@requires_gettext_019
def test_add_location_full(self):
"""makemessages --add-location=full"""
- management.call_command('makemessages', locale=[LOCALE], verbosity=0, add_location='full')
+ management.call_command(
+ "makemessages", locale=[LOCALE], verbosity=0, add_location="full"
+ )
self.assertTrue(os.path.exists(self.PO_FILE))
# Comment with source file relative path and line number is present.
- self.assertLocationCommentPresent(self.PO_FILE, 'Translatable literal #6b', 'templates', 'test.html')
+ self.assertLocationCommentPresent(
+ self.PO_FILE, "Translatable literal #6b", "templates", "test.html"
+ )
@requires_gettext_019
def test_add_location_file(self):
"""makemessages --add-location=file"""
- management.call_command('makemessages', locale=[LOCALE], verbosity=0, add_location='file')
+ management.call_command(
+ "makemessages", locale=[LOCALE], verbosity=0, add_location="file"
+ )
self.assertTrue(os.path.exists(self.PO_FILE))
# Comment with source file relative path is present.
- self.assertLocationCommentPresent(self.PO_FILE, None, 'templates', 'test.html')
+ self.assertLocationCommentPresent(self.PO_FILE, None, "templates", "test.html")
# But it should not contain the line number.
- self.assertLocationCommentNotPresent(self.PO_FILE, 'Translatable literal #6b', 'templates', 'test.html')
+ self.assertLocationCommentNotPresent(
+ self.PO_FILE, "Translatable literal #6b", "templates", "test.html"
+ )
@requires_gettext_019
def test_add_location_never(self):
"""makemessages --add-location=never"""
- management.call_command('makemessages', locale=[LOCALE], verbosity=0, add_location='never')
+ management.call_command(
+ "makemessages", locale=[LOCALE], verbosity=0, add_location="never"
+ )
self.assertTrue(os.path.exists(self.PO_FILE))
- self.assertLocationCommentNotPresent(self.PO_FILE, None, 'test.html')
+ self.assertLocationCommentNotPresent(self.PO_FILE, None, "test.html")
- @mock.patch('django.core.management.commands.makemessages.Command.gettext_version', new=(0, 18, 99))
+ @mock.patch(
+ "django.core.management.commands.makemessages.Command.gettext_version",
+ new=(0, 18, 99),
+ )
def test_add_location_gettext_version_check(self):
"""
CommandError is raised when using makemessages --add-location with
@@ -659,34 +775,40 @@ class LocationCommentsTests(ExtractorTests):
"""
msg = "The --add-location option requires gettext 0.19 or later. You have 0.18.99."
with self.assertRaisesMessage(CommandError, msg):
- management.call_command('makemessages', locale=[LOCALE], verbosity=0, add_location='full')
+ management.call_command(
+ "makemessages", locale=[LOCALE], verbosity=0, add_location="full"
+ )
class KeepPotFileExtractorTests(ExtractorTests):
- POT_FILE = 'locale/django.pot'
+ POT_FILE = "locale/django.pot"
def test_keep_pot_disabled_by_default(self):
- management.call_command('makemessages', locale=[LOCALE], verbosity=0)
+ management.call_command("makemessages", locale=[LOCALE], verbosity=0)
self.assertFalse(os.path.exists(self.POT_FILE))
def test_keep_pot_explicitly_disabled(self):
- management.call_command('makemessages', locale=[LOCALE], verbosity=0, keep_pot=False)
+ management.call_command(
+ "makemessages", locale=[LOCALE], verbosity=0, keep_pot=False
+ )
self.assertFalse(os.path.exists(self.POT_FILE))
def test_keep_pot_enabled(self):
- management.call_command('makemessages', locale=[LOCALE], verbosity=0, keep_pot=True)
+ management.call_command(
+ "makemessages", locale=[LOCALE], verbosity=0, keep_pot=True
+ )
self.assertTrue(os.path.exists(self.POT_FILE))
class MultipleLocaleExtractionTests(ExtractorTests):
- PO_FILE_PT = 'locale/pt/LC_MESSAGES/django.po'
- PO_FILE_DE = 'locale/de/LC_MESSAGES/django.po'
- PO_FILE_KO = 'locale/ko/LC_MESSAGES/django.po'
- LOCALES = ['pt', 'de', 'ch']
+ PO_FILE_PT = "locale/pt/LC_MESSAGES/django.po"
+ PO_FILE_DE = "locale/de/LC_MESSAGES/django.po"
+ PO_FILE_KO = "locale/ko/LC_MESSAGES/django.po"
+ LOCALES = ["pt", "de", "ch"]
def test_multiple_locales(self):
- management.call_command('makemessages', locale=['pt', 'de'], verbosity=0)
+ management.call_command("makemessages", locale=["pt", "de"], verbosity=0)
self.assertTrue(os.path.exists(self.PO_FILE_PT))
self.assertTrue(os.path.exists(self.PO_FILE_DE))
@@ -696,19 +818,19 @@ class MultipleLocaleExtractionTests(ExtractorTests):
are considered as language directories, except if the directory doesn't
start with two letters (which excludes __pycache__, .gitignore, etc.).
"""
- os.mkdir(os.path.join('locale', '_do_not_pick'))
+ os.mkdir(os.path.join("locale", "_do_not_pick"))
# Excluding locales that do not compile
- management.call_command('makemessages', exclude=['ja', 'es_AR'], verbosity=0)
+ management.call_command("makemessages", exclude=["ja", "es_AR"], verbosity=0)
self.assertTrue(os.path.exists(self.PO_FILE_KO))
- self.assertFalse(os.path.exists('locale/_do_not_pick/LC_MESSAGES/django.po'))
+ self.assertFalse(os.path.exists("locale/_do_not_pick/LC_MESSAGES/django.po"))
class ExcludedLocaleExtractionTests(ExtractorTests):
- work_subdir = 'exclude'
+ work_subdir = "exclude"
- LOCALES = ['en', 'fr', 'it']
- PO_FILE = 'locale/%s/LC_MESSAGES/django.po'
+ LOCALES = ["en", "fr", "it"]
+ PO_FILE = "locale/%s/LC_MESSAGES/django.po"
def _set_times_for_all_po_files(self):
"""
@@ -719,7 +841,7 @@ class ExcludedLocaleExtractionTests(ExtractorTests):
def setUp(self):
super().setUp()
- copytree('canned_locale', 'locale')
+ copytree("canned_locale", "locale")
self._set_times_for_all_po_files()
def test_command_help(self):
@@ -727,36 +849,40 @@ class ExcludedLocaleExtractionTests(ExtractorTests):
# `call_command` bypasses the parser; by calling
# `execute_from_command_line` with the help subcommand we
# ensure that there are no issues with the parser itself.
- execute_from_command_line(['django-admin', 'help', 'makemessages'])
+ execute_from_command_line(["django-admin", "help", "makemessages"])
def test_one_locale_excluded(self):
- management.call_command('makemessages', exclude=['it'], verbosity=0)
- self.assertRecentlyModified(self.PO_FILE % 'en')
- self.assertRecentlyModified(self.PO_FILE % 'fr')
- self.assertNotRecentlyModified(self.PO_FILE % 'it')
+ management.call_command("makemessages", exclude=["it"], verbosity=0)
+ self.assertRecentlyModified(self.PO_FILE % "en")
+ self.assertRecentlyModified(self.PO_FILE % "fr")
+ self.assertNotRecentlyModified(self.PO_FILE % "it")
def test_multiple_locales_excluded(self):
- management.call_command('makemessages', exclude=['it', 'fr'], verbosity=0)
- self.assertRecentlyModified(self.PO_FILE % 'en')
- self.assertNotRecentlyModified(self.PO_FILE % 'fr')
- self.assertNotRecentlyModified(self.PO_FILE % 'it')
+ management.call_command("makemessages", exclude=["it", "fr"], verbosity=0)
+ self.assertRecentlyModified(self.PO_FILE % "en")
+ self.assertNotRecentlyModified(self.PO_FILE % "fr")
+ self.assertNotRecentlyModified(self.PO_FILE % "it")
def test_one_locale_excluded_with_locale(self):
- management.call_command('makemessages', locale=['en', 'fr'], exclude=['fr'], verbosity=0)
- self.assertRecentlyModified(self.PO_FILE % 'en')
- self.assertNotRecentlyModified(self.PO_FILE % 'fr')
- self.assertNotRecentlyModified(self.PO_FILE % 'it')
+ management.call_command(
+ "makemessages", locale=["en", "fr"], exclude=["fr"], verbosity=0
+ )
+ self.assertRecentlyModified(self.PO_FILE % "en")
+ self.assertNotRecentlyModified(self.PO_FILE % "fr")
+ self.assertNotRecentlyModified(self.PO_FILE % "it")
def test_multiple_locales_excluded_with_locale(self):
- management.call_command('makemessages', locale=['en', 'fr', 'it'], exclude=['fr', 'it'], verbosity=0)
- self.assertRecentlyModified(self.PO_FILE % 'en')
- self.assertNotRecentlyModified(self.PO_FILE % 'fr')
- self.assertNotRecentlyModified(self.PO_FILE % 'it')
+ management.call_command(
+ "makemessages", locale=["en", "fr", "it"], exclude=["fr", "it"], verbosity=0
+ )
+ self.assertRecentlyModified(self.PO_FILE % "en")
+ self.assertNotRecentlyModified(self.PO_FILE % "fr")
+ self.assertNotRecentlyModified(self.PO_FILE % "it")
class CustomLayoutExtractionTests(ExtractorTests):
- work_subdir = 'project_dir'
+ work_subdir = "project_dir"
def test_no_locale_raises(self):
msg = (
@@ -765,15 +891,15 @@ class CustomLayoutExtractionTests(ExtractorTests):
"or LOCALE_PATHS setting is set."
)
with self.assertRaisesMessage(management.CommandError, msg):
- management.call_command('makemessages', locale=[LOCALE], verbosity=0)
+ management.call_command("makemessages", locale=[LOCALE], verbosity=0)
# Working files are cleaned up on an error.
- self.assertFalse(os.path.exists('./app_no_locale/test.html.py'))
+ self.assertFalse(os.path.exists("./app_no_locale/test.html.py"))
def test_project_locale_paths(self):
- self._test_project_locale_paths(os.path.join(self.test_dir, 'project_locale'))
+ self._test_project_locale_paths(os.path.join(self.test_dir, "project_locale"))
def test_project_locale_paths_pathlib(self):
- self._test_project_locale_paths(Path(self.test_dir) / 'project_locale')
+ self._test_project_locale_paths(Path(self.test_dir) / "project_locale")
def _test_project_locale_paths(self, locale_path):
"""
@@ -781,43 +907,50 @@ class CustomLayoutExtractionTests(ExtractorTests):
* translations outside of that app are in LOCALE_PATHS[0]
"""
with override_settings(LOCALE_PATHS=[locale_path]):
- management.call_command('makemessages', locale=[LOCALE], verbosity=0)
+ management.call_command("makemessages", locale=[LOCALE], verbosity=0)
project_de_locale = os.path.join(
- self.test_dir, 'project_locale', 'de', 'LC_MESSAGES', 'django.po')
+ self.test_dir, "project_locale", "de", "LC_MESSAGES", "django.po"
+ )
app_de_locale = os.path.join(
- self.test_dir, 'app_with_locale', 'locale', 'de', 'LC_MESSAGES', 'django.po')
+ self.test_dir,
+ "app_with_locale",
+ "locale",
+ "de",
+ "LC_MESSAGES",
+ "django.po",
+ )
self.assertTrue(os.path.exists(project_de_locale))
self.assertTrue(os.path.exists(app_de_locale))
with open(project_de_locale) as fp:
po_contents = fp.read()
- self.assertMsgId('This app has no locale directory', po_contents)
- self.assertMsgId('This is a project-level string', po_contents)
+ self.assertMsgId("This app has no locale directory", po_contents)
+ self.assertMsgId("This is a project-level string", po_contents)
with open(app_de_locale) as fp:
po_contents = fp.read()
- self.assertMsgId('This app has a locale directory', po_contents)
+ self.assertMsgId("This app has a locale directory", po_contents)
-@skipUnless(has_xgettext, 'xgettext is mandatory for extraction tests')
+@skipUnless(has_xgettext, "xgettext is mandatory for extraction tests")
class NoSettingsExtractionTests(AdminScriptTestCase):
def test_makemessages_no_settings(self):
- out, err = self.run_django_admin(['makemessages', '-l', 'en', '-v', '0'])
+ out, err = self.run_django_admin(["makemessages", "-l", "en", "-v", "0"])
self.assertNoOutput(err)
self.assertNoOutput(out)
class UnchangedPoExtractionTests(ExtractorTests):
- work_subdir = 'unchanged'
+ work_subdir = "unchanged"
def setUp(self):
super().setUp()
po_file = Path(self.PO_FILE)
- po_file_tmp = Path(self.PO_FILE + '.tmp')
- if os.name == 'nt':
+ po_file_tmp = Path(self.PO_FILE + ".tmp")
+ if os.name == "nt":
# msgmerge outputs Windows style paths on Windows.
po_contents = po_file_tmp.read_text().replace(
- '#: __init__.py',
- '#: .\\__init__.py',
+ "#: __init__.py",
+ "#: .\\__init__.py",
)
po_file.write_text(po_contents)
else:
@@ -831,10 +964,10 @@ class UnchangedPoExtractionTests(ExtractorTests):
def test_po_changed_with_new_strings(self):
"""PO files are updated when new changes are detected."""
- Path('models.py.tmp').rename('models.py')
+ Path("models.py.tmp").rename("models.py")
_, po_contents = self._run_makemessages()
self.assertNotEqual(po_contents, self.original_po_contents)
self.assertMsgId(
- 'This is a hitherto undiscovered translatable string.',
+ "This is a hitherto undiscovered translatable string.",
po_contents,
)
diff --git a/tests/i18n/test_management.py b/tests/i18n/test_management.py
index c464a13295..332702c0f4 100644
--- a/tests/i18n/test_management.py
+++ b/tests/i18n/test_management.py
@@ -5,18 +5,28 @@ from django.test import SimpleTestCase
class TranslatableFileTests(SimpleTestCase):
-
def test_repr(self):
- dirpath = 'dir'
- file_name = 'example'
- trans_file = TranslatableFile(dirpath=dirpath, file_name=file_name, locale_dir=None)
- self.assertEqual(repr(trans_file), '<TranslatableFile: %s>' % os.path.join(dirpath, file_name))
+ dirpath = "dir"
+ file_name = "example"
+ trans_file = TranslatableFile(
+ dirpath=dirpath, file_name=file_name, locale_dir=None
+ )
+ self.assertEqual(
+ repr(trans_file),
+ "<TranslatableFile: %s>" % os.path.join(dirpath, file_name),
+ )
def test_eq(self):
- dirpath = 'dir'
- file_name = 'example'
- trans_file = TranslatableFile(dirpath=dirpath, file_name=file_name, locale_dir=None)
- trans_file_eq = TranslatableFile(dirpath=dirpath, file_name=file_name, locale_dir=None)
- trans_file_not_eq = TranslatableFile(dirpath='tmp', file_name=file_name, locale_dir=None)
+ dirpath = "dir"
+ file_name = "example"
+ trans_file = TranslatableFile(
+ dirpath=dirpath, file_name=file_name, locale_dir=None
+ )
+ trans_file_eq = TranslatableFile(
+ dirpath=dirpath, file_name=file_name, locale_dir=None
+ )
+ trans_file_not_eq = TranslatableFile(
+ dirpath="tmp", file_name=file_name, locale_dir=None
+ )
self.assertEqual(trans_file, trans_file_eq)
self.assertNotEqual(trans_file, trans_file_not_eq)
diff --git a/tests/i18n/test_percents.py b/tests/i18n/test_percents.py
index 5362ace0a7..f1dce0c7c6 100644
--- a/tests/i18n/test_percents.py
+++ b/tests/i18n/test_percents.py
@@ -6,20 +6,22 @@ from django.utils.translation import activate, get_language, trans_real
from .utils import POFileAssertionMixin
-SAMPLEPROJECT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'sampleproject')
-SAMPLEPROJECT_LOCALE = os.path.join(SAMPLEPROJECT_DIR, 'locale')
+SAMPLEPROJECT_DIR = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)), "sampleproject"
+)
+SAMPLEPROJECT_LOCALE = os.path.join(SAMPLEPROJECT_DIR, "locale")
@override_settings(LOCALE_PATHS=[SAMPLEPROJECT_LOCALE])
class FrenchTestCase(SimpleTestCase):
"""Tests using the French translations of the sampleproject."""
- PO_FILE = os.path.join(SAMPLEPROJECT_LOCALE, 'fr', 'LC_MESSAGES', 'django.po')
+ PO_FILE = os.path.join(SAMPLEPROJECT_LOCALE, "fr", "LC_MESSAGES", "django.po")
def setUp(self):
self._language = get_language()
self._translations = trans_real._translations
- activate('fr')
+ activate("fr")
def tearDown(self):
trans_real._translations = self._translations
@@ -42,19 +44,34 @@ class ExtractingStringsWithPercentSigns(POFileAssertionMixin, FrenchTestCase):
self.po_contents = fp.read()
def test_trans_tag_with_percent_symbol_at_the_end(self):
- self.assertMsgId('Literal with a percent symbol at the end %%', self.po_contents)
+ self.assertMsgId(
+ "Literal with a percent symbol at the end %%", self.po_contents
+ )
def test_trans_tag_with_percent_symbol_in_the_middle(self):
- self.assertMsgId('Literal with a percent %% symbol in the middle', self.po_contents)
- self.assertMsgId('It is 100%%', self.po_contents)
+ self.assertMsgId(
+ "Literal with a percent %% symbol in the middle", self.po_contents
+ )
+ self.assertMsgId("It is 100%%", self.po_contents)
def test_trans_tag_with_string_that_look_like_fmt_spec(self):
- self.assertMsgId('Looks like a str fmt spec %%s but should not be interpreted as such', self.po_contents)
- self.assertMsgId('Looks like a str fmt spec %% o but should not be interpreted as such', self.po_contents)
+ self.assertMsgId(
+ "Looks like a str fmt spec %%s but should not be interpreted as such",
+ self.po_contents,
+ )
+ self.assertMsgId(
+ "Looks like a str fmt spec %% o but should not be interpreted as such",
+ self.po_contents,
+ )
def test_adds_python_format_to_all_percent_signs(self):
- self.assertMsgId('1 percent sign %%, 2 percent signs %%%%, 3 percent signs %%%%%%', self.po_contents)
- self.assertMsgId('%(name)s says: 1 percent sign %%, 2 percent signs %%%%', self.po_contents)
+ self.assertMsgId(
+ "1 percent sign %%, 2 percent signs %%%%, 3 percent signs %%%%%%",
+ self.po_contents,
+ )
+ self.assertMsgId(
+ "%(name)s says: 1 percent sign %%, 2 percent signs %%%%", self.po_contents
+ )
class RenderingTemplatesWithPercentSigns(FrenchTestCase):
@@ -67,69 +84,79 @@ class RenderingTemplatesWithPercentSigns(FrenchTestCase):
"""
def test_translates_with_a_percent_symbol_at_the_end(self):
- expected = 'Littérale avec un symbole de pour cent à la fin %'
+ expected = "Littérale avec un symbole de pour cent à la fin %"
- trans_tpl = Template('{% load i18n %}{% translate "Literal with a percent symbol at the end %" %}')
+ trans_tpl = Template(
+ '{% load i18n %}{% translate "Literal with a percent symbol at the end %" %}'
+ )
self.assertEqual(trans_tpl.render(Context({})), expected)
block_tpl = Template(
- '{% load i18n %}{% blocktranslate %}Literal with a percent symbol at '
- 'the end %{% endblocktranslate %}'
+ "{% load i18n %}{% blocktranslate %}Literal with a percent symbol at "
+ "the end %{% endblocktranslate %}"
)
self.assertEqual(block_tpl.render(Context({})), expected)
def test_translates_with_percent_symbol_in_the_middle(self):
- expected = 'Pour cent littérale % avec un symbole au milieu'
+ expected = "Pour cent littérale % avec un symbole au milieu"
- trans_tpl = Template('{% load i18n %}{% translate "Literal with a percent % symbol in the middle" %}')
+ trans_tpl = Template(
+ '{% load i18n %}{% translate "Literal with a percent % symbol in the middle" %}'
+ )
self.assertEqual(trans_tpl.render(Context({})), expected)
block_tpl = Template(
- '{% load i18n %}{% blocktranslate %}Literal with a percent % symbol '
- 'in the middle{% endblocktranslate %}'
+ "{% load i18n %}{% blocktranslate %}Literal with a percent % symbol "
+ "in the middle{% endblocktranslate %}"
)
self.assertEqual(block_tpl.render(Context({})), expected)
def test_translates_with_percent_symbol_using_context(self):
trans_tpl = Template('{% load i18n %}{% translate "It is 100%" %}')
- self.assertEqual(trans_tpl.render(Context({})), 'Il est de 100%')
- trans_tpl = Template('{% load i18n %}{% translate "It is 100%" context "female" %}')
- self.assertEqual(trans_tpl.render(Context({})), 'Elle est de 100%')
+ self.assertEqual(trans_tpl.render(Context({})), "Il est de 100%")
+ trans_tpl = Template(
+ '{% load i18n %}{% translate "It is 100%" context "female" %}'
+ )
+ self.assertEqual(trans_tpl.render(Context({})), "Elle est de 100%")
- block_tpl = Template('{% load i18n %}{% blocktranslate %}It is 100%{% endblocktranslate %}')
- self.assertEqual(block_tpl.render(Context({})), 'Il est de 100%')
- block_tpl = Template('{% load i18n %}{% blocktranslate context "female" %}It is 100%{% endblocktranslate %}')
- self.assertEqual(block_tpl.render(Context({})), 'Elle est de 100%')
+ block_tpl = Template(
+ "{% load i18n %}{% blocktranslate %}It is 100%{% endblocktranslate %}"
+ )
+ self.assertEqual(block_tpl.render(Context({})), "Il est de 100%")
+ block_tpl = Template(
+ '{% load i18n %}{% blocktranslate context "female" %}It is 100%{% endblocktranslate %}'
+ )
+ self.assertEqual(block_tpl.render(Context({})), "Elle est de 100%")
def test_translates_with_string_that_look_like_fmt_spec_with_trans(self):
# tests "%s"
- expected = ('On dirait un spec str fmt %s mais ne devrait pas être interprété comme plus disponible')
+ expected = "On dirait un spec str fmt %s mais ne devrait pas être interprété comme plus disponible"
trans_tpl = Template(
'{% load i18n %}{% translate "Looks like a str fmt spec %s but '
'should not be interpreted as such" %}'
)
self.assertEqual(trans_tpl.render(Context({})), expected)
block_tpl = Template(
- '{% load i18n %}{% blocktranslate %}Looks like a str fmt spec %s but '
- 'should not be interpreted as such{% endblocktranslate %}'
+ "{% load i18n %}{% blocktranslate %}Looks like a str fmt spec %s but "
+ "should not be interpreted as such{% endblocktranslate %}"
)
self.assertEqual(block_tpl.render(Context({})), expected)
# tests "% o"
- expected = ('On dirait un spec str fmt % o mais ne devrait pas être interprété comme plus disponible')
+ expected = "On dirait un spec str fmt % o mais ne devrait pas être interprété comme plus disponible"
trans_tpl = Template(
'{% load i18n %}{% translate "Looks like a str fmt spec % o but should not be '
'interpreted as such" %}'
)
self.assertEqual(trans_tpl.render(Context({})), expected)
block_tpl = Template(
- '{% load i18n %}{% blocktranslate %}Looks like a str fmt spec % o but should not be '
- 'interpreted as such{% endblocktranslate %}'
+ "{% load i18n %}{% blocktranslate %}Looks like a str fmt spec % o but should not be "
+ "interpreted as such{% endblocktranslate %}"
)
self.assertEqual(block_tpl.render(Context({})), expected)
def test_translates_multiple_percent_signs(self):
- expected = ('1 % signe pour cent, signes %% 2 pour cent, trois signes de pourcentage %%%')
+ expected = "1 % signe pour cent, signes %% 2 pour cent, trois signes de pourcentage %%%"
trans_tpl = Template(
'{% load i18n %}{% translate "1 percent sign %, 2 percent signs %%, '
@@ -137,16 +164,16 @@ class RenderingTemplatesWithPercentSigns(FrenchTestCase):
)
self.assertEqual(trans_tpl.render(Context({})), expected)
block_tpl = Template(
- '{% load i18n %}{% blocktranslate %}1 percent sign %, 2 percent signs '
- '%%, 3 percent signs %%%{% endblocktranslate %}'
+ "{% load i18n %}{% blocktranslate %}1 percent sign %, 2 percent signs "
+ "%%, 3 percent signs %%%{% endblocktranslate %}"
)
self.assertEqual(block_tpl.render(Context({})), expected)
block_tpl = Template(
- '{% load i18n %}{% blocktranslate %}{{name}} says: 1 percent sign %, '
- '2 percent signs %%{% endblocktranslate %}'
+ "{% load i18n %}{% blocktranslate %}{{name}} says: 1 percent sign %, "
+ "2 percent signs %%{% endblocktranslate %}"
)
self.assertEqual(
block_tpl.render(Context({"name": "Django"})),
- 'Django dit: 1 pour cent signe %, deux signes de pourcentage %%'
+ "Django dit: 1 pour cent signe %, deux signes de pourcentage %%",
)
diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py
index 3dbb8236d7..aa77657471 100644
--- a/tests/i18n/tests.py
+++ b/tests/i18n/tests.py
@@ -19,26 +19,51 @@ from django.conf.locale import LANG_INFO
from django.conf.urls.i18n import i18n_patterns
from django.template import Context, Template
from django.test import (
- RequestFactory, SimpleTestCase, TestCase, ignore_warnings,
+ RequestFactory,
+ SimpleTestCase,
+ TestCase,
+ ignore_warnings,
override_settings,
)
from django.utils import translation
from django.utils.deprecation import RemovedInDjango50Warning
from django.utils.formats import (
- date_format, get_format, iter_format_modules, localize, localize_input,
- reset_format_cache, sanitize_separators, sanitize_strftime_format,
+ date_format,
+ get_format,
+ iter_format_modules,
+ localize,
+ localize_input,
+ reset_format_cache,
+ sanitize_separators,
+ sanitize_strftime_format,
time_format,
)
from django.utils.numberformat import format as nformat
from django.utils.safestring import SafeString, mark_safe
from django.utils.translation import (
- activate, check_for_language, deactivate, get_language, get_language_bidi,
- get_language_from_request, get_language_info, gettext, gettext_lazy,
- ngettext, ngettext_lazy, npgettext, npgettext_lazy, pgettext,
- round_away_from_one, to_language, to_locale, trans_null, trans_real,
+ activate,
+ check_for_language,
+ deactivate,
+ get_language,
+ get_language_bidi,
+ get_language_from_request,
+ get_language_info,
+ gettext,
+ gettext_lazy,
+ ngettext,
+ ngettext_lazy,
+ npgettext,
+ npgettext_lazy,
+ pgettext,
+ round_away_from_one,
+ to_language,
+ to_locale,
+ trans_null,
+ trans_real,
)
from django.utils.translation.reloader import (
- translation_file_changed, watch_for_translation_changes,
+ translation_file_changed,
+ watch_for_translation_changes,
)
from .forms import CompanyForm, I18nForm, SelectDateForm
@@ -46,7 +71,7 @@ from .models import Company, TestModel
here = os.path.dirname(os.path.abspath(__file__))
extended_locale_paths = settings.LOCALE_PATHS + [
- os.path.join(here, 'other', 'locale'),
+ os.path.join(here, "other", "locale"),
]
@@ -69,30 +94,34 @@ def patch_formats(lang, **settings):
class TranslationTests(SimpleTestCase):
- @translation.override('fr')
+ @translation.override("fr")
def test_plural(self):
"""
Test plurals with ngettext. French differs from English in that 0 is singular.
"""
self.assertEqual(
- ngettext('%(num)d year', '%(num)d years', 0) % {'num': 0},
- '0 année',
+ ngettext("%(num)d year", "%(num)d years", 0) % {"num": 0},
+ "0 année",
)
self.assertEqual(
- ngettext('%(num)d year', '%(num)d years', 2) % {'num': 2},
- '2 années',
+ ngettext("%(num)d year", "%(num)d years", 2) % {"num": 2},
+ "2 années",
+ )
+ self.assertEqual(
+ ngettext("%(size)d byte", "%(size)d bytes", 0) % {"size": 0}, "0 octet"
+ )
+ self.assertEqual(
+ ngettext("%(size)d byte", "%(size)d bytes", 2) % {"size": 2}, "2 octets"
)
- self.assertEqual(ngettext("%(size)d byte", "%(size)d bytes", 0) % {'size': 0}, "0 octet")
- self.assertEqual(ngettext("%(size)d byte", "%(size)d bytes", 2) % {'size': 2}, "2 octets")
def test_plural_null(self):
g = trans_null.ngettext
- self.assertEqual(g('%(num)d year', '%(num)d years', 0) % {'num': 0}, '0 years')
- self.assertEqual(g('%(num)d year', '%(num)d years', 1) % {'num': 1}, '1 year')
- self.assertEqual(g('%(num)d year', '%(num)d years', 2) % {'num': 2}, '2 years')
+ self.assertEqual(g("%(num)d year", "%(num)d years", 0) % {"num": 0}, "0 years")
+ self.assertEqual(g("%(num)d year", "%(num)d years", 1) % {"num": 1}, "1 year")
+ self.assertEqual(g("%(num)d year", "%(num)d years", 2) % {"num": 2}, "2 years")
@override_settings(LOCALE_PATHS=extended_locale_paths)
- @translation.override('fr')
+ @translation.override("fr")
def test_multiple_plurals_per_language(self):
"""
Normally, French has 2 plurals. As other/locale/fr/LC_MESSAGES/django.po
@@ -104,40 +133,39 @@ class TranslationTests(SimpleTestCase):
self.assertEqual(ngettext("%d singular", "%d plural", 2) % 2, "2 pluriel2")
french = trans_real.catalog()
# Internal _catalog can query subcatalogs (from different po files).
- self.assertEqual(french._catalog[('%d singular', 0)], '%d singulier')
- self.assertEqual(french._catalog[('%(num)d hour', 0)], '%(num)d heure')
+ self.assertEqual(french._catalog[("%d singular", 0)], "%d singulier")
+ self.assertEqual(french._catalog[("%(num)d hour", 0)], "%(num)d heure")
def test_override(self):
- activate('de')
+ activate("de")
try:
- with translation.override('pl'):
- self.assertEqual(get_language(), 'pl')
- self.assertEqual(get_language(), 'de')
+ with translation.override("pl"):
+ self.assertEqual(get_language(), "pl")
+ self.assertEqual(get_language(), "de")
with translation.override(None):
self.assertIsNone(get_language())
- with translation.override('pl'):
+ with translation.override("pl"):
pass
self.assertIsNone(get_language())
- self.assertEqual(get_language(), 'de')
+ self.assertEqual(get_language(), "de")
finally:
deactivate()
def test_override_decorator(self):
-
- @translation.override('pl')
+ @translation.override("pl")
def func_pl():
- self.assertEqual(get_language(), 'pl')
+ self.assertEqual(get_language(), "pl")
@translation.override(None)
def func_none():
self.assertIsNone(get_language())
try:
- activate('de')
+ activate("de")
func_pl()
- self.assertEqual(get_language(), 'de')
+ self.assertEqual(get_language(), "de")
func_none()
- self.assertEqual(get_language(), 'de')
+ self.assertEqual(get_language(), "de")
finally:
deactivate()
@@ -146,17 +174,18 @@ class TranslationTests(SimpleTestCase):
The language restored is the one used when the function was
called, not the one used when the decorator was initialized (#23381).
"""
- activate('fr')
+ activate("fr")
- @translation.override('pl')
+ @translation.override("pl")
def func_pl():
pass
+
deactivate()
try:
- activate('en')
+ activate("en")
func_pl()
- self.assertEqual(get_language(), 'en')
+ self.assertEqual(get_language(), "en")
finally:
deactivate()
@@ -164,22 +193,22 @@ class TranslationTests(SimpleTestCase):
"""
Format string interpolation should work with *_lazy objects.
"""
- s = gettext_lazy('Add %(name)s')
- d = {'name': 'Ringo'}
- self.assertEqual('Add Ringo', s % d)
- with translation.override('de', deactivate=True):
- self.assertEqual('Ringo hinzuf\xfcgen', s % d)
- with translation.override('pl'):
- self.assertEqual('Dodaj Ringo', s % d)
+ s = gettext_lazy("Add %(name)s")
+ d = {"name": "Ringo"}
+ self.assertEqual("Add Ringo", s % d)
+ with translation.override("de", deactivate=True):
+ self.assertEqual("Ringo hinzuf\xfcgen", s % d)
+ with translation.override("pl"):
+ self.assertEqual("Dodaj Ringo", s % d)
# It should be possible to compare *_lazy objects.
- s1 = gettext_lazy('Add %(name)s')
+ s1 = gettext_lazy("Add %(name)s")
self.assertEqual(s, s1)
- s2 = gettext_lazy('Add %(name)s')
- s3 = gettext_lazy('Add %(name)s')
+ s2 = gettext_lazy("Add %(name)s")
+ s3 = gettext_lazy("Add %(name)s")
self.assertEqual(s2, s3)
self.assertEqual(s, s2)
- s4 = gettext_lazy('Some other string')
+ s4 = gettext_lazy("Some other string")
self.assertNotEqual(s, s4)
def test_lazy_pickle(self):
@@ -190,99 +219,159 @@ class TranslationTests(SimpleTestCase):
@override_settings(LOCALE_PATHS=extended_locale_paths)
def test_ngettext_lazy(self):
- simple_with_format = ngettext_lazy('%d good result', '%d good results')
- simple_context_with_format = npgettext_lazy('Exclamation', '%d good result', '%d good results')
- simple_without_format = ngettext_lazy('good result', 'good results')
- with translation.override('de'):
- self.assertEqual(simple_with_format % 1, '1 gutes Resultat')
- self.assertEqual(simple_with_format % 4, '4 guten Resultate')
- self.assertEqual(simple_context_with_format % 1, '1 gutes Resultat!')
- self.assertEqual(simple_context_with_format % 4, '4 guten Resultate!')
- self.assertEqual(simple_without_format % 1, 'gutes Resultat')
- self.assertEqual(simple_without_format % 4, 'guten Resultate')
-
- complex_nonlazy = ngettext_lazy('Hi %(name)s, %(num)d good result', 'Hi %(name)s, %(num)d good results', 4)
+ simple_with_format = ngettext_lazy("%d good result", "%d good results")
+ simple_context_with_format = npgettext_lazy(
+ "Exclamation", "%d good result", "%d good results"
+ )
+ simple_without_format = ngettext_lazy("good result", "good results")
+ with translation.override("de"):
+ self.assertEqual(simple_with_format % 1, "1 gutes Resultat")
+ self.assertEqual(simple_with_format % 4, "4 guten Resultate")
+ self.assertEqual(simple_context_with_format % 1, "1 gutes Resultat!")
+ self.assertEqual(simple_context_with_format % 4, "4 guten Resultate!")
+ self.assertEqual(simple_without_format % 1, "gutes Resultat")
+ self.assertEqual(simple_without_format % 4, "guten Resultate")
+
+ complex_nonlazy = ngettext_lazy(
+ "Hi %(name)s, %(num)d good result", "Hi %(name)s, %(num)d good results", 4
+ )
complex_deferred = ngettext_lazy(
- 'Hi %(name)s, %(num)d good result', 'Hi %(name)s, %(num)d good results', 'num'
+ "Hi %(name)s, %(num)d good result",
+ "Hi %(name)s, %(num)d good results",
+ "num",
)
complex_context_nonlazy = npgettext_lazy(
- 'Greeting', 'Hi %(name)s, %(num)d good result', 'Hi %(name)s, %(num)d good results', 4
+ "Greeting",
+ "Hi %(name)s, %(num)d good result",
+ "Hi %(name)s, %(num)d good results",
+ 4,
)
complex_context_deferred = npgettext_lazy(
- 'Greeting', 'Hi %(name)s, %(num)d good result', 'Hi %(name)s, %(num)d good results', 'num'
+ "Greeting",
+ "Hi %(name)s, %(num)d good result",
+ "Hi %(name)s, %(num)d good results",
+ "num",
)
- with translation.override('de'):
- self.assertEqual(complex_nonlazy % {'num': 4, 'name': 'Jim'}, 'Hallo Jim, 4 guten Resultate')
- self.assertEqual(complex_deferred % {'name': 'Jim', 'num': 1}, 'Hallo Jim, 1 gutes Resultat')
- self.assertEqual(complex_deferred % {'name': 'Jim', 'num': 5}, 'Hallo Jim, 5 guten Resultate')
- with self.assertRaisesMessage(KeyError, 'Your dictionary lacks key'):
- complex_deferred % {'name': 'Jim'}
- self.assertEqual(complex_context_nonlazy % {'num': 4, 'name': 'Jim'}, 'Willkommen Jim, 4 guten Resultate')
- self.assertEqual(complex_context_deferred % {'name': 'Jim', 'num': 1}, 'Willkommen Jim, 1 gutes Resultat')
- self.assertEqual(complex_context_deferred % {'name': 'Jim', 'num': 5}, 'Willkommen Jim, 5 guten Resultate')
- with self.assertRaisesMessage(KeyError, 'Your dictionary lacks key'):
- complex_context_deferred % {'name': 'Jim'}
+ with translation.override("de"):
+ self.assertEqual(
+ complex_nonlazy % {"num": 4, "name": "Jim"},
+ "Hallo Jim, 4 guten Resultate",
+ )
+ self.assertEqual(
+ complex_deferred % {"name": "Jim", "num": 1},
+ "Hallo Jim, 1 gutes Resultat",
+ )
+ self.assertEqual(
+ complex_deferred % {"name": "Jim", "num": 5},
+ "Hallo Jim, 5 guten Resultate",
+ )
+ with self.assertRaisesMessage(KeyError, "Your dictionary lacks key"):
+ complex_deferred % {"name": "Jim"}
+ self.assertEqual(
+ complex_context_nonlazy % {"num": 4, "name": "Jim"},
+ "Willkommen Jim, 4 guten Resultate",
+ )
+ self.assertEqual(
+ complex_context_deferred % {"name": "Jim", "num": 1},
+ "Willkommen Jim, 1 gutes Resultat",
+ )
+ self.assertEqual(
+ complex_context_deferred % {"name": "Jim", "num": 5},
+ "Willkommen Jim, 5 guten Resultate",
+ )
+ with self.assertRaisesMessage(KeyError, "Your dictionary lacks key"):
+ complex_context_deferred % {"name": "Jim"}
@override_settings(LOCALE_PATHS=extended_locale_paths)
def test_ngettext_lazy_format_style(self):
- simple_with_format = ngettext_lazy('{} good result', '{} good results')
- simple_context_with_format = npgettext_lazy('Exclamation', '{} good result', '{} good results')
+ simple_with_format = ngettext_lazy("{} good result", "{} good results")
+ simple_context_with_format = npgettext_lazy(
+ "Exclamation", "{} good result", "{} good results"
+ )
- with translation.override('de'):
- self.assertEqual(simple_with_format.format(1), '1 gutes Resultat')
- self.assertEqual(simple_with_format.format(4), '4 guten Resultate')
- self.assertEqual(simple_context_with_format.format(1), '1 gutes Resultat!')
- self.assertEqual(simple_context_with_format.format(4), '4 guten Resultate!')
+ with translation.override("de"):
+ self.assertEqual(simple_with_format.format(1), "1 gutes Resultat")
+ self.assertEqual(simple_with_format.format(4), "4 guten Resultate")
+ self.assertEqual(simple_context_with_format.format(1), "1 gutes Resultat!")
+ self.assertEqual(simple_context_with_format.format(4), "4 guten Resultate!")
- complex_nonlazy = ngettext_lazy('Hi {name}, {num} good result', 'Hi {name}, {num} good results', 4)
+ complex_nonlazy = ngettext_lazy(
+ "Hi {name}, {num} good result", "Hi {name}, {num} good results", 4
+ )
complex_deferred = ngettext_lazy(
- 'Hi {name}, {num} good result', 'Hi {name}, {num} good results', 'num'
+ "Hi {name}, {num} good result", "Hi {name}, {num} good results", "num"
)
complex_context_nonlazy = npgettext_lazy(
- 'Greeting', 'Hi {name}, {num} good result', 'Hi {name}, {num} good results', 4
+ "Greeting",
+ "Hi {name}, {num} good result",
+ "Hi {name}, {num} good results",
+ 4,
)
complex_context_deferred = npgettext_lazy(
- 'Greeting', 'Hi {name}, {num} good result', 'Hi {name}, {num} good results', 'num'
+ "Greeting",
+ "Hi {name}, {num} good result",
+ "Hi {name}, {num} good results",
+ "num",
)
- with translation.override('de'):
- self.assertEqual(complex_nonlazy.format(num=4, name='Jim'), 'Hallo Jim, 4 guten Resultate')
- self.assertEqual(complex_deferred.format(name='Jim', num=1), 'Hallo Jim, 1 gutes Resultat')
- self.assertEqual(complex_deferred.format(name='Jim', num=5), 'Hallo Jim, 5 guten Resultate')
- with self.assertRaisesMessage(KeyError, 'Your dictionary lacks key'):
- complex_deferred.format(name='Jim')
- self.assertEqual(complex_context_nonlazy.format(num=4, name='Jim'), 'Willkommen Jim, 4 guten Resultate')
- self.assertEqual(complex_context_deferred.format(name='Jim', num=1), 'Willkommen Jim, 1 gutes Resultat')
- self.assertEqual(complex_context_deferred.format(name='Jim', num=5), 'Willkommen Jim, 5 guten Resultate')
- with self.assertRaisesMessage(KeyError, 'Your dictionary lacks key'):
- complex_context_deferred.format(name='Jim')
+ with translation.override("de"):
+ self.assertEqual(
+ complex_nonlazy.format(num=4, name="Jim"),
+ "Hallo Jim, 4 guten Resultate",
+ )
+ self.assertEqual(
+ complex_deferred.format(name="Jim", num=1),
+ "Hallo Jim, 1 gutes Resultat",
+ )
+ self.assertEqual(
+ complex_deferred.format(name="Jim", num=5),
+ "Hallo Jim, 5 guten Resultate",
+ )
+ with self.assertRaisesMessage(KeyError, "Your dictionary lacks key"):
+ complex_deferred.format(name="Jim")
+ self.assertEqual(
+ complex_context_nonlazy.format(num=4, name="Jim"),
+ "Willkommen Jim, 4 guten Resultate",
+ )
+ self.assertEqual(
+ complex_context_deferred.format(name="Jim", num=1),
+ "Willkommen Jim, 1 gutes Resultat",
+ )
+ self.assertEqual(
+ complex_context_deferred.format(name="Jim", num=5),
+ "Willkommen Jim, 5 guten Resultate",
+ )
+ with self.assertRaisesMessage(KeyError, "Your dictionary lacks key"):
+ complex_context_deferred.format(name="Jim")
def test_ngettext_lazy_bool(self):
- self.assertTrue(ngettext_lazy('%d good result', '%d good results'))
- self.assertFalse(ngettext_lazy('', ''))
+ self.assertTrue(ngettext_lazy("%d good result", "%d good results"))
+ self.assertFalse(ngettext_lazy("", ""))
def test_ngettext_lazy_pickle(self):
- s1 = ngettext_lazy('%d good result', '%d good results')
- self.assertEqual(s1 % 1, '1 good result')
- self.assertEqual(s1 % 8, '8 good results')
+ s1 = ngettext_lazy("%d good result", "%d good results")
+ self.assertEqual(s1 % 1, "1 good result")
+ self.assertEqual(s1 % 8, "8 good results")
s2 = pickle.loads(pickle.dumps(s1))
- self.assertEqual(s2 % 1, '1 good result')
- self.assertEqual(s2 % 8, '8 good results')
+ self.assertEqual(s2 % 1, "1 good result")
+ self.assertEqual(s2 % 8, "8 good results")
@override_settings(LOCALE_PATHS=extended_locale_paths)
def test_pgettext(self):
trans_real._active = Local()
trans_real._translations = {}
- with translation.override('de'):
+ with translation.override("de"):
self.assertEqual(pgettext("unexisting", "May"), "May")
self.assertEqual(pgettext("month name", "May"), "Mai")
self.assertEqual(pgettext("verb", "May"), "Kann")
- self.assertEqual(npgettext("search", "%d result", "%d results", 4) % 4, "4 Resultate")
+ self.assertEqual(
+ npgettext("search", "%d result", "%d results", 4) % 4, "4 Resultate"
+ )
def test_empty_value(self):
"""Empty value must stay empty after being translated (#23196)."""
- with translation.override('de'):
- self.assertEqual('', gettext(''))
- s = mark_safe('')
+ with translation.override("de"):
+ self.assertEqual("", gettext(""))
+ s = mark_safe("")
self.assertEqual(s, gettext(s))
@override_settings(LOCALE_PATHS=extended_locale_paths)
@@ -293,58 +382,58 @@ class TranslationTests(SimpleTestCase):
"""
trans_real._active = Local()
trans_real._translations = {}
- s1 = mark_safe('Password')
- s2 = mark_safe('May')
- with translation.override('de', deactivate=True):
+ s1 = mark_safe("Password")
+ s2 = mark_safe("May")
+ with translation.override("de", deactivate=True):
self.assertIs(type(gettext(s1)), SafeString)
- self.assertIs(type(pgettext('month name', s2)), SafeString)
- self.assertEqual('aPassword', SafeString('a') + s1)
- self.assertEqual('Passworda', s1 + SafeString('a'))
- self.assertEqual('Passworda', s1 + mark_safe('a'))
- self.assertEqual('aPassword', mark_safe('a') + s1)
- self.assertEqual('as', mark_safe('a') + mark_safe('s'))
+ self.assertIs(type(pgettext("month name", s2)), SafeString)
+ self.assertEqual("aPassword", SafeString("a") + s1)
+ self.assertEqual("Passworda", s1 + SafeString("a"))
+ self.assertEqual("Passworda", s1 + mark_safe("a"))
+ self.assertEqual("aPassword", mark_safe("a") + s1)
+ self.assertEqual("as", mark_safe("a") + mark_safe("s"))
def test_maclines(self):
"""
Translations on files with Mac or DOS end of lines will be converted
to unix EOF in .po catalogs.
"""
- ca_translation = trans_real.translation('ca')
- ca_translation._catalog['Mac\nEOF\n'] = 'Catalan Mac\nEOF\n'
- ca_translation._catalog['Win\nEOF\n'] = 'Catalan Win\nEOF\n'
- with translation.override('ca', deactivate=True):
- self.assertEqual('Catalan Mac\nEOF\n', gettext('Mac\rEOF\r'))
- self.assertEqual('Catalan Win\nEOF\n', gettext('Win\r\nEOF\r\n'))
+ ca_translation = trans_real.translation("ca")
+ ca_translation._catalog["Mac\nEOF\n"] = "Catalan Mac\nEOF\n"
+ ca_translation._catalog["Win\nEOF\n"] = "Catalan Win\nEOF\n"
+ with translation.override("ca", deactivate=True):
+ self.assertEqual("Catalan Mac\nEOF\n", gettext("Mac\rEOF\r"))
+ self.assertEqual("Catalan Win\nEOF\n", gettext("Win\r\nEOF\r\n"))
def test_to_locale(self):
tests = (
- ('en', 'en'),
- ('EN', 'en'),
- ('en-us', 'en_US'),
- ('EN-US', 'en_US'),
- ('en_US', 'en_US'),
+ ("en", "en"),
+ ("EN", "en"),
+ ("en-us", "en_US"),
+ ("EN-US", "en_US"),
+ ("en_US", "en_US"),
# With > 2 characters after the dash.
- ('sr-latn', 'sr_Latn'),
- ('sr-LATN', 'sr_Latn'),
- ('sr_Latn', 'sr_Latn'),
+ ("sr-latn", "sr_Latn"),
+ ("sr-LATN", "sr_Latn"),
+ ("sr_Latn", "sr_Latn"),
# 3-char language codes.
- ('ber-MA', 'ber_MA'),
- ('BER-MA', 'ber_MA'),
- ('BER_MA', 'ber_MA'),
- ('ber_MA', 'ber_MA'),
+ ("ber-MA", "ber_MA"),
+ ("BER-MA", "ber_MA"),
+ ("BER_MA", "ber_MA"),
+ ("ber_MA", "ber_MA"),
# With private use subtag (x-informal).
- ('nl-nl-x-informal', 'nl_NL-x-informal'),
- ('NL-NL-X-INFORMAL', 'nl_NL-x-informal'),
- ('sr-latn-x-informal', 'sr_Latn-x-informal'),
- ('SR-LATN-X-INFORMAL', 'sr_Latn-x-informal'),
+ ("nl-nl-x-informal", "nl_NL-x-informal"),
+ ("NL-NL-X-INFORMAL", "nl_NL-x-informal"),
+ ("sr-latn-x-informal", "sr_Latn-x-informal"),
+ ("SR-LATN-X-INFORMAL", "sr_Latn-x-informal"),
)
for lang, locale in tests:
with self.subTest(lang=lang):
self.assertEqual(to_locale(lang), locale)
def test_to_language(self):
- self.assertEqual(to_language('en_US'), 'en-us')
- self.assertEqual(to_language('sr_Lat'), 'sr-lat')
+ self.assertEqual(to_language("en_US"), "en-us")
+ self.assertEqual(to_language("sr_Lat"), "sr-lat")
def test_language_bidi(self):
self.assertIs(get_language_bidi(), False)
@@ -353,7 +442,7 @@ class TranslationTests(SimpleTestCase):
def test_language_bidi_null(self):
self.assertIs(trans_null.get_language_bidi(), False)
- with override_settings(LANGUAGE_CODE='he'):
+ with override_settings(LANGUAGE_CODE="he"):
self.assertIs(get_language_bidi(), True)
@@ -371,15 +460,15 @@ class TranslationLoadingTests(SimpleTestCase):
@override_settings(
USE_I18N=True,
- LANGUAGE_CODE='en',
+ LANGUAGE_CODE="en",
LANGUAGES=[
- ('en', 'English'),
- ('en-ca', 'English (Canada)'),
- ('en-nz', 'English (New Zealand)'),
- ('en-au', 'English (Australia)'),
+ ("en", "English"),
+ ("en-ca", "English (Canada)"),
+ ("en-nz", "English (New Zealand)"),
+ ("en-au", "English (Australia)"),
],
- LOCALE_PATHS=[os.path.join(here, 'loading')],
- INSTALLED_APPS=['i18n.loading_app'],
+ LOCALE_PATHS=[os.path.join(here, "loading")],
+ INSTALLED_APPS=["i18n.loading_app"],
)
def test_translation_loading(self):
"""
@@ -387,10 +476,10 @@ class TranslationLoadingTests(SimpleTestCase):
"loading". Catalogs are merged correctly.
"""
tests = [
- ('en', 'local country person'),
- ('en_AU', 'aussie'),
- ('en_NZ', 'kiwi'),
- ('en_CA', 'canuck'),
+ ("en", "local country person"),
+ ("en_AU", "aussie"),
+ ("en_NZ", "kiwi"),
+ ("en_CA", "canuck"),
]
# Load all relevant translations.
for language, _ in tests:
@@ -399,11 +488,10 @@ class TranslationLoadingTests(SimpleTestCase):
for language, nickname in tests:
with self.subTest(language=language):
activate(language)
- self.assertEqual(gettext('local country person'), nickname)
+ self.assertEqual(gettext("local country person"), nickname)
class TranslationThreadSafetyTests(SimpleTestCase):
-
def setUp(self):
self._old_language = get_language()
self._translations = trans_real._translations
@@ -413,10 +501,10 @@ class TranslationThreadSafetyTests(SimpleTestCase):
class sideeffect_str(str):
def split(self, *args, **kwargs):
res = str.split(self, *args, **kwargs)
- trans_real._translations['en-YY'] = None
+ trans_real._translations["en-YY"] = None
return res
- trans_real._translations = {sideeffect_str('en-XX'): None}
+ trans_real._translations = {sideeffect_str("en-XX"): None}
def tearDown(self):
trans_real._translations = self._translations
@@ -425,29 +513,30 @@ class TranslationThreadSafetyTests(SimpleTestCase):
def test_bug14894_translation_activate_thread_safety(self):
translation_count = len(trans_real._translations)
# May raise RuntimeError if translation.activate() isn't thread-safe.
- translation.activate('pl')
+ translation.activate("pl")
# make sure sideeffect_str actually added a new translation
self.assertLess(translation_count, len(trans_real._translations))
class FormattingTests(SimpleTestCase):
-
def setUp(self):
super().setUp()
- self.n = decimal.Decimal('66666.666')
+ self.n = decimal.Decimal("66666.666")
self.f = 99999.999
self.d = datetime.date(2009, 12, 31)
self.dt = datetime.datetime(2009, 12, 31, 20, 50)
self.t = datetime.time(10, 15, 48)
self.long = 10000
- self.ctxt = Context({
- 'n': self.n,
- 't': self.t,
- 'd': self.d,
- 'dt': self.dt,
- 'f': self.f,
- 'l': self.long,
- })
+ self.ctxt = Context(
+ {
+ "n": self.n,
+ "t": self.t,
+ "d": self.d,
+ "dt": self.dt,
+ "f": self.f,
+ "l": self.long,
+ }
+ )
def test_all_format_strings(self):
all_locales = LANG_INFO.keys()
@@ -455,55 +544,129 @@ class FormattingTests(SimpleTestCase):
some_datetime = datetime.datetime(2017, 10, 14, 10, 23)
for locale in all_locales:
with self.subTest(locale=locale), translation.override(locale):
- self.assertIn('2017', date_format(some_date)) # Uses DATE_FORMAT by default
- self.assertIn('23', time_format(some_datetime)) # Uses TIME_FORMAT by default
- self.assertIn('2017', date_format(some_datetime, format=get_format('DATETIME_FORMAT')))
- self.assertIn('2017', date_format(some_date, format=get_format('YEAR_MONTH_FORMAT')))
- self.assertIn('14', date_format(some_date, format=get_format('MONTH_DAY_FORMAT')))
- self.assertIn('2017', date_format(some_date, format=get_format('SHORT_DATE_FORMAT')))
- self.assertIn('2017', date_format(some_datetime, format=get_format('SHORT_DATETIME_FORMAT')))
+ self.assertIn(
+ "2017", date_format(some_date)
+ ) # Uses DATE_FORMAT by default
+ self.assertIn(
+ "23", time_format(some_datetime)
+ ) # Uses TIME_FORMAT by default
+ self.assertIn(
+ "2017",
+ date_format(some_datetime, format=get_format("DATETIME_FORMAT")),
+ )
+ self.assertIn(
+ "2017",
+ date_format(some_date, format=get_format("YEAR_MONTH_FORMAT")),
+ )
+ self.assertIn(
+ "14", date_format(some_date, format=get_format("MONTH_DAY_FORMAT"))
+ )
+ self.assertIn(
+ "2017",
+ date_format(some_date, format=get_format("SHORT_DATE_FORMAT")),
+ )
+ self.assertIn(
+ "2017",
+ date_format(
+ some_datetime, format=get_format("SHORT_DATETIME_FORMAT")
+ ),
+ )
def test_locale_independent(self):
"""
Localization of numbers
"""
with self.settings(USE_THOUSAND_SEPARATOR=False):
- self.assertEqual('66666.66', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=','))
- self.assertEqual('66666A6', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B'))
- self.assertEqual('66666', nformat(self.n, decimal_sep='X', decimal_pos=0, grouping=1, thousand_sep='Y'))
+ self.assertEqual(
+ "66666.66",
+ nformat(
+ self.n, decimal_sep=".", decimal_pos=2, grouping=3, thousand_sep=","
+ ),
+ )
+ self.assertEqual(
+ "66666A6",
+ nformat(
+ self.n, decimal_sep="A", decimal_pos=1, grouping=1, thousand_sep="B"
+ ),
+ )
+ self.assertEqual(
+ "66666",
+ nformat(
+ self.n, decimal_sep="X", decimal_pos=0, grouping=1, thousand_sep="Y"
+ ),
+ )
with self.settings(USE_THOUSAND_SEPARATOR=True):
self.assertEqual(
- '66,666.66',
- nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=',')
+ "66,666.66",
+ nformat(
+ self.n, decimal_sep=".", decimal_pos=2, grouping=3, thousand_sep=","
+ ),
+ )
+ self.assertEqual(
+ "6B6B6B6B6A6",
+ nformat(
+ self.n, decimal_sep="A", decimal_pos=1, grouping=1, thousand_sep="B"
+ ),
)
self.assertEqual(
- '6B6B6B6B6A6',
- nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B')
+ "-66666.6", nformat(-66666.666, decimal_sep=".", decimal_pos=1)
)
- self.assertEqual('-66666.6', nformat(-66666.666, decimal_sep='.', decimal_pos=1))
- self.assertEqual('-66666.0', nformat(int('-66666'), decimal_sep='.', decimal_pos=1))
- self.assertEqual('10000.0', nformat(self.long, decimal_sep='.', decimal_pos=1))
self.assertEqual(
- '10,00,00,000.00',
- nformat(100000000.00, decimal_sep='.', decimal_pos=2, grouping=(3, 2, 0), thousand_sep=',')
+ "-66666.0", nformat(int("-66666"), decimal_sep=".", decimal_pos=1)
)
self.assertEqual(
- '1,0,00,000,0000.00',
- nformat(10000000000.00, decimal_sep='.', decimal_pos=2, grouping=(4, 3, 2, 1, 0), thousand_sep=',')
+ "10000.0", nformat(self.long, decimal_sep=".", decimal_pos=1)
)
self.assertEqual(
- '10000,00,000.00',
- nformat(1000000000.00, decimal_sep='.', decimal_pos=2, grouping=(3, 2, -1), thousand_sep=',')
+ "10,00,00,000.00",
+ nformat(
+ 100000000.00,
+ decimal_sep=".",
+ decimal_pos=2,
+ grouping=(3, 2, 0),
+ thousand_sep=",",
+ ),
+ )
+ self.assertEqual(
+ "1,0,00,000,0000.00",
+ nformat(
+ 10000000000.00,
+ decimal_sep=".",
+ decimal_pos=2,
+ grouping=(4, 3, 2, 1, 0),
+ thousand_sep=",",
+ ),
+ )
+ self.assertEqual(
+ "10000,00,000.00",
+ nformat(
+ 1000000000.00,
+ decimal_sep=".",
+ decimal_pos=2,
+ grouping=(3, 2, -1),
+ thousand_sep=",",
+ ),
)
# This unusual grouping/force_grouping combination may be triggered by the intcomma filter (#17414)
self.assertEqual(
- '10000',
- nformat(self.long, decimal_sep='.', decimal_pos=0, grouping=0, force_grouping=True)
+ "10000",
+ nformat(
+ self.long,
+ decimal_sep=".",
+ decimal_pos=0,
+ grouping=0,
+ force_grouping=True,
+ ),
)
# date filter
- self.assertEqual('31.12.2009 в 20:50', Template('{{ dt|date:"d.m.Y в H:i" }}').render(self.ctxt))
- self.assertEqual('⌚ 10:15', Template('{{ t|time:"⌚ H:i" }}').render(self.ctxt))
+ self.assertEqual(
+ "31.12.2009 в 20:50",
+ Template('{{ dt|date:"d.m.Y в H:i" }}').render(self.ctxt),
+ )
+ self.assertEqual(
+ "⌚ 10:15", Template('{{ t|time:"⌚ H:i" }}').render(self.ctxt)
+ )
@ignore_warnings(category=RemovedInDjango50Warning)
@override_settings(USE_L10N=False)
@@ -512,63 +675,92 @@ class FormattingTests(SimpleTestCase):
Catalan locale with format i18n disabled translations will be used,
but not formats
"""
- with translation.override('ca', deactivate=True):
+ with translation.override("ca", deactivate=True):
self.maxDiff = 3000
- self.assertEqual('N j, Y', get_format('DATE_FORMAT'))
- self.assertEqual(0, get_format('FIRST_DAY_OF_WEEK'))
- self.assertEqual('.', get_format('DECIMAL_SEPARATOR'))
- self.assertEqual('10:15 a.m.', time_format(self.t))
- self.assertEqual('Des. 31, 2009', date_format(self.d))
- self.assertEqual('desembre 2009', date_format(self.d, 'YEAR_MONTH_FORMAT'))
- self.assertEqual('12/31/2009 8:50 p.m.', date_format(self.dt, 'SHORT_DATETIME_FORMAT'))
- self.assertEqual('No localizable', localize('No localizable'))
- self.assertEqual('66666.666', localize(self.n))
- self.assertEqual('99999.999', localize(self.f))
- self.assertEqual('10000', localize(self.long))
- self.assertEqual('Des. 31, 2009', localize(self.d))
- self.assertEqual('Des. 31, 2009, 8:50 p.m.', localize(self.dt))
- self.assertEqual('66666.666', Template('{{ n }}').render(self.ctxt))
- self.assertEqual('99999.999', Template('{{ f }}').render(self.ctxt))
- self.assertEqual('Des. 31, 2009', Template('{{ d }}').render(self.ctxt))
- self.assertEqual('Des. 31, 2009, 8:50 p.m.', Template('{{ dt }}').render(self.ctxt))
- self.assertEqual('66666.67', Template('{{ n|floatformat:"2u" }}').render(self.ctxt))
- self.assertEqual('100000.0', Template('{{ f|floatformat:"u" }}').render(self.ctxt))
+ self.assertEqual("N j, Y", get_format("DATE_FORMAT"))
+ self.assertEqual(0, get_format("FIRST_DAY_OF_WEEK"))
+ self.assertEqual(".", get_format("DECIMAL_SEPARATOR"))
+ self.assertEqual("10:15 a.m.", time_format(self.t))
+ self.assertEqual("Des. 31, 2009", date_format(self.d))
+ self.assertEqual("desembre 2009", date_format(self.d, "YEAR_MONTH_FORMAT"))
+ self.assertEqual(
+ "12/31/2009 8:50 p.m.", date_format(self.dt, "SHORT_DATETIME_FORMAT")
+ )
+ self.assertEqual("No localizable", localize("No localizable"))
+ self.assertEqual("66666.666", localize(self.n))
+ self.assertEqual("99999.999", localize(self.f))
+ self.assertEqual("10000", localize(self.long))
+ self.assertEqual("Des. 31, 2009", localize(self.d))
+ self.assertEqual("Des. 31, 2009, 8:50 p.m.", localize(self.dt))
+ self.assertEqual("66666.666", Template("{{ n }}").render(self.ctxt))
+ self.assertEqual("99999.999", Template("{{ f }}").render(self.ctxt))
+ self.assertEqual("Des. 31, 2009", Template("{{ d }}").render(self.ctxt))
+ self.assertEqual(
+ "Des. 31, 2009, 8:50 p.m.", Template("{{ dt }}").render(self.ctxt)
+ )
self.assertEqual(
- '66666.67',
+ "66666.67", Template('{{ n|floatformat:"2u" }}').render(self.ctxt)
+ )
+ self.assertEqual(
+ "100000.0", Template('{{ f|floatformat:"u" }}').render(self.ctxt)
+ )
+ self.assertEqual(
+ "66666.67",
Template('{{ n|floatformat:"2gu" }}').render(self.ctxt),
)
self.assertEqual(
- '100000.0',
+ "100000.0",
Template('{{ f|floatformat:"ug" }}').render(self.ctxt),
)
- self.assertEqual('10:15 a.m.', Template('{{ t|time:"TIME_FORMAT" }}').render(self.ctxt))
- self.assertEqual('12/31/2009', Template('{{ d|date:"SHORT_DATE_FORMAT" }}').render(self.ctxt))
self.assertEqual(
- '12/31/2009 8:50 p.m.', Template('{{ dt|date:"SHORT_DATETIME_FORMAT" }}').render(self.ctxt)
+ "10:15 a.m.", Template('{{ t|time:"TIME_FORMAT" }}').render(self.ctxt)
+ )
+ self.assertEqual(
+ "12/31/2009",
+ Template('{{ d|date:"SHORT_DATE_FORMAT" }}').render(self.ctxt),
+ )
+ self.assertEqual(
+ "12/31/2009 8:50 p.m.",
+ Template('{{ dt|date:"SHORT_DATETIME_FORMAT" }}').render(self.ctxt),
)
- form = I18nForm({
- 'decimal_field': '66666,666',
- 'float_field': '99999,999',
- 'date_field': '31/12/2009',
- 'datetime_field': '31/12/2009 20:50',
- 'time_field': '20:50',
- 'integer_field': '1.234',
- })
+ form = I18nForm(
+ {
+ "decimal_field": "66666,666",
+ "float_field": "99999,999",
+ "date_field": "31/12/2009",
+ "datetime_field": "31/12/2009 20:50",
+ "time_field": "20:50",
+ "integer_field": "1.234",
+ }
+ )
self.assertFalse(form.is_valid())
- self.assertEqual(['Introdu\xefu un n\xfamero.'], form.errors['float_field'])
- self.assertEqual(['Introdu\xefu un n\xfamero.'], form.errors['decimal_field'])
- self.assertEqual(['Introdu\xefu una data v\xe0lida.'], form.errors['date_field'])
- self.assertEqual(['Introdu\xefu una data/hora v\xe0lides.'], form.errors['datetime_field'])
- self.assertEqual(['Introdu\xefu un n\xfamero enter.'], form.errors['integer_field'])
-
- form2 = SelectDateForm({
- 'date_field_month': '12',
- 'date_field_day': '31',
- 'date_field_year': '2009'
- })
+ self.assertEqual(["Introdu\xefu un n\xfamero."], form.errors["float_field"])
+ self.assertEqual(
+ ["Introdu\xefu un n\xfamero."], form.errors["decimal_field"]
+ )
+ self.assertEqual(
+ ["Introdu\xefu una data v\xe0lida."], form.errors["date_field"]
+ )
+ self.assertEqual(
+ ["Introdu\xefu una data/hora v\xe0lides."],
+ form.errors["datetime_field"],
+ )
+ self.assertEqual(
+ ["Introdu\xefu un n\xfamero enter."], form.errors["integer_field"]
+ )
+
+ form2 = SelectDateForm(
+ {
+ "date_field_month": "12",
+ "date_field_day": "31",
+ "date_field_year": "2009",
+ }
+ )
self.assertTrue(form2.is_valid())
- self.assertEqual(datetime.date(2009, 12, 31), form2.cleaned_data['date_field'])
+ self.assertEqual(
+ datetime.date(2009, 12, 31), form2.cleaned_data["date_field"]
+ )
self.assertHTMLEqual(
'<select name="mydate_month" id="id_mydate_month">'
'<option value="">---</option>'
@@ -584,7 +776,7 @@ class FormattingTests(SimpleTestCase):
'<option value="10">octubre</option>'
'<option value="11">novembre</option>'
'<option value="12" selected>desembre</option>'
- '</select>'
+ "</select>"
'<select name="mydate_day" id="id_mydate_day">'
'<option value="">---</option>'
'<option value="1">1</option>'
@@ -618,7 +810,7 @@ class FormattingTests(SimpleTestCase):
'<option value="29">29</option>'
'<option value="30">30</option>'
'<option value="31" selected>31</option>'
- '</select>'
+ "</select>"
'<select name="mydate_year" id="id_mydate_year">'
'<option value="">---</option>'
'<option value="2009" selected>2009</option>'
@@ -631,17 +823,25 @@ class FormattingTests(SimpleTestCase):
'<option value="2016">2016</option>'
'<option value="2017">2017</option>'
'<option value="2018">2018</option>'
- '</select>',
- forms.SelectDateWidget(years=range(2009, 2019)).render('mydate', datetime.date(2009, 12, 31))
+ "</select>",
+ forms.SelectDateWidget(years=range(2009, 2019)).render(
+ "mydate", datetime.date(2009, 12, 31)
+ ),
)
# We shouldn't change the behavior of the floatformat filter re:
# thousand separator and grouping when localization is disabled
# even if the USE_THOUSAND_SEPARATOR, NUMBER_GROUPING and
# THOUSAND_SEPARATOR settings are specified.
- with self.settings(USE_THOUSAND_SEPARATOR=True, NUMBER_GROUPING=1, THOUSAND_SEPARATOR='!'):
- self.assertEqual('66666.67', Template('{{ n|floatformat:"2u" }}').render(self.ctxt))
- self.assertEqual('100000.0', Template('{{ f|floatformat:"u" }}').render(self.ctxt))
+ with self.settings(
+ USE_THOUSAND_SEPARATOR=True, NUMBER_GROUPING=1, THOUSAND_SEPARATOR="!"
+ ):
+ self.assertEqual(
+ "66666.67", Template('{{ n|floatformat:"2u" }}').render(self.ctxt)
+ )
+ self.assertEqual(
+ "100000.0", Template('{{ f|floatformat:"u" }}').render(self.ctxt)
+ )
def test_false_like_locale_formats(self):
"""
@@ -649,113 +849,161 @@ class FormattingTests(SimpleTestCase):
even if they would be interpreted as False in a conditional test
(e.g. 0 or empty string) (#16938).
"""
- with translation.override('fr'):
- with self.settings(USE_THOUSAND_SEPARATOR=True, THOUSAND_SEPARATOR='!'):
- self.assertEqual('\xa0', get_format('THOUSAND_SEPARATOR'))
+ with translation.override("fr"):
+ with self.settings(USE_THOUSAND_SEPARATOR=True, THOUSAND_SEPARATOR="!"):
+ self.assertEqual("\xa0", get_format("THOUSAND_SEPARATOR"))
# Even a second time (after the format has been cached)...
- self.assertEqual('\xa0', get_format('THOUSAND_SEPARATOR'))
+ self.assertEqual("\xa0", get_format("THOUSAND_SEPARATOR"))
with self.settings(FIRST_DAY_OF_WEEK=0):
- self.assertEqual(1, get_format('FIRST_DAY_OF_WEEK'))
+ self.assertEqual(1, get_format("FIRST_DAY_OF_WEEK"))
# Even a second time (after the format has been cached)...
- self.assertEqual(1, get_format('FIRST_DAY_OF_WEEK'))
+ self.assertEqual(1, get_format("FIRST_DAY_OF_WEEK"))
def test_l10n_enabled(self):
self.maxDiff = 3000
# Catalan locale
- with translation.override('ca', deactivate=True):
- self.assertEqual(r'j \d\e F \d\e Y', get_format('DATE_FORMAT'))
- self.assertEqual(1, get_format('FIRST_DAY_OF_WEEK'))
- self.assertEqual(',', get_format('DECIMAL_SEPARATOR'))
- self.assertEqual('10:15', time_format(self.t))
- self.assertEqual('31 de desembre de 2009', date_format(self.d))
- self.assertEqual('desembre del 2009', date_format(self.d, 'YEAR_MONTH_FORMAT'))
- self.assertEqual('31/12/2009 20:50', date_format(self.dt, 'SHORT_DATETIME_FORMAT'))
- self.assertEqual('No localizable', localize('No localizable'))
+ with translation.override("ca", deactivate=True):
+ self.assertEqual(r"j \d\e F \d\e Y", get_format("DATE_FORMAT"))
+ self.assertEqual(1, get_format("FIRST_DAY_OF_WEEK"))
+ self.assertEqual(",", get_format("DECIMAL_SEPARATOR"))
+ self.assertEqual("10:15", time_format(self.t))
+ self.assertEqual("31 de desembre de 2009", date_format(self.d))
+ self.assertEqual(
+ "desembre del 2009", date_format(self.d, "YEAR_MONTH_FORMAT")
+ )
+ self.assertEqual(
+ "31/12/2009 20:50", date_format(self.dt, "SHORT_DATETIME_FORMAT")
+ )
+ self.assertEqual("No localizable", localize("No localizable"))
with self.settings(USE_THOUSAND_SEPARATOR=True):
- self.assertEqual('66.666,666', localize(self.n))
- self.assertEqual('99.999,999', localize(self.f))
- self.assertEqual('10.000', localize(self.long))
- self.assertEqual('True', localize(True))
+ self.assertEqual("66.666,666", localize(self.n))
+ self.assertEqual("99.999,999", localize(self.f))
+ self.assertEqual("10.000", localize(self.long))
+ self.assertEqual("True", localize(True))
with self.settings(USE_THOUSAND_SEPARATOR=False):
- self.assertEqual('66666,666', localize(self.n))
- self.assertEqual('99999,999', localize(self.f))
- self.assertEqual('10000', localize(self.long))
- self.assertEqual('31 de desembre de 2009', localize(self.d))
- self.assertEqual('31 de desembre de 2009 a les 20:50', localize(self.dt))
+ self.assertEqual("66666,666", localize(self.n))
+ self.assertEqual("99999,999", localize(self.f))
+ self.assertEqual("10000", localize(self.long))
+ self.assertEqual("31 de desembre de 2009", localize(self.d))
+ self.assertEqual(
+ "31 de desembre de 2009 a les 20:50", localize(self.dt)
+ )
with self.settings(USE_THOUSAND_SEPARATOR=True):
- self.assertEqual('66.666,666', Template('{{ n }}').render(self.ctxt))
- self.assertEqual('99.999,999', Template('{{ f }}').render(self.ctxt))
- self.assertEqual('10.000', Template('{{ l }}').render(self.ctxt))
+ self.assertEqual("66.666,666", Template("{{ n }}").render(self.ctxt))
+ self.assertEqual("99.999,999", Template("{{ f }}").render(self.ctxt))
+ self.assertEqual("10.000", Template("{{ l }}").render(self.ctxt))
with self.settings(USE_THOUSAND_SEPARATOR=True):
- form3 = I18nForm({
- 'decimal_field': '66.666,666',
- 'float_field': '99.999,999',
- 'date_field': '31/12/2009',
- 'datetime_field': '31/12/2009 20:50',
- 'time_field': '20:50',
- 'integer_field': '1.234',
- })
+ form3 = I18nForm(
+ {
+ "decimal_field": "66.666,666",
+ "float_field": "99.999,999",
+ "date_field": "31/12/2009",
+ "datetime_field": "31/12/2009 20:50",
+ "time_field": "20:50",
+ "integer_field": "1.234",
+ }
+ )
self.assertTrue(form3.is_valid())
- self.assertEqual(decimal.Decimal('66666.666'), form3.cleaned_data['decimal_field'])
- self.assertEqual(99999.999, form3.cleaned_data['float_field'])
- self.assertEqual(datetime.date(2009, 12, 31), form3.cleaned_data['date_field'])
- self.assertEqual(datetime.datetime(2009, 12, 31, 20, 50), form3.cleaned_data['datetime_field'])
- self.assertEqual(datetime.time(20, 50), form3.cleaned_data['time_field'])
- self.assertEqual(1234, form3.cleaned_data['integer_field'])
+ self.assertEqual(
+ decimal.Decimal("66666.666"), form3.cleaned_data["decimal_field"]
+ )
+ self.assertEqual(99999.999, form3.cleaned_data["float_field"])
+ self.assertEqual(
+ datetime.date(2009, 12, 31), form3.cleaned_data["date_field"]
+ )
+ self.assertEqual(
+ datetime.datetime(2009, 12, 31, 20, 50),
+ form3.cleaned_data["datetime_field"],
+ )
+ self.assertEqual(
+ datetime.time(20, 50), form3.cleaned_data["time_field"]
+ )
+ self.assertEqual(1234, form3.cleaned_data["integer_field"])
with self.settings(USE_THOUSAND_SEPARATOR=False):
- self.assertEqual('66666,666', Template('{{ n }}').render(self.ctxt))
- self.assertEqual('99999,999', Template('{{ f }}').render(self.ctxt))
- self.assertEqual('31 de desembre de 2009', Template('{{ d }}').render(self.ctxt))
- self.assertEqual('31 de desembre de 2009 a les 20:50', Template('{{ dt }}').render(self.ctxt))
- self.assertEqual('66666,67', Template('{{ n|floatformat:2 }}').render(self.ctxt))
- self.assertEqual('100000,0', Template('{{ f|floatformat }}').render(self.ctxt))
+ self.assertEqual("66666,666", Template("{{ n }}").render(self.ctxt))
+ self.assertEqual("99999,999", Template("{{ f }}").render(self.ctxt))
+ self.assertEqual(
+ "31 de desembre de 2009", Template("{{ d }}").render(self.ctxt)
+ )
+ self.assertEqual(
+ "31 de desembre de 2009 a les 20:50",
+ Template("{{ dt }}").render(self.ctxt),
+ )
self.assertEqual(
- '66.666,67',
+ "66666,67", Template("{{ n|floatformat:2 }}").render(self.ctxt)
+ )
+ self.assertEqual(
+ "100000,0", Template("{{ f|floatformat }}").render(self.ctxt)
+ )
+ self.assertEqual(
+ "66.666,67",
Template('{{ n|floatformat:"2g" }}').render(self.ctxt),
)
self.assertEqual(
- '100.000,0',
+ "100.000,0",
Template('{{ f|floatformat:"g" }}').render(self.ctxt),
)
- self.assertEqual('10:15', Template('{{ t|time:"TIME_FORMAT" }}').render(self.ctxt))
- self.assertEqual('31/12/2009', Template('{{ d|date:"SHORT_DATE_FORMAT" }}').render(self.ctxt))
self.assertEqual(
- '31/12/2009 20:50',
- Template('{{ dt|date:"SHORT_DATETIME_FORMAT" }}').render(self.ctxt)
+ "10:15", Template('{{ t|time:"TIME_FORMAT" }}').render(self.ctxt)
+ )
+ self.assertEqual(
+ "31/12/2009",
+ Template('{{ d|date:"SHORT_DATE_FORMAT" }}').render(self.ctxt),
+ )
+ self.assertEqual(
+ "31/12/2009 20:50",
+ Template('{{ dt|date:"SHORT_DATETIME_FORMAT" }}').render(self.ctxt),
+ )
+ self.assertEqual(
+ date_format(datetime.datetime.now(), "DATE_FORMAT"),
+ Template('{% now "DATE_FORMAT" %}').render(self.ctxt),
)
- self.assertEqual(date_format(datetime.datetime.now(), "DATE_FORMAT"),
- Template('{% now "DATE_FORMAT" %}').render(self.ctxt))
with self.settings(USE_THOUSAND_SEPARATOR=False):
- form4 = I18nForm({
- 'decimal_field': '66666,666',
- 'float_field': '99999,999',
- 'date_field': '31/12/2009',
- 'datetime_field': '31/12/2009 20:50',
- 'time_field': '20:50',
- 'integer_field': '1234',
- })
+ form4 = I18nForm(
+ {
+ "decimal_field": "66666,666",
+ "float_field": "99999,999",
+ "date_field": "31/12/2009",
+ "datetime_field": "31/12/2009 20:50",
+ "time_field": "20:50",
+ "integer_field": "1234",
+ }
+ )
self.assertTrue(form4.is_valid())
- self.assertEqual(decimal.Decimal('66666.666'), form4.cleaned_data['decimal_field'])
- self.assertEqual(99999.999, form4.cleaned_data['float_field'])
- self.assertEqual(datetime.date(2009, 12, 31), form4.cleaned_data['date_field'])
- self.assertEqual(datetime.datetime(2009, 12, 31, 20, 50), form4.cleaned_data['datetime_field'])
- self.assertEqual(datetime.time(20, 50), form4.cleaned_data['time_field'])
- self.assertEqual(1234, form4.cleaned_data['integer_field'])
-
- form5 = SelectDateForm({
- 'date_field_month': '12',
- 'date_field_day': '31',
- 'date_field_year': '2009'
- })
+ self.assertEqual(
+ decimal.Decimal("66666.666"), form4.cleaned_data["decimal_field"]
+ )
+ self.assertEqual(99999.999, form4.cleaned_data["float_field"])
+ self.assertEqual(
+ datetime.date(2009, 12, 31), form4.cleaned_data["date_field"]
+ )
+ self.assertEqual(
+ datetime.datetime(2009, 12, 31, 20, 50),
+ form4.cleaned_data["datetime_field"],
+ )
+ self.assertEqual(
+ datetime.time(20, 50), form4.cleaned_data["time_field"]
+ )
+ self.assertEqual(1234, form4.cleaned_data["integer_field"])
+
+ form5 = SelectDateForm(
+ {
+ "date_field_month": "12",
+ "date_field_day": "31",
+ "date_field_year": "2009",
+ }
+ )
self.assertTrue(form5.is_valid())
- self.assertEqual(datetime.date(2009, 12, 31), form5.cleaned_data['date_field'])
+ self.assertEqual(
+ datetime.date(2009, 12, 31), form5.cleaned_data["date_field"]
+ )
self.assertHTMLEqual(
'<select name="mydate_day" id="id_mydate_day">'
'<option value="">---</option>'
@@ -790,7 +1038,7 @@ class FormattingTests(SimpleTestCase):
'<option value="29">29</option>'
'<option value="30">30</option>'
'<option value="31" selected>31</option>'
- '</select>'
+ "</select>"
'<select name="mydate_month" id="id_mydate_month">'
'<option value="">---</option>'
'<option value="1">gener</option>'
@@ -805,7 +1053,7 @@ class FormattingTests(SimpleTestCase):
'<option value="10">octubre</option>'
'<option value="11">novembre</option>'
'<option value="12" selected>desembre</option>'
- '</select>'
+ "</select>"
'<select name="mydate_year" id="id_mydate_year">'
'<option value="">---</option>'
'<option value="2009" selected>2009</option>'
@@ -818,12 +1066,14 @@ class FormattingTests(SimpleTestCase):
'<option value="2016">2016</option>'
'<option value="2017">2017</option>'
'<option value="2018">2018</option>'
- '</select>',
- forms.SelectDateWidget(years=range(2009, 2019)).render('mydate', datetime.date(2009, 12, 31))
+ "</select>",
+ forms.SelectDateWidget(years=range(2009, 2019)).render(
+ "mydate", datetime.date(2009, 12, 31)
+ ),
)
# Russian locale (with E as month)
- with translation.override('ru', deactivate=True):
+ with translation.override("ru", deactivate=True):
self.assertHTMLEqual(
'<select name="mydate_day" id="id_mydate_day">'
'<option value="">---</option>'
@@ -858,7 +1108,7 @@ class FormattingTests(SimpleTestCase):
'<option value="29">29</option>'
'<option value="30">30</option>'
'<option value="31" selected>31</option>'
- '</select>'
+ "</select>"
'<select name="mydate_month" id="id_mydate_month">'
'<option value="">---</option>'
'<option value="1">\u042f\u043d\u0432\u0430\u0440\u044c</option>'
@@ -873,7 +1123,7 @@ class FormattingTests(SimpleTestCase):
'<option value="10">\u041e\u043a\u0442\u044f\u0431\u0440\u044c</option>'
'<option value="11">\u041d\u043e\u044f\u0431\u0440\u044c</option>'
'<option value="12" selected>\u0414\u0435\u043a\u0430\u0431\u0440\u044c</option>'
- '</select>'
+ "</select>"
'<select name="mydate_year" id="id_mydate_year">'
'<option value="">---</option>'
'<option value="2009" selected>2009</option>'
@@ -886,81 +1136,107 @@ class FormattingTests(SimpleTestCase):
'<option value="2016">2016</option>'
'<option value="2017">2017</option>'
'<option value="2018">2018</option>'
- '</select>',
- forms.SelectDateWidget(years=range(2009, 2019)).render('mydate', datetime.date(2009, 12, 31))
+ "</select>",
+ forms.SelectDateWidget(years=range(2009, 2019)).render(
+ "mydate", datetime.date(2009, 12, 31)
+ ),
)
# English locale
- with translation.override('en', deactivate=True):
- self.assertEqual('N j, Y', get_format('DATE_FORMAT'))
- self.assertEqual(0, get_format('FIRST_DAY_OF_WEEK'))
- self.assertEqual('.', get_format('DECIMAL_SEPARATOR'))
- self.assertEqual('Dec. 31, 2009', date_format(self.d))
- self.assertEqual('December 2009', date_format(self.d, 'YEAR_MONTH_FORMAT'))
- self.assertEqual('12/31/2009 8:50 p.m.', date_format(self.dt, 'SHORT_DATETIME_FORMAT'))
- self.assertEqual('No localizable', localize('No localizable'))
+ with translation.override("en", deactivate=True):
+ self.assertEqual("N j, Y", get_format("DATE_FORMAT"))
+ self.assertEqual(0, get_format("FIRST_DAY_OF_WEEK"))
+ self.assertEqual(".", get_format("DECIMAL_SEPARATOR"))
+ self.assertEqual("Dec. 31, 2009", date_format(self.d))
+ self.assertEqual("December 2009", date_format(self.d, "YEAR_MONTH_FORMAT"))
+ self.assertEqual(
+ "12/31/2009 8:50 p.m.", date_format(self.dt, "SHORT_DATETIME_FORMAT")
+ )
+ self.assertEqual("No localizable", localize("No localizable"))
with self.settings(USE_THOUSAND_SEPARATOR=True):
- self.assertEqual('66,666.666', localize(self.n))
- self.assertEqual('99,999.999', localize(self.f))
- self.assertEqual('10,000', localize(self.long))
+ self.assertEqual("66,666.666", localize(self.n))
+ self.assertEqual("99,999.999", localize(self.f))
+ self.assertEqual("10,000", localize(self.long))
with self.settings(USE_THOUSAND_SEPARATOR=False):
- self.assertEqual('66666.666', localize(self.n))
- self.assertEqual('99999.999', localize(self.f))
- self.assertEqual('10000', localize(self.long))
- self.assertEqual('Dec. 31, 2009', localize(self.d))
- self.assertEqual('Dec. 31, 2009, 8:50 p.m.', localize(self.dt))
+ self.assertEqual("66666.666", localize(self.n))
+ self.assertEqual("99999.999", localize(self.f))
+ self.assertEqual("10000", localize(self.long))
+ self.assertEqual("Dec. 31, 2009", localize(self.d))
+ self.assertEqual("Dec. 31, 2009, 8:50 p.m.", localize(self.dt))
with self.settings(USE_THOUSAND_SEPARATOR=True):
- self.assertEqual('66,666.666', Template('{{ n }}').render(self.ctxt))
- self.assertEqual('99,999.999', Template('{{ f }}').render(self.ctxt))
- self.assertEqual('10,000', Template('{{ l }}').render(self.ctxt))
+ self.assertEqual("66,666.666", Template("{{ n }}").render(self.ctxt))
+ self.assertEqual("99,999.999", Template("{{ f }}").render(self.ctxt))
+ self.assertEqual("10,000", Template("{{ l }}").render(self.ctxt))
with self.settings(USE_THOUSAND_SEPARATOR=False):
- self.assertEqual('66666.666', Template('{{ n }}').render(self.ctxt))
- self.assertEqual('99999.999', Template('{{ f }}').render(self.ctxt))
- self.assertEqual('Dec. 31, 2009', Template('{{ d }}').render(self.ctxt))
- self.assertEqual('Dec. 31, 2009, 8:50 p.m.', Template('{{ dt }}').render(self.ctxt))
- self.assertEqual('66666.67', Template('{{ n|floatformat:2 }}').render(self.ctxt))
- self.assertEqual('100000.0', Template('{{ f|floatformat }}').render(self.ctxt))
+ self.assertEqual("66666.666", Template("{{ n }}").render(self.ctxt))
+ self.assertEqual("99999.999", Template("{{ f }}").render(self.ctxt))
+ self.assertEqual("Dec. 31, 2009", Template("{{ d }}").render(self.ctxt))
+ self.assertEqual(
+ "Dec. 31, 2009, 8:50 p.m.", Template("{{ dt }}").render(self.ctxt)
+ )
+ self.assertEqual(
+ "66666.67", Template("{{ n|floatformat:2 }}").render(self.ctxt)
+ )
self.assertEqual(
- '66,666.67',
+ "100000.0", Template("{{ f|floatformat }}").render(self.ctxt)
+ )
+ self.assertEqual(
+ "66,666.67",
Template('{{ n|floatformat:"2g" }}').render(self.ctxt),
)
self.assertEqual(
- '100,000.0',
+ "100,000.0",
Template('{{ f|floatformat:"g" }}').render(self.ctxt),
)
- self.assertEqual('12/31/2009', Template('{{ d|date:"SHORT_DATE_FORMAT" }}').render(self.ctxt))
self.assertEqual(
- '12/31/2009 8:50 p.m.',
- Template('{{ dt|date:"SHORT_DATETIME_FORMAT" }}').render(self.ctxt)
+ "12/31/2009",
+ Template('{{ d|date:"SHORT_DATE_FORMAT" }}').render(self.ctxt),
+ )
+ self.assertEqual(
+ "12/31/2009 8:50 p.m.",
+ Template('{{ dt|date:"SHORT_DATETIME_FORMAT" }}').render(self.ctxt),
)
- form5 = I18nForm({
- 'decimal_field': '66666.666',
- 'float_field': '99999.999',
- 'date_field': '12/31/2009',
- 'datetime_field': '12/31/2009 20:50',
- 'time_field': '20:50',
- 'integer_field': '1234',
- })
+ form5 = I18nForm(
+ {
+ "decimal_field": "66666.666",
+ "float_field": "99999.999",
+ "date_field": "12/31/2009",
+ "datetime_field": "12/31/2009 20:50",
+ "time_field": "20:50",
+ "integer_field": "1234",
+ }
+ )
self.assertTrue(form5.is_valid())
- self.assertEqual(decimal.Decimal('66666.666'), form5.cleaned_data['decimal_field'])
- self.assertEqual(99999.999, form5.cleaned_data['float_field'])
- self.assertEqual(datetime.date(2009, 12, 31), form5.cleaned_data['date_field'])
- self.assertEqual(datetime.datetime(2009, 12, 31, 20, 50), form5.cleaned_data['datetime_field'])
- self.assertEqual(datetime.time(20, 50), form5.cleaned_data['time_field'])
- self.assertEqual(1234, form5.cleaned_data['integer_field'])
-
- form6 = SelectDateForm({
- 'date_field_month': '12',
- 'date_field_day': '31',
- 'date_field_year': '2009'
- })
+ self.assertEqual(
+ decimal.Decimal("66666.666"), form5.cleaned_data["decimal_field"]
+ )
+ self.assertEqual(99999.999, form5.cleaned_data["float_field"])
+ self.assertEqual(
+ datetime.date(2009, 12, 31), form5.cleaned_data["date_field"]
+ )
+ self.assertEqual(
+ datetime.datetime(2009, 12, 31, 20, 50),
+ form5.cleaned_data["datetime_field"],
+ )
+ self.assertEqual(datetime.time(20, 50), form5.cleaned_data["time_field"])
+ self.assertEqual(1234, form5.cleaned_data["integer_field"])
+
+ form6 = SelectDateForm(
+ {
+ "date_field_month": "12",
+ "date_field_day": "31",
+ "date_field_year": "2009",
+ }
+ )
self.assertTrue(form6.is_valid())
- self.assertEqual(datetime.date(2009, 12, 31), form6.cleaned_data['date_field'])
+ self.assertEqual(
+ datetime.date(2009, 12, 31), form6.cleaned_data["date_field"]
+ )
self.assertHTMLEqual(
'<select name="mydate_month" id="id_mydate_month">'
'<option value="">---</option>'
@@ -976,7 +1252,7 @@ class FormattingTests(SimpleTestCase):
'<option value="10">October</option>'
'<option value="11">November</option>'
'<option value="12" selected>December</option>'
- '</select>'
+ "</select>"
'<select name="mydate_day" id="id_mydate_day">'
'<option value="">---</option>'
'<option value="1">1</option>'
@@ -1010,7 +1286,7 @@ class FormattingTests(SimpleTestCase):
'<option value="29">29</option>'
'<option value="30">30</option>'
'<option value="31" selected>31</option>'
- '</select>'
+ "</select>"
'<select name="mydate_year" id="id_mydate_year">'
'<option value="">---</option>'
'<option value="2009" selected>2009</option>'
@@ -1023,8 +1299,10 @@ class FormattingTests(SimpleTestCase):
'<option value="2016">2016</option>'
'<option value="2017">2017</option>'
'<option value="2018">2018</option>'
- '</select>',
- forms.SelectDateWidget(years=range(2009, 2019)).render('mydate', datetime.date(2009, 12, 31))
+ "</select>",
+ forms.SelectDateWidget(years=range(2009, 2019)).render(
+ "mydate", datetime.date(2009, 12, 31)
+ ),
)
def test_sub_locales(self):
@@ -1032,23 +1310,25 @@ class FormattingTests(SimpleTestCase):
Check if sublocales fall back to the main locale
"""
with self.settings(USE_THOUSAND_SEPARATOR=True):
- with translation.override('de-at', deactivate=True):
- self.assertEqual('66.666,666', Template('{{ n }}').render(self.ctxt))
- with translation.override('es-us', deactivate=True):
- self.assertEqual('31 de Diciembre de 2009', date_format(self.d))
+ with translation.override("de-at", deactivate=True):
+ self.assertEqual("66.666,666", Template("{{ n }}").render(self.ctxt))
+ with translation.override("es-us", deactivate=True):
+ self.assertEqual("31 de Diciembre de 2009", date_format(self.d))
def test_localized_input(self):
"""
Tests if form input is correctly localized
"""
self.maxDiff = 1200
- with translation.override('de-at', deactivate=True):
- form6 = CompanyForm({
- 'name': 'acme',
- 'date_added': datetime.datetime(2009, 12, 31, 6, 0, 0),
- 'cents_paid': decimal.Decimal('59.47'),
- 'products_delivered': 12000,
- })
+ with translation.override("de-at", deactivate=True):
+ form6 = CompanyForm(
+ {
+ "name": "acme",
+ "date_added": datetime.datetime(2009, 12, 31, 6, 0, 0),
+ "cents_paid": decimal.Decimal("59.47"),
+ "products_delivered": 12000,
+ }
+ )
self.assertTrue(form6.is_valid())
self.assertHTMLEqual(
form6.as_ul(),
@@ -1060,23 +1340,29 @@ class FormattingTests(SimpleTestCase):
'<input type="text" name="cents_paid" value="59,47" id="id_cents_paid" required></li>'
'<li><label for="id_products_delivered">Products delivered:</label>'
'<input type="text" name="products_delivered" value="12000" id="id_products_delivered" required>'
- '</li>'
+ "</li>",
+ )
+ self.assertEqual(
+ localize_input(datetime.datetime(2009, 12, 31, 6, 0, 0)),
+ "31.12.2009 06:00:00",
+ )
+ self.assertEqual(
+ datetime.datetime(2009, 12, 31, 6, 0, 0),
+ form6.cleaned_data["date_added"],
)
- self.assertEqual(localize_input(datetime.datetime(2009, 12, 31, 6, 0, 0)), '31.12.2009 06:00:00')
- self.assertEqual(datetime.datetime(2009, 12, 31, 6, 0, 0), form6.cleaned_data['date_added'])
with self.settings(USE_THOUSAND_SEPARATOR=True):
# Checking for the localized "products_delivered" field
self.assertInHTML(
'<input type="text" name="products_delivered" '
'value="12.000" id="id_products_delivered" required>',
- form6.as_ul()
+ form6.as_ul(),
)
def test_localized_input_func(self):
tests = (
- (True, 'True'),
- (datetime.date(1, 1, 1), '0001-01-01'),
- (datetime.datetime(1, 1, 1), '0001-01-01 00:00:00'),
+ (True, "True"),
+ (datetime.date(1, 1, 1), "0001-01-01"),
+ (datetime.datetime(1, 1, 1), "0001-01-01 00:00:00"),
)
with self.settings(USE_THOUSAND_SEPARATOR=True):
for value, expected in tests:
@@ -1087,10 +1373,10 @@ class FormattingTests(SimpleTestCase):
for year in (1, 99, 999, 1000):
dt = datetime.date(year, 1, 1)
for fmt, expected in [
- ('%C', '%02d' % (year // 100)),
- ('%F', '%04d-01-01' % year),
- ('%G', '%04d' % year),
- ('%Y', '%04d' % year),
+ ("%C", "%02d" % (year // 100)),
+ ("%F", "%04d-01-01" % year),
+ ("%G", "%04d" % year),
+ ("%Y", "%04d" % year),
]:
with self.subTest(year=year, fmt=fmt):
fmt = sanitize_strftime_format(fmt)
@@ -1099,14 +1385,14 @@ class FormattingTests(SimpleTestCase):
def test_sanitize_strftime_format_with_escaped_percent(self):
dt = datetime.date(1, 1, 1)
for fmt, expected in [
- ('%%C', '%C'),
- ('%%F', '%F'),
- ('%%G', '%G'),
- ('%%Y', '%Y'),
- ('%%%%C', '%%C'),
- ('%%%%F', '%%F'),
- ('%%%%G', '%%G'),
- ('%%%%Y', '%%Y'),
+ ("%%C", "%C"),
+ ("%%F", "%F"),
+ ("%%G", "%G"),
+ ("%%Y", "%Y"),
+ ("%%%%C", "%%C"),
+ ("%%%%F", "%%F"),
+ ("%%%%G", "%%G"),
+ ("%%%%Y", "%%Y"),
]:
with self.subTest(fmt=fmt):
fmt = sanitize_strftime_format(fmt)
@@ -1115,14 +1401,14 @@ class FormattingTests(SimpleTestCase):
for year in (1, 99, 999, 1000):
dt = datetime.date(year, 1, 1)
for fmt, expected in [
- ('%%%C', '%%%02d' % (year // 100)),
- ('%%%F', '%%%04d-01-01' % year),
- ('%%%G', '%%%04d' % year),
- ('%%%Y', '%%%04d' % year),
- ('%%%%%C', '%%%%%02d' % (year // 100)),
- ('%%%%%F', '%%%%%04d-01-01' % year),
- ('%%%%%G', '%%%%%04d' % year),
- ('%%%%%Y', '%%%%%04d' % year),
+ ("%%%C", "%%%02d" % (year // 100)),
+ ("%%%F", "%%%04d-01-01" % year),
+ ("%%%G", "%%%04d" % year),
+ ("%%%Y", "%%%04d" % year),
+ ("%%%%%C", "%%%%%02d" % (year // 100)),
+ ("%%%%%F", "%%%%%04d-01-01" % year),
+ ("%%%%%G", "%%%%%04d" % year),
+ ("%%%%%Y", "%%%%%04d" % year),
]:
with self.subTest(year=year, fmt=fmt):
fmt = sanitize_strftime_format(fmt)
@@ -1135,23 +1421,25 @@ class FormattingTests(SimpleTestCase):
# Non-strings are untouched
self.assertEqual(sanitize_separators(123), 123)
- with translation.override('ru', deactivate=True):
+ with translation.override("ru", deactivate=True):
# Russian locale has non-breaking space (\xa0) as thousand separator
# Usual space is accepted too when sanitizing inputs
with self.settings(USE_THOUSAND_SEPARATOR=True):
- self.assertEqual(sanitize_separators('1\xa0234\xa0567'), '1234567')
- self.assertEqual(sanitize_separators('77\xa0777,777'), '77777.777')
- self.assertEqual(sanitize_separators('12 345'), '12345')
- self.assertEqual(sanitize_separators('77 777,777'), '77777.777')
+ self.assertEqual(sanitize_separators("1\xa0234\xa0567"), "1234567")
+ self.assertEqual(sanitize_separators("77\xa0777,777"), "77777.777")
+ self.assertEqual(sanitize_separators("12 345"), "12345")
+ self.assertEqual(sanitize_separators("77 777,777"), "77777.777")
with translation.override(None): # RemovedInDjango50Warning
- with self.settings(USE_THOUSAND_SEPARATOR=True, THOUSAND_SEPARATOR='.'):
- self.assertEqual(sanitize_separators('12\xa0345'), '12\xa0345')
+ with self.settings(USE_THOUSAND_SEPARATOR=True, THOUSAND_SEPARATOR="."):
+ self.assertEqual(sanitize_separators("12\xa0345"), "12\xa0345")
with self.settings(USE_THOUSAND_SEPARATOR=True):
- with patch_formats(get_language(), THOUSAND_SEPARATOR='.', DECIMAL_SEPARATOR=','):
- self.assertEqual(sanitize_separators('10.234'), '10234')
+ with patch_formats(
+ get_language(), THOUSAND_SEPARATOR=".", DECIMAL_SEPARATOR=","
+ ):
+ self.assertEqual(sanitize_separators("10.234"), "10234")
# Suspicion that user entered dot as decimal separator (#22171)
- self.assertEqual(sanitize_separators('10.10'), '10.10')
+ self.assertEqual(sanitize_separators("10.10"), "10.10")
# RemovedInDjango50Warning: When the deprecation ends, remove
# @ignore_warnings and USE_L10N=False. The assertions should remain
@@ -1159,19 +1447,19 @@ class FormattingTests(SimpleTestCase):
# locale-dictated formats.
with ignore_warnings(category=RemovedInDjango50Warning):
with self.settings(USE_L10N=False):
- with self.settings(DECIMAL_SEPARATOR=','):
- self.assertEqual(sanitize_separators('1001,10'), '1001.10')
- self.assertEqual(sanitize_separators('1001.10'), '1001.10')
+ with self.settings(DECIMAL_SEPARATOR=","):
+ self.assertEqual(sanitize_separators("1001,10"), "1001.10")
+ self.assertEqual(sanitize_separators("1001.10"), "1001.10")
with self.settings(
- DECIMAL_SEPARATOR=',',
- THOUSAND_SEPARATOR='.',
+ DECIMAL_SEPARATOR=",",
+ THOUSAND_SEPARATOR=".",
USE_THOUSAND_SEPARATOR=True,
):
- self.assertEqual(sanitize_separators('1.001,10'), '1001.10')
- self.assertEqual(sanitize_separators('1001,10'), '1001.10')
- self.assertEqual(sanitize_separators('1001.10'), '1001.10')
+ self.assertEqual(sanitize_separators("1.001,10"), "1001.10")
+ self.assertEqual(sanitize_separators("1001,10"), "1001.10")
+ self.assertEqual(sanitize_separators("1001.10"), "1001.10")
# Invalid output.
- self.assertEqual(sanitize_separators('1,001.10'), '1.001.10')
+ self.assertEqual(sanitize_separators("1,001.10"), "1.001.10")
def test_iter_format_modules(self):
"""
@@ -1179,68 +1467,80 @@ class FormattingTests(SimpleTestCase):
"""
# Importing some format modules so that we can compare the returned
# modules with these expected modules
- default_mod = import_module('django.conf.locale.de.formats')
- test_mod = import_module('i18n.other.locale.de.formats')
- test_mod2 = import_module('i18n.other2.locale.de.formats')
+ default_mod = import_module("django.conf.locale.de.formats")
+ test_mod = import_module("i18n.other.locale.de.formats")
+ test_mod2 = import_module("i18n.other2.locale.de.formats")
- with translation.override('de-at', deactivate=True):
+ with translation.override("de-at", deactivate=True):
# Should return the correct default module when no setting is set
- self.assertEqual(list(iter_format_modules('de')), [default_mod])
+ self.assertEqual(list(iter_format_modules("de")), [default_mod])
# When the setting is a string, should return the given module and
# the default module
self.assertEqual(
- list(iter_format_modules('de', 'i18n.other.locale')),
- [test_mod, default_mod])
+ list(iter_format_modules("de", "i18n.other.locale")),
+ [test_mod, default_mod],
+ )
# When setting is a list of strings, should return the given
# modules and the default module
self.assertEqual(
- list(iter_format_modules('de', ['i18n.other.locale', 'i18n.other2.locale'])),
- [test_mod, test_mod2, default_mod])
+ list(
+ iter_format_modules(
+ "de", ["i18n.other.locale", "i18n.other2.locale"]
+ )
+ ),
+ [test_mod, test_mod2, default_mod],
+ )
def test_iter_format_modules_stability(self):
"""
Tests the iter_format_modules function always yields format modules in
a stable and correct order in presence of both base ll and ll_CC formats.
"""
- en_format_mod = import_module('django.conf.locale.en.formats')
- en_gb_format_mod = import_module('django.conf.locale.en_GB.formats')
- self.assertEqual(list(iter_format_modules('en-gb')), [en_gb_format_mod, en_format_mod])
+ en_format_mod = import_module("django.conf.locale.en.formats")
+ en_gb_format_mod = import_module("django.conf.locale.en_GB.formats")
+ self.assertEqual(
+ list(iter_format_modules("en-gb")), [en_gb_format_mod, en_format_mod]
+ )
def test_get_format_modules_lang(self):
- with translation.override('de', deactivate=True):
- self.assertEqual('.', get_format('DECIMAL_SEPARATOR', lang='en'))
+ with translation.override("de", deactivate=True):
+ self.assertEqual(".", get_format("DECIMAL_SEPARATOR", lang="en"))
def test_localize_templatetag_and_filter(self):
"""
Test the {% localize %} templatetag and the localize/unlocalize filters.
"""
- context = Context({'int': 1455, 'float': 3.14, 'date': datetime.date(2016, 12, 31)})
+ context = Context(
+ {"int": 1455, "float": 3.14, "date": datetime.date(2016, 12, 31)}
+ )
template1 = Template(
- '{% load l10n %}{% localize %}{{ int }}/{{ float }}/{{ date }}{% endlocalize %}; '
- '{% localize on %}{{ int }}/{{ float }}/{{ date }}{% endlocalize %}'
+ "{% load l10n %}{% localize %}{{ int }}/{{ float }}/{{ date }}{% endlocalize %}; "
+ "{% localize on %}{{ int }}/{{ float }}/{{ date }}{% endlocalize %}"
)
template2 = Template(
- '{% load l10n %}{{ int }}/{{ float }}/{{ date }}; '
- '{% localize off %}{{ int }}/{{ float }}/{{ date }};{% endlocalize %} '
- '{{ int }}/{{ float }}/{{ date }}'
+ "{% load l10n %}{{ int }}/{{ float }}/{{ date }}; "
+ "{% localize off %}{{ int }}/{{ float }}/{{ date }};{% endlocalize %} "
+ "{{ int }}/{{ float }}/{{ date }}"
)
template3 = Template(
- '{% load l10n %}{{ int }}/{{ float }}/{{ date }}; '
- '{{ int|unlocalize }}/{{ float|unlocalize }}/{{ date|unlocalize }}'
+ "{% load l10n %}{{ int }}/{{ float }}/{{ date }}; "
+ "{{ int|unlocalize }}/{{ float|unlocalize }}/{{ date|unlocalize }}"
)
template4 = Template(
- '{% load l10n %}{{ int }}/{{ float }}/{{ date }}; '
- '{{ int|localize }}/{{ float|localize }}/{{ date|localize }}'
+ "{% load l10n %}{{ int }}/{{ float }}/{{ date }}; "
+ "{{ int|localize }}/{{ float|localize }}/{{ date|localize }}"
+ )
+ expected_localized = "1.455/3,14/31. Dezember 2016"
+ expected_unlocalized = "1455/3.14/Dez. 31, 2016"
+ output1 = "; ".join([expected_localized, expected_localized])
+ output2 = "; ".join(
+ [expected_localized, expected_unlocalized, expected_localized]
)
- expected_localized = '1.455/3,14/31. Dezember 2016'
- expected_unlocalized = '1455/3.14/Dez. 31, 2016'
- output1 = '; '.join([expected_localized, expected_localized])
- output2 = '; '.join([expected_localized, expected_unlocalized, expected_localized])
- output3 = '; '.join([expected_localized, expected_unlocalized])
- output4 = '; '.join([expected_unlocalized, expected_localized])
- with translation.override('de', deactivate=True):
+ output3 = "; ".join([expected_localized, expected_unlocalized])
+ output4 = "; ".join([expected_unlocalized, expected_localized])
+ with translation.override("de", deactivate=True):
# RemovedInDjango50Warning: When the deprecation ends, remove
# @ignore_warnings and USE_L10N=False. The assertions should remain
# because format-related settings will take precedence over
@@ -1248,8 +1548,8 @@ class FormattingTests(SimpleTestCase):
with ignore_warnings(category=RemovedInDjango50Warning):
with self.settings(
USE_L10N=False,
- DATE_FORMAT='N j, Y',
- DECIMAL_SEPARATOR='.',
+ DATE_FORMAT="N j, Y",
+ DECIMAL_SEPARATOR=".",
NUMBER_GROUPING=0,
USE_THOUSAND_SEPARATOR=True,
):
@@ -1263,29 +1563,29 @@ class FormattingTests(SimpleTestCase):
def test_localized_off_numbers(self):
"""A string representation is returned for unlocalized numbers."""
template = Template(
- '{% load l10n %}{% localize off %}'
- '{{ int }}/{{ float }}/{{ decimal }}{% endlocalize %}'
+ "{% load l10n %}{% localize off %}"
+ "{{ int }}/{{ float }}/{{ decimal }}{% endlocalize %}"
)
context = Context(
- {'int': 1455, 'float': 3.14, 'decimal': decimal.Decimal('24.1567')}
+ {"int": 1455, "float": 3.14, "decimal": decimal.Decimal("24.1567")}
)
with self.settings(
- DECIMAL_SEPARATOR=',',
+ DECIMAL_SEPARATOR=",",
USE_THOUSAND_SEPARATOR=True,
- THOUSAND_SEPARATOR='°',
+ THOUSAND_SEPARATOR="°",
NUMBER_GROUPING=2,
):
- self.assertEqual(template.render(context), '1455/3.14/24.1567')
+ self.assertEqual(template.render(context), "1455/3.14/24.1567")
# RemovedInDjango50Warning.
with ignore_warnings(category=RemovedInDjango50Warning):
with self.settings(
USE_L10N=False,
- DECIMAL_SEPARATOR=',',
+ DECIMAL_SEPARATOR=",",
USE_THOUSAND_SEPARATOR=True,
- THOUSAND_SEPARATOR='°',
+ THOUSAND_SEPARATOR="°",
NUMBER_GROUPING=2,
):
- self.assertEqual(template.render(context), '1455/3.14/24.1567')
+ self.assertEqual(template.render(context), "1455/3.14/24.1567")
def test_localized_as_text_as_hidden_input(self):
"""
@@ -1293,45 +1593,51 @@ class FormattingTests(SimpleTestCase):
"""
self.maxDiff = 1200
- with translation.override('de-at', deactivate=True):
- template = Template('{% load l10n %}{{ form.date_added }}; {{ form.cents_paid }}')
- template_as_text = Template('{% load l10n %}{{ form.date_added.as_text }}; {{ form.cents_paid.as_text }}')
+ with translation.override("de-at", deactivate=True):
+ template = Template(
+ "{% load l10n %}{{ form.date_added }}; {{ form.cents_paid }}"
+ )
+ template_as_text = Template(
+ "{% load l10n %}{{ form.date_added.as_text }}; {{ form.cents_paid.as_text }}"
+ )
template_as_hidden = Template(
- '{% load l10n %}{{ form.date_added.as_hidden }}; {{ form.cents_paid.as_hidden }}'
- )
- form = CompanyForm({
- 'name': 'acme',
- 'date_added': datetime.datetime(2009, 12, 31, 6, 0, 0),
- 'cents_paid': decimal.Decimal('59.47'),
- 'products_delivered': 12000,
- })
- context = Context({'form': form})
+ "{% load l10n %}{{ form.date_added.as_hidden }}; {{ form.cents_paid.as_hidden }}"
+ )
+ form = CompanyForm(
+ {
+ "name": "acme",
+ "date_added": datetime.datetime(2009, 12, 31, 6, 0, 0),
+ "cents_paid": decimal.Decimal("59.47"),
+ "products_delivered": 12000,
+ }
+ )
+ context = Context({"form": form})
self.assertTrue(form.is_valid())
self.assertHTMLEqual(
template.render(context),
'<input id="id_date_added" name="date_added" type="text" value="31.12.2009 06:00:00" required>;'
- '<input id="id_cents_paid" name="cents_paid" type="text" value="59,47" required>'
+ '<input id="id_cents_paid" name="cents_paid" type="text" value="59,47" required>',
)
self.assertHTMLEqual(
template_as_text.render(context),
'<input id="id_date_added" name="date_added" type="text" value="31.12.2009 06:00:00" required>;'
- ' <input id="id_cents_paid" name="cents_paid" type="text" value="59,47" required>'
+ ' <input id="id_cents_paid" name="cents_paid" type="text" value="59,47" required>',
)
self.assertHTMLEqual(
template_as_hidden.render(context),
'<input id="id_date_added" name="date_added" type="hidden" value="31.12.2009 06:00:00">;'
- '<input id="id_cents_paid" name="cents_paid" type="hidden" value="59,47">'
+ '<input id="id_cents_paid" name="cents_paid" type="hidden" value="59,47">',
)
def test_format_arbitrary_settings(self):
- self.assertEqual(get_format('DEBUG'), 'DEBUG')
+ self.assertEqual(get_format("DEBUG"), "DEBUG")
def test_get_custom_format(self):
reset_format_cache()
- with self.settings(FORMAT_MODULE_PATH='i18n.other.locale'):
- with translation.override('fr', deactivate=True):
- self.assertEqual('d/m/Y CUSTOM', get_format('CUSTOM_DAY_FORMAT'))
+ with self.settings(FORMAT_MODULE_PATH="i18n.other.locale"):
+ with translation.override("fr", deactivate=True):
+ self.assertEqual("d/m/Y CUSTOM", get_format("CUSTOM_DAY_FORMAT"))
def test_admin_javascript_supported_input_formats(self):
"""
@@ -1339,21 +1645,27 @@ class FormattingTests(SimpleTestCase):
DATETIME_INPUT_FORMATS must not contain %f since that's unsupported by
the admin's time picker widget.
"""
- regex = re.compile('%([^BcdHImMpSwxXyY%])')
+ regex = re.compile("%([^BcdHImMpSwxXyY%])")
for language_code, language_name in settings.LANGUAGES:
- for format_name in ('DATE_INPUT_FORMATS', 'TIME_INPUT_FORMATS', 'DATETIME_INPUT_FORMATS'):
+ for format_name in (
+ "DATE_INPUT_FORMATS",
+ "TIME_INPUT_FORMATS",
+ "DATETIME_INPUT_FORMATS",
+ ):
with self.subTest(language=language_code, format=format_name):
formatter = get_format(format_name, lang=language_code)[0]
self.assertEqual(
- regex.findall(formatter), [],
- "%s locale's %s uses an unsupported format code." % (language_code, format_name)
+ regex.findall(formatter),
+ [],
+ "%s locale's %s uses an unsupported format code."
+ % (language_code, format_name),
)
class MiscTests(SimpleTestCase):
rf = RequestFactory()
- @override_settings(LANGUAGE_CODE='de')
+ @override_settings(LANGUAGE_CODE="de")
def test_english_fallback(self):
"""
With a non-English LANGUAGE_CODE and if the active language is English
@@ -1361,11 +1673,11 @@ class MiscTests(SimpleTestCase):
(instead of falling back to LANGUAGE_CODE) (See #24413).
"""
self.assertEqual(gettext("Image"), "Bild")
- with translation.override('en'):
+ with translation.override("en"):
self.assertEqual(gettext("Image"), "Image")
- with translation.override('en-us'):
+ with translation.override("en-us"):
self.assertEqual(gettext("Image"), "Image")
- with translation.override('en-ca'):
+ with translation.override("en-ca"):
self.assertEqual(gettext("Image"), "Image")
def test_parse_spec_http_header(self):
@@ -1376,98 +1688,109 @@ class MiscTests(SimpleTestCase):
"""
tests = [
# Good headers
- ('de', [('de', 1.0)]),
- ('en-AU', [('en-au', 1.0)]),
- ('es-419', [('es-419', 1.0)]),
- ('*;q=1.00', [('*', 1.0)]),
- ('en-AU;q=0.123', [('en-au', 0.123)]),
- ('en-au;q=0.5', [('en-au', 0.5)]),
- ('en-au;q=1.0', [('en-au', 1.0)]),
- ('da, en-gb;q=0.25, en;q=0.5', [('da', 1.0), ('en', 0.5), ('en-gb', 0.25)]),
- ('en-au-xx', [('en-au-xx', 1.0)]),
- ('de,en-au;q=0.75,en-us;q=0.5,en;q=0.25,es;q=0.125,fa;q=0.125',
- [('de', 1.0), ('en-au', 0.75), ('en-us', 0.5), ('en', 0.25), ('es', 0.125), ('fa', 0.125)]),
- ('*', [('*', 1.0)]),
- ('de;q=0.', [('de', 0.0)]),
- ('en; q=1,', [('en', 1.0)]),
- ('en; q=1.0, * ; q=0.5', [('en', 1.0), ('*', 0.5)]),
+ ("de", [("de", 1.0)]),
+ ("en-AU", [("en-au", 1.0)]),
+ ("es-419", [("es-419", 1.0)]),
+ ("*;q=1.00", [("*", 1.0)]),
+ ("en-AU;q=0.123", [("en-au", 0.123)]),
+ ("en-au;q=0.5", [("en-au", 0.5)]),
+ ("en-au;q=1.0", [("en-au", 1.0)]),
+ ("da, en-gb;q=0.25, en;q=0.5", [("da", 1.0), ("en", 0.5), ("en-gb", 0.25)]),
+ ("en-au-xx", [("en-au-xx", 1.0)]),
+ (
+ "de,en-au;q=0.75,en-us;q=0.5,en;q=0.25,es;q=0.125,fa;q=0.125",
+ [
+ ("de", 1.0),
+ ("en-au", 0.75),
+ ("en-us", 0.5),
+ ("en", 0.25),
+ ("es", 0.125),
+ ("fa", 0.125),
+ ],
+ ),
+ ("*", [("*", 1.0)]),
+ ("de;q=0.", [("de", 0.0)]),
+ ("en; q=1,", [("en", 1.0)]),
+ ("en; q=1.0, * ; q=0.5", [("en", 1.0), ("*", 0.5)]),
# Bad headers
- ('en-gb;q=1.0000', []),
- ('en;q=0.1234', []),
- ('en;q=.2', []),
- ('abcdefghi-au', []),
- ('**', []),
- ('en,,gb', []),
- ('en-au;q=0.1.0', []),
- (('X' * 97) + 'Z,en', []),
- ('da, en-gb;q=0.8, en;q=0.7,#', []),
- ('de;q=2.0', []),
- ('de;q=0.a', []),
- ('12-345', []),
- ('', []),
- ('en;q=1e0', []),
- ('en-au;q=1.0', []),
+ ("en-gb;q=1.0000", []),
+ ("en;q=0.1234", []),
+ ("en;q=.2", []),
+ ("abcdefghi-au", []),
+ ("**", []),
+ ("en,,gb", []),
+ ("en-au;q=0.1.0", []),
+ (("X" * 97) + "Z,en", []),
+ ("da, en-gb;q=0.8, en;q=0.7,#", []),
+ ("de;q=2.0", []),
+ ("de;q=0.a", []),
+ ("12-345", []),
+ ("", []),
+ ("en;q=1e0", []),
+ ("en-au;q=1.0", []),
]
for value, expected in tests:
with self.subTest(value=value):
- self.assertEqual(trans_real.parse_accept_lang_header(value), tuple(expected))
+ self.assertEqual(
+ trans_real.parse_accept_lang_header(value), tuple(expected)
+ )
def test_parse_literal_http_header(self):
"""
Now test that we parse a literal HTTP header correctly.
"""
g = get_language_from_request
- r = self.rf.get('/')
+ r = self.rf.get("/")
r.COOKIES = {}
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'pt-br'}
- self.assertEqual('pt-br', g(r))
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "pt-br"}
+ self.assertEqual("pt-br", g(r))
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'pt'}
- self.assertEqual('pt', g(r))
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "pt"}
+ self.assertEqual("pt", g(r))
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'es,de'}
- self.assertEqual('es', g(r))
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "es,de"}
+ self.assertEqual("es", g(r))
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-ar,de'}
- self.assertEqual('es-ar', g(r))
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "es-ar,de"}
+ self.assertEqual("es-ar", g(r))
# This test assumes there won't be a Django translation to a US
# variation of the Spanish language, a safe assumption. When the
# user sets it as the preferred language, the main 'es'
# translation should be selected instead.
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-us'}
- self.assertEqual(g(r), 'es')
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "es-us"}
+ self.assertEqual(g(r), "es")
# This tests the following scenario: there isn't a main language (zh)
# translation of Django but there is a translation to variation (zh-hans)
# the user sets zh-hans as the preferred language, it should be selected
# by Django without falling back nor ignoring it.
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'zh-hans,de'}
- self.assertEqual(g(r), 'zh-hans')
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "zh-hans,de"}
+ self.assertEqual(g(r), "zh-hans")
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'NL'}
- self.assertEqual('nl', g(r))
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "NL"}
+ self.assertEqual("nl", g(r))
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'fy'}
- self.assertEqual('fy', g(r))
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "fy"}
+ self.assertEqual("fy", g(r))
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'ia'}
- self.assertEqual('ia', g(r))
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "ia"}
+ self.assertEqual("ia", g(r))
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'sr-latn'}
- self.assertEqual('sr-latn', g(r))
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "sr-latn"}
+ self.assertEqual("sr-latn", g(r))
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'zh-hans'}
- self.assertEqual('zh-hans', g(r))
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "zh-hans"}
+ self.assertEqual("zh-hans", g(r))
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'zh-hant'}
- self.assertEqual('zh-hant', g(r))
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "zh-hant"}
+ self.assertEqual("zh-hant", g(r))
@override_settings(
LANGUAGES=[
- ('en', 'English'),
- ('zh-hans', 'Simplified Chinese'),
- ('zh-hant', 'Traditional Chinese'),
+ ("en", "English"),
+ ("zh-hans", "Simplified Chinese"),
+ ("zh-hant", "Traditional Chinese"),
]
)
def test_support_for_deprecated_chinese_language_codes(self):
@@ -1481,23 +1804,23 @@ class MiscTests(SimpleTestCase):
refs #18419 -- this is explicitly for browser compatibility
"""
g = get_language_from_request
- r = self.rf.get('/')
+ r = self.rf.get("/")
r.COOKIES = {}
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'zh-cn,en'}
- self.assertEqual(g(r), 'zh-hans')
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "zh-cn,en"}
+ self.assertEqual(g(r), "zh-hans")
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'zh-tw,en'}
- self.assertEqual(g(r), 'zh-hant')
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "zh-tw,en"}
+ self.assertEqual(g(r), "zh-hant")
def test_special_fallback_language(self):
"""
Some languages may have special fallbacks that don't follow the simple
'fr-ca' -> 'fr' logic (notably Chinese codes).
"""
- r = self.rf.get('/')
+ r = self.rf.get("/")
r.COOKIES = {}
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'zh-my,en'}
- self.assertEqual(get_language_from_request(r), 'zh-hans')
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "zh-my,en"}
+ self.assertEqual(get_language_from_request(r), "zh-hans")
def test_subsequent_code_fallback_language(self):
"""
@@ -1505,18 +1828,18 @@ class MiscTests(SimpleTestCase):
supported.
"""
tests = [
- ('zh-Hans-CN', 'zh-hans'),
- ('zh-hans-mo', 'zh-hans'),
- ('zh-hans-HK', 'zh-hans'),
- ('zh-Hant-HK', 'zh-hant'),
- ('zh-hant-tw', 'zh-hant'),
- ('zh-hant-SG', 'zh-hant'),
+ ("zh-Hans-CN", "zh-hans"),
+ ("zh-hans-mo", "zh-hans"),
+ ("zh-hans-HK", "zh-hans"),
+ ("zh-Hant-HK", "zh-hant"),
+ ("zh-hant-tw", "zh-hant"),
+ ("zh-hant-SG", "zh-hant"),
]
- r = self.rf.get('/')
+ r = self.rf.get("/")
r.COOKIES = {}
for value, expected in tests:
with self.subTest(value=value):
- r.META = {'HTTP_ACCEPT_LANGUAGE': f'{value},en'}
+ r.META = {"HTTP_ACCEPT_LANGUAGE": f"{value},en"}
self.assertEqual(get_language_from_request(r), expected)
def test_parse_language_cookie(self):
@@ -1524,113 +1847,113 @@ class MiscTests(SimpleTestCase):
Now test that we parse language preferences stored in a cookie correctly.
"""
g = get_language_from_request
- r = self.rf.get('/')
- r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: 'pt-br'}
+ r = self.rf.get("/")
+ r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: "pt-br"}
r.META = {}
- self.assertEqual('pt-br', g(r))
+ self.assertEqual("pt-br", g(r))
- r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: 'pt'}
+ r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: "pt"}
r.META = {}
- self.assertEqual('pt', g(r))
+ self.assertEqual("pt", g(r))
- r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: 'es'}
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'de'}
- self.assertEqual('es', g(r))
+ r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: "es"}
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "de"}
+ self.assertEqual("es", g(r))
# This test assumes there won't be a Django translation to a US
# variation of the Spanish language, a safe assumption. When the
# user sets it as the preferred language, the main 'es'
# translation should be selected instead.
- r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: 'es-us'}
+ r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: "es-us"}
r.META = {}
- self.assertEqual(g(r), 'es')
+ self.assertEqual(g(r), "es")
# This tests the following scenario: there isn't a main language (zh)
# translation of Django but there is a translation to variation (zh-hans)
# the user sets zh-hans as the preferred language, it should be selected
# by Django without falling back nor ignoring it.
- r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: 'zh-hans'}
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'de'}
- self.assertEqual(g(r), 'zh-hans')
+ r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: "zh-hans"}
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "de"}
+ self.assertEqual(g(r), "zh-hans")
@override_settings(
USE_I18N=True,
LANGUAGES=[
- ('en', 'English'),
- ('de', 'German'),
- ('de-at', 'Austrian German'),
- ('pt-br', 'Portuguese (Brazil)'),
+ ("en", "English"),
+ ("de", "German"),
+ ("de-at", "Austrian German"),
+ ("pt-br", "Portuguese (Brazil)"),
],
)
def test_get_supported_language_variant_real(self):
g = trans_real.get_supported_language_variant
- self.assertEqual(g('en'), 'en')
- self.assertEqual(g('en-gb'), 'en')
- self.assertEqual(g('de'), 'de')
- self.assertEqual(g('de-at'), 'de-at')
- self.assertEqual(g('de-ch'), 'de')
- self.assertEqual(g('pt-br'), 'pt-br')
- self.assertEqual(g('pt'), 'pt-br')
- self.assertEqual(g('pt-pt'), 'pt-br')
+ self.assertEqual(g("en"), "en")
+ self.assertEqual(g("en-gb"), "en")
+ self.assertEqual(g("de"), "de")
+ self.assertEqual(g("de-at"), "de-at")
+ self.assertEqual(g("de-ch"), "de")
+ self.assertEqual(g("pt-br"), "pt-br")
+ self.assertEqual(g("pt"), "pt-br")
+ self.assertEqual(g("pt-pt"), "pt-br")
with self.assertRaises(LookupError):
- g('pt', strict=True)
+ g("pt", strict=True)
with self.assertRaises(LookupError):
- g('pt-pt', strict=True)
+ g("pt-pt", strict=True)
with self.assertRaises(LookupError):
- g('xyz')
+ g("xyz")
with self.assertRaises(LookupError):
- g('xy-zz')
+ g("xy-zz")
def test_get_supported_language_variant_null(self):
g = trans_null.get_supported_language_variant
self.assertEqual(g(settings.LANGUAGE_CODE), settings.LANGUAGE_CODE)
with self.assertRaises(LookupError):
- g('pt')
+ g("pt")
with self.assertRaises(LookupError):
- g('de')
+ g("de")
with self.assertRaises(LookupError):
- g('de-at')
+ g("de-at")
with self.assertRaises(LookupError):
- g('de', strict=True)
+ g("de", strict=True)
with self.assertRaises(LookupError):
- g('de-at', strict=True)
+ g("de-at", strict=True)
with self.assertRaises(LookupError):
- g('xyz')
+ g("xyz")
@override_settings(
LANGUAGES=[
- ('en', 'English'),
- ('en-latn-us', 'Latin English'),
- ('en-Latn-US', 'BCP 47 case format'),
- ('de', 'German'),
- ('de-1996', 'German, orthography of 1996'),
- ('de-at', 'Austrian German'),
- ('de-ch-1901', 'German, Swiss variant, traditional orthography'),
- ('i-mingo', 'Mingo'),
- ('kl-tunumiit', 'Tunumiisiut'),
- ('nan-hani-tw', 'Hanji'),
- ('pl', 'Polish'),
+ ("en", "English"),
+ ("en-latn-us", "Latin English"),
+ ("en-Latn-US", "BCP 47 case format"),
+ ("de", "German"),
+ ("de-1996", "German, orthography of 1996"),
+ ("de-at", "Austrian German"),
+ ("de-ch-1901", "German, Swiss variant, traditional orthography"),
+ ("i-mingo", "Mingo"),
+ ("kl-tunumiit", "Tunumiisiut"),
+ ("nan-hani-tw", "Hanji"),
+ ("pl", "Polish"),
],
)
def test_get_language_from_path_real(self):
g = trans_real.get_language_from_path
tests = [
- ('/pl/', 'pl'),
- ('/pl', 'pl'),
- ('/xyz/', None),
- ('/en/', 'en'),
- ('/en-gb/', 'en'),
- ('/en-latn-us/', 'en-latn-us'),
- ('/en-Latn-US/', 'en-Latn-US'),
- ('/de/', 'de'),
- ('/de-1996/', 'de-1996'),
- ('/de-at/', 'de-at'),
- ('/de-ch/', 'de'),
- ('/de-ch-1901/', 'de-ch-1901'),
- ('/de-simple-page-test/', None),
- ('/i-mingo/', 'i-mingo'),
- ('/kl-tunumiit/', 'kl-tunumiit'),
- ('/nan-hani-tw/', 'nan-hani-tw'),
+ ("/pl/", "pl"),
+ ("/pl", "pl"),
+ ("/xyz/", None),
+ ("/en/", "en"),
+ ("/en-gb/", "en"),
+ ("/en-latn-us/", "en-latn-us"),
+ ("/en-Latn-US/", "en-Latn-US"),
+ ("/de/", "de"),
+ ("/de-1996/", "de-1996"),
+ ("/de-at/", "de-at"),
+ ("/de-ch/", "de"),
+ ("/de-ch-1901/", "de-ch-1901"),
+ ("/de-simple-page-test/", None),
+ ("/i-mingo/", "i-mingo"),
+ ("/kl-tunumiit/", "kl-tunumiit"),
+ ("/nan-hani-tw/", "nan-hani-tw"),
]
for path, language in tests:
with self.subTest(path=path):
@@ -1638,9 +1961,9 @@ class MiscTests(SimpleTestCase):
def test_get_language_from_path_null(self):
g = trans_null.get_language_from_path
- self.assertIsNone(g('/pl/'))
- self.assertIsNone(g('/pl'))
- self.assertIsNone(g('/xyz/'))
+ self.assertIsNone(g("/pl/"))
+ self.assertIsNone(g("/pl"))
+ self.assertIsNone(g("/xyz/"))
def test_cache_resetting(self):
"""
@@ -1648,12 +1971,12 @@ class MiscTests(SimpleTestCase):
previously valid should not be used (#14170).
"""
g = get_language_from_request
- r = self.rf.get('/')
+ r = self.rf.get("/")
r.COOKIES = {}
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'pt-br'}
- self.assertEqual('pt-br', g(r))
- with self.settings(LANGUAGES=[('en', 'English')]):
- self.assertNotEqual('pt-br', g(r))
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "pt-br"}
+ self.assertEqual("pt-br", g(r))
+ with self.settings(LANGUAGES=[("en", "English")]):
+ self.assertNotEqual("pt-br", g(r))
def test_i18n_patterns_returns_list(self):
with override_settings(USE_I18N=False):
@@ -1663,10 +1986,9 @@ class MiscTests(SimpleTestCase):
class ResolutionOrderI18NTests(SimpleTestCase):
-
def setUp(self):
super().setUp()
- activate('de')
+ activate("de")
def tearDown(self):
deactivate()
@@ -1675,64 +1997,63 @@ class ResolutionOrderI18NTests(SimpleTestCase):
def assertGettext(self, msgid, msgstr):
result = gettext(msgid)
self.assertIn(
- msgstr, result,
+ msgstr,
+ result,
"The string '%s' isn't in the translation of '%s'; the actual result is '%s'."
- % (msgstr, msgid, result)
+ % (msgstr, msgid, result),
)
class AppResolutionOrderI18NTests(ResolutionOrderI18NTests):
-
- @override_settings(LANGUAGE_CODE='de')
+ @override_settings(LANGUAGE_CODE="de")
def test_app_translation(self):
# Original translation.
- self.assertGettext('Date/time', 'Datum/Zeit')
+ self.assertGettext("Date/time", "Datum/Zeit")
# Different translation.
- with self.modify_settings(INSTALLED_APPS={'append': 'i18n.resolution'}):
+ with self.modify_settings(INSTALLED_APPS={"append": "i18n.resolution"}):
# Force refreshing translations.
- activate('de')
+ activate("de")
# Doesn't work because it's added later in the list.
- self.assertGettext('Date/time', 'Datum/Zeit')
+ self.assertGettext("Date/time", "Datum/Zeit")
- with self.modify_settings(INSTALLED_APPS={'remove': 'django.contrib.admin.apps.SimpleAdminConfig'}):
+ with self.modify_settings(
+ INSTALLED_APPS={"remove": "django.contrib.admin.apps.SimpleAdminConfig"}
+ ):
# Force refreshing translations.
- activate('de')
+ activate("de")
# Unless the original is removed from the list.
- self.assertGettext('Date/time', 'Datum/Zeit (APP)')
+ self.assertGettext("Date/time", "Datum/Zeit (APP)")
@override_settings(LOCALE_PATHS=extended_locale_paths)
class LocalePathsResolutionOrderI18NTests(ResolutionOrderI18NTests):
-
def test_locale_paths_translation(self):
- self.assertGettext('Time', 'LOCALE_PATHS')
+ self.assertGettext("Time", "LOCALE_PATHS")
def test_locale_paths_override_app_translation(self):
- with self.settings(INSTALLED_APPS=['i18n.resolution']):
- self.assertGettext('Time', 'LOCALE_PATHS')
+ with self.settings(INSTALLED_APPS=["i18n.resolution"]):
+ self.assertGettext("Time", "LOCALE_PATHS")
class DjangoFallbackResolutionOrderI18NTests(ResolutionOrderI18NTests):
-
def test_django_fallback(self):
- self.assertEqual(gettext('Date/time'), 'Datum/Zeit')
+ self.assertEqual(gettext("Date/time"), "Datum/Zeit")
-@override_settings(INSTALLED_APPS=['i18n.territorial_fallback'])
+@override_settings(INSTALLED_APPS=["i18n.territorial_fallback"])
class TranslationFallbackI18NTests(ResolutionOrderI18NTests):
-
def test_sparse_territory_catalog(self):
"""
Untranslated strings for territorial language variants use the
translations of the generic language. In this case, the de-de
translation falls back to de.
"""
- with translation.override('de-de'):
- self.assertGettext('Test 1 (en)', '(de-de)')
- self.assertGettext('Test 2 (en)', '(de)')
+ with translation.override("de-de"):
+ self.assertGettext("Test 1 (en)", "(de-de)")
+ self.assertGettext("Test 2 (en)", "(de)")
class TestModels(TestCase):
@@ -1742,83 +2063,82 @@ class TestModels(TestCase):
def test_safestr(self):
c = Company(cents_paid=12, products_delivered=1)
- c.name = SafeString('Iñtërnâtiônàlizætiøn1')
+ c.name = SafeString("Iñtërnâtiônàlizætiøn1")
c.save()
class TestLanguageInfo(SimpleTestCase):
def test_localized_language_info(self):
- li = get_language_info('de')
- self.assertEqual(li['code'], 'de')
- self.assertEqual(li['name_local'], 'Deutsch')
- self.assertEqual(li['name'], 'German')
- self.assertIs(li['bidi'], False)
+ li = get_language_info("de")
+ self.assertEqual(li["code"], "de")
+ self.assertEqual(li["name_local"], "Deutsch")
+ self.assertEqual(li["name"], "German")
+ self.assertIs(li["bidi"], False)
def test_unknown_language_code(self):
with self.assertRaisesMessage(KeyError, "Unknown language code xx"):
- get_language_info('xx')
- with translation.override('xx'):
+ get_language_info("xx")
+ with translation.override("xx"):
# A language with no translation catalogs should fallback to the
# untranslated string.
self.assertEqual(gettext("Title"), "Title")
def test_unknown_only_country_code(self):
- li = get_language_info('de-xx')
- self.assertEqual(li['code'], 'de')
- self.assertEqual(li['name_local'], 'Deutsch')
- self.assertEqual(li['name'], 'German')
- self.assertIs(li['bidi'], False)
+ li = get_language_info("de-xx")
+ self.assertEqual(li["code"], "de")
+ self.assertEqual(li["name_local"], "Deutsch")
+ self.assertEqual(li["name"], "German")
+ self.assertIs(li["bidi"], False)
def test_unknown_language_code_and_country_code(self):
with self.assertRaisesMessage(KeyError, "Unknown language code xx-xx and xx"):
- get_language_info('xx-xx')
+ get_language_info("xx-xx")
def test_fallback_language_code(self):
"""
get_language_info return the first fallback language info if the lang_info
struct does not contain the 'name' key.
"""
- li = get_language_info('zh-my')
- self.assertEqual(li['code'], 'zh-hans')
- li = get_language_info('zh-hans')
- self.assertEqual(li['code'], 'zh-hans')
+ li = get_language_info("zh-my")
+ self.assertEqual(li["code"], "zh-hans")
+ li = get_language_info("zh-hans")
+ self.assertEqual(li["code"], "zh-hans")
@override_settings(
USE_I18N=True,
LANGUAGES=[
- ('en', 'English'),
- ('fr', 'French'),
+ ("en", "English"),
+ ("fr", "French"),
],
MIDDLEWARE=[
- 'django.middleware.locale.LocaleMiddleware',
- 'django.middleware.common.CommonMiddleware',
+ "django.middleware.locale.LocaleMiddleware",
+ "django.middleware.common.CommonMiddleware",
],
- ROOT_URLCONF='i18n.urls',
+ ROOT_URLCONF="i18n.urls",
)
class LocaleMiddlewareTests(TestCase):
-
def test_streaming_response(self):
# Regression test for #5241
- response = self.client.get('/fr/streaming/')
+ response = self.client.get("/fr/streaming/")
self.assertContains(response, "Oui/Non")
- response = self.client.get('/en/streaming/')
+ response = self.client.get("/en/streaming/")
self.assertContains(response, "Yes/No")
@override_settings(
USE_I18N=True,
LANGUAGES=[
- ('en', 'English'),
- ('de', 'German'),
- ('fr', 'French'),
+ ("en", "English"),
+ ("de", "German"),
+ ("fr", "French"),
],
MIDDLEWARE=[
- 'django.middleware.locale.LocaleMiddleware',
- 'django.middleware.common.CommonMiddleware',
+ "django.middleware.locale.LocaleMiddleware",
+ "django.middleware.common.CommonMiddleware",
],
- ROOT_URLCONF='i18n.urls_default_unprefixed',
- LANGUAGE_CODE='en',
+ ROOT_URLCONF="i18n.urls_default_unprefixed",
+ LANGUAGE_CODE="en",
)
class UnprefixedDefaultLanguageTests(SimpleTestCase):
def test_default_lang_without_prefix(self):
@@ -1826,21 +2146,21 @@ class UnprefixedDefaultLanguageTests(SimpleTestCase):
With i18n_patterns(..., prefix_default_language=False), the default
language (settings.LANGUAGE_CODE) should be accessible without a prefix.
"""
- response = self.client.get('/simple/')
- self.assertEqual(response.content, b'Yes')
+ response = self.client.get("/simple/")
+ self.assertEqual(response.content, b"Yes")
def test_other_lang_with_prefix(self):
- response = self.client.get('/fr/simple/')
- self.assertEqual(response.content, b'Oui')
+ response = self.client.get("/fr/simple/")
+ self.assertEqual(response.content, b"Oui")
def test_unprefixed_language_other_than_accept_language(self):
- response = self.client.get('/simple/', HTTP_ACCEPT_LANGUAGE='fr')
- self.assertEqual(response.content, b'Yes')
+ response = self.client.get("/simple/", HTTP_ACCEPT_LANGUAGE="fr")
+ self.assertEqual(response.content, b"Yes")
def test_page_with_dash(self):
# A page starting with /de* shouldn't match the 'de' language code.
- response = self.client.get('/de-simple-page-test/')
- self.assertEqual(response.content, b'Yes')
+ response = self.client.get("/de-simple-page-test/")
+ self.assertEqual(response.content, b"Yes")
def test_no_redirect_on_404(self):
"""
@@ -1850,86 +2170,85 @@ class UnprefixedDefaultLanguageTests(SimpleTestCase):
"""
# A match for /group1/group2/ must exist for this to act as a
# regression test.
- response = self.client.get('/group1/group2/')
+ response = self.client.get("/group1/group2/")
self.assertEqual(response.status_code, 200)
- response = self.client.get('/nonexistent/')
+ response = self.client.get("/nonexistent/")
self.assertEqual(response.status_code, 404)
@override_settings(
USE_I18N=True,
LANGUAGES=[
- ('bg', 'Bulgarian'),
- ('en-us', 'English'),
- ('pt-br', 'Portuguese (Brazil)'),
+ ("bg", "Bulgarian"),
+ ("en-us", "English"),
+ ("pt-br", "Portuguese (Brazil)"),
],
MIDDLEWARE=[
- 'django.middleware.locale.LocaleMiddleware',
- 'django.middleware.common.CommonMiddleware',
+ "django.middleware.locale.LocaleMiddleware",
+ "django.middleware.common.CommonMiddleware",
],
- ROOT_URLCONF='i18n.urls'
+ ROOT_URLCONF="i18n.urls",
)
class CountrySpecificLanguageTests(SimpleTestCase):
rf = RequestFactory()
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'))
- self.assertTrue(check_for_language('sr-RS@12345'))
- self.assertFalse(check_for_language('en-ü'))
- self.assertFalse(check_for_language('en\x00'))
+ 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"))
+ self.assertTrue(check_for_language("sr-RS@12345"))
+ self.assertFalse(check_for_language("en-ü"))
+ self.assertFalse(check_for_language("en\x00"))
self.assertFalse(check_for_language(None))
- self.assertFalse(check_for_language('be@ '))
+ self.assertFalse(check_for_language("be@ "))
# Specifying encoding is not supported (Django enforces UTF-8)
- self.assertFalse(check_for_language('tr-TR.UTF-8'))
- self.assertFalse(check_for_language('tr-TR.UTF8'))
- self.assertFalse(check_for_language('de-DE.utf-8'))
+ self.assertFalse(check_for_language("tr-TR.UTF-8"))
+ self.assertFalse(check_for_language("tr-TR.UTF8"))
+ self.assertFalse(check_for_language("de-DE.utf-8"))
def test_check_for_language_null(self):
- self.assertIs(trans_null.check_for_language('en'), True)
+ self.assertIs(trans_null.check_for_language("en"), True)
def test_get_language_from_request(self):
# issue 19919
- r = self.rf.get('/')
+ r = self.rf.get("/")
r.COOKIES = {}
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.8,bg;q=0.6,ru;q=0.4'}
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "en-US,en;q=0.8,bg;q=0.6,ru;q=0.4"}
lang = get_language_from_request(r)
- self.assertEqual('en-us', lang)
- r = self.rf.get('/')
+ self.assertEqual("en-us", lang)
+ r = self.rf.get("/")
r.COOKIES = {}
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'bg-bg,en-US;q=0.8,en;q=0.6,ru;q=0.4'}
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "bg-bg,en-US;q=0.8,en;q=0.6,ru;q=0.4"}
lang = get_language_from_request(r)
- self.assertEqual('bg', lang)
+ self.assertEqual("bg", lang)
def test_get_language_from_request_null(self):
lang = trans_null.get_language_from_request(None)
- self.assertEqual(lang, 'en')
- with override_settings(LANGUAGE_CODE='de'):
+ self.assertEqual(lang, "en")
+ with override_settings(LANGUAGE_CODE="de"):
lang = trans_null.get_language_from_request(None)
- self.assertEqual(lang, 'de')
+ self.assertEqual(lang, "de")
def test_specific_language_codes(self):
# issue 11915
- r = self.rf.get('/')
+ r = self.rf.get("/")
r.COOKIES = {}
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'pt,en-US;q=0.8,en;q=0.6,ru;q=0.4'}
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "pt,en-US;q=0.8,en;q=0.6,ru;q=0.4"}
lang = get_language_from_request(r)
- self.assertEqual('pt-br', lang)
- r = self.rf.get('/')
+ self.assertEqual("pt-br", lang)
+ r = self.rf.get("/")
r.COOKIES = {}
- r.META = {'HTTP_ACCEPT_LANGUAGE': 'pt-pt,en-US;q=0.8,en;q=0.6,ru;q=0.4'}
+ r.META = {"HTTP_ACCEPT_LANGUAGE": "pt-pt,en-US;q=0.8,en;q=0.6,ru;q=0.4"}
lang = get_language_from_request(r)
- self.assertEqual('pt-br', lang)
+ self.assertEqual("pt-br", lang)
class TranslationFilesMissing(SimpleTestCase):
-
def setUp(self):
super().setUp()
self.gettext_find_builtin = gettext_module.find
@@ -1946,7 +2265,7 @@ class TranslationFilesMissing(SimpleTestCase):
self.patchGettextFind()
trans_real._translations = {}
with self.assertRaises(OSError):
- activate('en')
+ activate("en")
class NonDjangoLanguageTests(SimpleTestCase):
@@ -1954,40 +2273,48 @@ class NonDjangoLanguageTests(SimpleTestCase):
A language non present in default Django languages can still be
installed/used by a Django project.
"""
+
@override_settings(
USE_I18N=True,
LANGUAGES=[
- ('en-us', 'English'),
- ('xxx', 'Somelanguage'),
+ ("en-us", "English"),
+ ("xxx", "Somelanguage"),
],
- LANGUAGE_CODE='xxx',
- LOCALE_PATHS=[os.path.join(here, 'commands', 'locale')],
+ LANGUAGE_CODE="xxx",
+ LOCALE_PATHS=[os.path.join(here, "commands", "locale")],
)
def test_non_django_language(self):
- self.assertEqual(get_language(), 'xxx')
+ self.assertEqual(get_language(), "xxx")
self.assertEqual(gettext("year"), "reay")
@override_settings(USE_I18N=True)
def test_check_for_language(self):
with tempfile.TemporaryDirectory() as app_dir:
- os.makedirs(os.path.join(app_dir, 'locale', 'dummy_Lang', 'LC_MESSAGES'))
- open(os.path.join(app_dir, 'locale', 'dummy_Lang', 'LC_MESSAGES', 'django.mo'), 'w').close()
- app_config = AppConfig('dummy_app', AppModuleStub(__path__=[app_dir]))
- with mock.patch('django.apps.apps.get_app_configs', return_value=[app_config]):
- self.assertIs(check_for_language('dummy-lang'), True)
+ os.makedirs(os.path.join(app_dir, "locale", "dummy_Lang", "LC_MESSAGES"))
+ open(
+ os.path.join(
+ app_dir, "locale", "dummy_Lang", "LC_MESSAGES", "django.mo"
+ ),
+ "w",
+ ).close()
+ app_config = AppConfig("dummy_app", AppModuleStub(__path__=[app_dir]))
+ with mock.patch(
+ "django.apps.apps.get_app_configs", return_value=[app_config]
+ ):
+ self.assertIs(check_for_language("dummy-lang"), True)
@override_settings(
USE_I18N=True,
LANGUAGES=[
- ('en-us', 'English'),
+ ("en-us", "English"),
# xyz language has no locale files
- ('xyz', 'XYZ'),
+ ("xyz", "XYZ"),
],
)
- @translation.override('xyz')
+ @translation.override("xyz")
def test_plural_non_django_language(self):
- self.assertEqual(get_language(), 'xyz')
- self.assertEqual(ngettext('year', 'years', 2), 'years')
+ self.assertEqual(get_language(), "xyz")
+ self.assertEqual(ngettext("year", "years", 2), "years")
@override_settings(USE_I18N=True)
@@ -2008,26 +2335,26 @@ class WatchForTranslationChangesTests(SimpleTestCase):
with tempfile.TemporaryDirectory() as app_dir:
with self.settings(LOCALE_PATHS=[app_dir]):
watch_for_translation_changes(mocked_sender)
- mocked_sender.watch_dir.assert_any_call(Path(app_dir), '**/*.mo')
+ mocked_sender.watch_dir.assert_any_call(Path(app_dir), "**/*.mo")
def test_i18n_app_dirs(self):
mocked_sender = mock.MagicMock()
- with self.settings(INSTALLED_APPS=['tests.i18n.sampleproject']):
+ with self.settings(INSTALLED_APPS=["tests.i18n.sampleproject"]):
watch_for_translation_changes(mocked_sender)
- project_dir = Path(__file__).parent / 'sampleproject' / 'locale'
- mocked_sender.watch_dir.assert_any_call(project_dir, '**/*.mo')
+ project_dir = Path(__file__).parent / "sampleproject" / "locale"
+ mocked_sender.watch_dir.assert_any_call(project_dir, "**/*.mo")
def test_i18n_app_dirs_ignore_django_apps(self):
mocked_sender = mock.MagicMock()
- with self.settings(INSTALLED_APPS=['django.contrib.admin']):
+ with self.settings(INSTALLED_APPS=["django.contrib.admin"]):
watch_for_translation_changes(mocked_sender)
- mocked_sender.watch_dir.assert_called_once_with(Path('locale'), '**/*.mo')
+ mocked_sender.watch_dir.assert_called_once_with(Path("locale"), "**/*.mo")
def test_i18n_local_locale(self):
mocked_sender = mock.MagicMock()
watch_for_translation_changes(mocked_sender)
- locale_dir = Path(__file__).parent / 'locale'
- mocked_sender.watch_dir.assert_any_call(locale_dir, '**/*.mo')
+ locale_dir = Path(__file__).parent / "locale"
+ mocked_sender.watch_dir.assert_any_call(locale_dir, "**/*.mo")
class TranslationFileChangedTests(SimpleTestCase):
@@ -2040,17 +2367,17 @@ class TranslationFileChangedTests(SimpleTestCase):
trans_real._translations = self.trans_real_translations
def test_ignores_non_mo_files(self):
- gettext_module._translations = {'foo': 'bar'}
- path = Path('test.py')
+ gettext_module._translations = {"foo": "bar"}
+ path = Path("test.py")
self.assertIsNone(translation_file_changed(None, path))
- self.assertEqual(gettext_module._translations, {'foo': 'bar'})
+ self.assertEqual(gettext_module._translations, {"foo": "bar"})
def test_resets_cache_with_mo_files(self):
- gettext_module._translations = {'foo': 'bar'}
- trans_real._translations = {'foo': 'bar'}
+ gettext_module._translations = {"foo": "bar"}
+ trans_real._translations = {"foo": "bar"}
trans_real._default = 1
trans_real._active = False
- path = Path('test.mo')
+ path = Path("test.mo")
self.assertIs(translation_file_changed(None, path), True)
self.assertEqual(gettext_module._translations, {})
self.assertEqual(trans_real._translations, {})
@@ -2062,21 +2389,21 @@ class UtilsTests(SimpleTestCase):
def test_round_away_from_one(self):
tests = [
(0, 0),
- (0., 0),
+ (0.0, 0),
(0.25, 0),
(0.5, 0),
(0.75, 0),
(1, 1),
- (1., 1),
+ (1.0, 1),
(1.25, 2),
(1.5, 2),
(1.75, 2),
- (-0., 0),
+ (-0.0, 0),
(-0.25, -1),
(-0.5, -1),
(-0.75, -1),
(-1, -1),
- (-1., -1),
+ (-1.0, -1),
(-1.25, -2),
(-1.5, -2),
(-1.75, -2),
diff --git a/tests/i18n/unchanged/__init__.py b/tests/i18n/unchanged/__init__.py
index 0ff42ffd6c..afcadcbcb7 100644
--- a/tests/i18n/unchanged/__init__.py
+++ b/tests/i18n/unchanged/__init__.py
@@ -1,4 +1,4 @@
from django.utils.translation import gettext as _
-string1 = _('This is a translatable string.')
-string2 = _('This is another translatable string.')
+string1 = _("This is a translatable string.")
+string2 = _("This is another translatable string.")
diff --git a/tests/i18n/urls.py b/tests/i18n/urls.py
index 6a1dd75e24..6e2ffab83f 100644
--- a/tests/i18n/urls.py
+++ b/tests/i18n/urls.py
@@ -4,6 +4,6 @@ from django.urls import path
from django.utils.translation import gettext_lazy as _
urlpatterns = i18n_patterns(
- path('simple/', lambda r: HttpResponse()),
- path('streaming/', lambda r: StreamingHttpResponse([_('Yes'), '/', _('No')])),
+ path("simple/", lambda r: HttpResponse()),
+ path("streaming/", lambda r: StreamingHttpResponse([_("Yes"), "/", _("No")])),
)
diff --git a/tests/i18n/urls_default_unprefixed.py b/tests/i18n/urls_default_unprefixed.py
index 8801d078f4..f14b059d37 100644
--- a/tests/i18n/urls_default_unprefixed.py
+++ b/tests/i18n/urls_default_unprefixed.py
@@ -4,8 +4,8 @@ from django.urls import path, re_path
from django.utils.translation import gettext_lazy as _
urlpatterns = i18n_patterns(
- re_path(r'^(?P<arg>[\w-]+)-page', lambda request, **arg: HttpResponse(_('Yes'))),
- path('simple/', lambda r: HttpResponse(_('Yes'))),
- re_path(r'^(.+)/(.+)/$', lambda *args: HttpResponse()),
+ re_path(r"^(?P<arg>[\w-]+)-page", lambda request, **arg: HttpResponse(_("Yes"))),
+ path("simple/", lambda r: HttpResponse(_("Yes"))),
+ re_path(r"^(.+)/(.+)/$", lambda *args: HttpResponse()),
prefix_default_language=False,
)
diff --git a/tests/i18n/utils.py b/tests/i18n/utils.py
index d6cae260aa..625f4a8841 100644
--- a/tests/i18n/utils.py
+++ b/tests/i18n/utils.py
@@ -7,25 +7,25 @@ source_code_dir = os.path.dirname(__file__)
def copytree(src, dst):
- shutil.copytree(src, dst, ignore=shutil.ignore_patterns('__pycache__'))
+ shutil.copytree(src, dst, ignore=shutil.ignore_patterns("__pycache__"))
class POFileAssertionMixin:
-
def _assertPoKeyword(self, keyword, expected_value, haystack, use_quotes=True):
q = '"'
if use_quotes:
expected_value = '"%s"' % expected_value
q = "'"
- needle = '%s %s' % (keyword, expected_value)
+ needle = "%s %s" % (keyword, expected_value)
expected_value = re.escape(expected_value)
return self.assertTrue(
- re.search('^%s %s' % (keyword, expected_value), haystack, re.MULTILINE),
- 'Could not find %(q)s%(n)s%(q)s in generated PO file' % {'n': needle, 'q': q}
+ re.search("^%s %s" % (keyword, expected_value), haystack, re.MULTILINE),
+ "Could not find %(q)s%(n)s%(q)s in generated PO file"
+ % {"n": needle, "q": q},
)
def assertMsgId(self, msgid, haystack, use_quotes=True):
- return self._assertPoKeyword('msgid', msgid, haystack, use_quotes=use_quotes)
+ return self._assertPoKeyword("msgid", msgid, haystack, use_quotes=use_quotes)
class RunInTmpDirMixin:
@@ -44,7 +44,7 @@ class RunInTmpDirMixin:
def setUp(self):
self._cwd = os.getcwd()
- self.work_dir = tempfile.mkdtemp(prefix='i18n_')
+ self.work_dir = tempfile.mkdtemp(prefix="i18n_")
# Resolve symlinks, if any, in test directory paths.
self.test_dir = os.path.realpath(os.path.join(self.work_dir, self.work_subdir))
copytree(os.path.join(source_code_dir, self.work_subdir), self.test_dir)
@@ -56,6 +56,9 @@ class RunInTmpDirMixin:
os.chdir(self.test_dir)
def _rmrf(self, dname):
- if os.path.commonprefix([self.test_dir, os.path.abspath(dname)]) != self.test_dir:
+ if (
+ os.path.commonprefix([self.test_dir, os.path.abspath(dname)])
+ != self.test_dir
+ ):
return
shutil.rmtree(dname)