测试gitnore

This commit is contained in:
ladeng07
2022-05-06 15:45:57 +08:00
parent 12f390949b
commit 51552904f9
2347 changed files with 120102 additions and 53549 deletions
@@ -1,37 +1,31 @@
"""
Internationalization support.
"""
import warnings
from contextlib import ContextDecorator
from decimal import ROUND_UP, Decimal
from django.utils.autoreload import autoreload_started, file_changed
from django.utils.deprecation import RemovedInDjango40Warning
from django.utils.functional import lazy
from django.utils.regex_helper import _lazy_re_compile
__all__ = [
"activate",
"deactivate",
"override",
"deactivate_all",
"get_language",
"get_language_from_request",
"get_language_info",
"get_language_bidi",
"check_for_language",
"to_language",
"to_locale",
"templatize",
"gettext",
"gettext_lazy",
"gettext_noop",
"ngettext",
"ngettext_lazy",
"pgettext",
"pgettext_lazy",
"npgettext",
"npgettext_lazy",
'activate', 'deactivate', 'override', 'deactivate_all',
'get_language', 'get_language_from_request',
'get_language_info', 'get_language_bidi',
'check_for_language', 'to_language', 'to_locale', 'templatize',
'gettext', 'gettext_lazy', 'gettext_noop',
'ugettext', 'ugettext_lazy', 'ugettext_noop',
'ngettext', 'ngettext_lazy',
'ungettext', 'ungettext_lazy',
'pgettext', 'pgettext_lazy',
'npgettext', 'npgettext_lazy',
'LANGUAGE_SESSION_KEY',
]
LANGUAGE_SESSION_KEY = '_language'
class TranslatorCommentWarning(SyntaxWarning):
pass
@@ -45,7 +39,6 @@ class TranslatorCommentWarning(SyntaxWarning):
# replace the functions with their real counterparts (once we do access the
# settings).
class Trans:
"""
The purpose of this class is to store the actual translation function upon
@@ -61,20 +54,13 @@ class Trans:
def __getattr__(self, real_name):
from django.conf import settings
if settings.USE_I18N:
from django.utils.translation import trans_real as trans
from django.utils.translation.reloader import (
translation_file_changed,
watch_for_translation_changes,
)
autoreload_started.connect(
watch_for_translation_changes, dispatch_uid="translation_file_changed"
)
file_changed.connect(
translation_file_changed, dispatch_uid="translation_file_changed"
translation_file_changed, watch_for_translation_changes,
)
autoreload_started.connect(watch_for_translation_changes, dispatch_uid='translation_file_changed')
file_changed.connect(translation_file_changed, dispatch_uid='translation_file_changed')
else:
from django.utils.translation import trans_null as trans
setattr(self, real_name, getattr(trans, real_name))
@@ -91,14 +77,53 @@ def gettext_noop(message):
return _trans.gettext_noop(message)
def ugettext_noop(message):
"""
A legacy compatibility wrapper for Unicode handling on Python 2.
Alias of gettext_noop() since Django 2.0.
"""
warnings.warn(
'django.utils.translation.ugettext_noop() is deprecated in favor of '
'django.utils.translation.gettext_noop().',
RemovedInDjango40Warning, stacklevel=2,
)
return gettext_noop(message)
def gettext(message):
return _trans.gettext(message)
def ugettext(message):
"""
A legacy compatibility wrapper for Unicode handling on Python 2.
Alias of gettext() since Django 2.0.
"""
warnings.warn(
'django.utils.translation.ugettext() is deprecated in favor of '
'django.utils.translation.gettext().',
RemovedInDjango40Warning, stacklevel=2,
)
return gettext(message)
def ngettext(singular, plural, number):
return _trans.ngettext(singular, plural, number)
def ungettext(singular, plural, number):
"""
A legacy compatibility wrapper for Unicode handling on Python 2.
Alias of ngettext() since Django 2.0.
"""
warnings.warn(
'django.utils.translation.ungettext() is deprecated in favor of '
'django.utils.translation.ngettext().',
RemovedInDjango40Warning, stacklevel=2,
)
return ngettext(singular, plural, number)
def pgettext(context, message):
return _trans.pgettext(context, message)
@@ -111,35 +136,46 @@ gettext_lazy = lazy(gettext, str)
pgettext_lazy = lazy(pgettext, str)
def ugettext_lazy(message):
"""
A legacy compatibility wrapper for Unicode handling on Python 2. Has been
Alias of gettext_lazy since Django 2.0.
"""
warnings.warn(
'django.utils.translation.ugettext_lazy() is deprecated in favor of '
'django.utils.translation.gettext_lazy().',
RemovedInDjango40Warning, stacklevel=2,
)
return gettext_lazy(message)
def lazy_number(func, resultclass, number=None, **kwargs):
if isinstance(number, int):
kwargs["number"] = number
kwargs['number'] = number
proxy = lazy(func, resultclass)(**kwargs)
else:
original_kwargs = kwargs.copy()
class NumberAwareString(resultclass):
def __bool__(self):
return bool(kwargs["singular"])
return bool(kwargs['singular'])
def _get_number_value(self, values):
try:
return values[number]
except KeyError:
raise KeyError(
"Your dictionary lacks key '%s'. Please provide "
"Your dictionary lacks key '%s\'. Please provide "
"it, because it is required to determine whether "
"string is singular or plural." % number
)
def _translate(self, number_value):
kwargs["number"] = number_value
kwargs['number'] = number_value
return func(**kwargs)
def format(self, *args, **kwargs):
number_value = (
self._get_number_value(kwargs) if kwargs and number else args[0]
)
number_value = self._get_number_value(kwargs) if kwargs and number else args[0]
return self._translate(number_value).format(*args, **kwargs)
def __mod__(self, rhs):
@@ -156,10 +192,7 @@ def lazy_number(func, resultclass, number=None, **kwargs):
return translated
proxy = lazy(lambda **kwargs: NumberAwareString(), NumberAwareString)(**kwargs)
proxy.__reduce__ = lambda: (
_lazy_number_unpickle,
(func, resultclass, number, original_kwargs),
)
proxy.__reduce__ = lambda: (_lazy_number_unpickle, (func, resultclass, number, original_kwargs))
return proxy
@@ -171,10 +204,21 @@ def ngettext_lazy(singular, plural, number=None):
return lazy_number(ngettext, str, singular=singular, plural=plural, number=number)
def npgettext_lazy(context, singular, plural, number=None):
return lazy_number(
npgettext, str, context=context, singular=singular, plural=plural, number=number
def ungettext_lazy(singular, plural, number=None):
"""
A legacy compatibility wrapper for Unicode handling on Python 2.
An alias of ungettext_lazy() since Django 2.0.
"""
warnings.warn(
'django.utils.translation.ungettext_lazy() is deprecated in favor of '
'django.utils.translation.ngettext_lazy().',
RemovedInDjango40Warning, stacklevel=2,
)
return ngettext_lazy(singular, plural, number)
def npgettext_lazy(context, singular, plural, number=None):
return lazy_number(npgettext, str, context=context, singular=singular, plural=plural, number=number)
def activate(language):
@@ -220,27 +264,27 @@ def check_for_language(lang_code):
def to_language(locale):
"""Turn a locale name (en_US) into a language name (en-us)."""
p = locale.find("_")
p = locale.find('_')
if p >= 0:
return locale[:p].lower() + "-" + locale[p + 1 :].lower()
return locale[:p].lower() + '-' + locale[p + 1:].lower()
else:
return locale.lower()
def to_locale(language):
"""Turn a language name (en-us) into a locale name (en_US)."""
lang, _, country = language.lower().partition("-")
language, _, country = language.lower().partition('-')
if not country:
return language[:3].lower() + language[3:]
return language
# A language with > 2 characters after the dash only has its first
# character after the dash capitalized; e.g. sr-latn becomes sr_Latn.
# A language with 2 characters after the dash has both characters
# capitalized; e.g. en-us becomes en_US.
country, _, tail = country.partition("-")
country, _, tail = country.partition('-')
country = country.title() if len(country) > 2 else country.upper()
if tail:
country += "-" + tail
return lang + "_" + country
country += '-' + tail
return language + '_' + country
def get_language_from_request(request, check_path=False):
@@ -257,7 +301,6 @@ def get_supported_language_variant(lang_code, *, strict=False):
def templatize(src, **kwargs):
from .template import templatize
return templatize(src, **kwargs)
@@ -267,35 +310,32 @@ def deactivate_all():
def get_language_info(lang_code):
from django.conf.locale import LANG_INFO
try:
lang_info = LANG_INFO[lang_code]
if "fallback" in lang_info and "name" not in lang_info:
info = get_language_info(lang_info["fallback"][0])
if 'fallback' in lang_info and 'name' not in lang_info:
info = get_language_info(lang_info['fallback'][0])
else:
info = lang_info
except KeyError:
if "-" not in lang_code:
if '-' not in lang_code:
raise KeyError("Unknown language code %s." % lang_code)
generic_lang_code = lang_code.split("-")[0]
generic_lang_code = lang_code.split('-')[0]
try:
info = LANG_INFO[generic_lang_code]
except KeyError:
raise KeyError(
"Unknown language code %s and %s." % (lang_code, generic_lang_code)
)
raise KeyError("Unknown language code %s and %s." % (lang_code, generic_lang_code))
if info:
info["name_translated"] = gettext_lazy(info["name"])
info['name_translated'] = gettext_lazy(info['name'])
return info
trim_whitespace_re = _lazy_re_compile(r"\s*\n\s*")
trim_whitespace_re = _lazy_re_compile(r'\s*\n\s*')
def trim_whitespace(s):
return trim_whitespace_re.sub(" ", s.strip())
return trim_whitespace_re.sub(' ', s.strip())
def round_away_from_one(value):
return int(Decimal(value - 1).quantize(Decimal("0"), rounding=ROUND_UP)) + 1
return int(Decimal(value - 1).quantize(Decimal('0'), rounding=ROUND_UP)) + 1
@@ -11,24 +11,23 @@ def watch_for_translation_changes(sender, **kwargs):
from django.conf import settings
if settings.USE_I18N:
directories = [Path("locale")]
directories = [Path('locale')]
directories.extend(
Path(config.path) / "locale"
Path(config.path) / 'locale'
for config in apps.get_app_configs()
if not is_django_module(config.module)
)
directories.extend(Path(p) for p in settings.LOCALE_PATHS)
for path in directories:
sender.watch_dir(path, "**/*.mo")
sender.watch_dir(path, '**/*.mo')
def translation_file_changed(sender, file_path, **kwargs):
"""Clear the internal translations cache if a .mo file is modified."""
if file_path.suffix == ".mo":
if file_path.suffix == '.mo':
import gettext
from django.utils.translation import trans_real
gettext._translations = {}
trans_real._translations = {}
trans_real._default = None
@@ -1,14 +1,12 @@
import warnings
from io import StringIO
from django.template.base import Lexer, TokenType
from django.template.base import TRANSLATOR_COMMENT_MARK, Lexer, TokenType
from django.utils.regex_helper import _lazy_re_compile
from . import TranslatorCommentWarning, trim_whitespace
TRANSLATOR_COMMENT_MARK = "Translators"
dot_re = _lazy_re_compile(r"\S")
dot_re = _lazy_re_compile(r'\S')
def blankout(src, char):
@@ -28,9 +26,7 @@ inline_re = _lazy_re_compile(
# Match the optional context part
r"""(\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?')))?\s*"""
)
block_re = _lazy_re_compile(
r"""^\s*blocktrans(?:late)?(\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?')))?(?:\s+|$)"""
)
block_re = _lazy_re_compile(r"""^\s*blocktrans(?:late)?(\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?')))?(?:\s+|$)""")
endblock_re = _lazy_re_compile(r"""^\s*endblocktrans(?:late)?$""")
plural_re = _lazy_re_compile(r"""^\s*plural$""")
constant_re = _lazy_re_compile(r"""_\(((?:".*?")|(?:'.*?'))\)""")
@@ -42,7 +38,7 @@ def templatize(src, origin=None):
does so by translating the Django translation tags into standard gettext
function invocations.
"""
out = StringIO("")
out = StringIO('')
message_context = None
intrans = False
inplural = False
@@ -54,30 +50,27 @@ def templatize(src, origin=None):
lineno_comment_map = {}
comment_lineno_cache = None
# Adding the u prefix allows gettext to recognize the string (#26093).
raw_prefix = "u"
raw_prefix = 'u'
def join_tokens(tokens, trim=False):
message = "".join(tokens)
message = ''.join(tokens)
if trim:
message = trim_whitespace(message)
return message
for t in Lexer(src).tokenize():
if incomment:
if t.token_type == TokenType.BLOCK and t.contents == "endcomment":
content = "".join(comment)
if t.token_type == TokenType.BLOCK and t.contents == 'endcomment':
content = ''.join(comment)
translators_comment_start = None
for lineno, line in enumerate(content.splitlines(True)):
if line.lstrip().startswith(TRANSLATOR_COMMENT_MARK):
translators_comment_start = lineno
for lineno, line in enumerate(content.splitlines(True)):
if (
translators_comment_start is not None
and lineno >= translators_comment_start
):
out.write(" # %s" % line)
if translators_comment_start is not None and lineno >= translators_comment_start:
out.write(' # %s' % line)
else:
out.write(" #\n")
out.write(' #\n')
incomment = False
comment = []
else:
@@ -89,44 +82,36 @@ def templatize(src, origin=None):
if endbmatch:
if inplural:
if message_context:
out.write(
" npgettext({p}{!r}, {p}{!r}, {p}{!r},count) ".format(
message_context,
join_tokens(singular, trimmed),
join_tokens(plural, trimmed),
p=raw_prefix,
)
)
out.write(' npgettext({p}{!r}, {p}{!r}, {p}{!r},count) '.format(
message_context,
join_tokens(singular, trimmed),
join_tokens(plural, trimmed),
p=raw_prefix,
))
else:
out.write(
" ngettext({p}{!r}, {p}{!r}, count) ".format(
join_tokens(singular, trimmed),
join_tokens(plural, trimmed),
p=raw_prefix,
)
)
out.write(' ngettext({p}{!r}, {p}{!r}, count) '.format(
join_tokens(singular, trimmed),
join_tokens(plural, trimmed),
p=raw_prefix,
))
for part in singular:
out.write(blankout(part, "S"))
out.write(blankout(part, 'S'))
for part in plural:
out.write(blankout(part, "P"))
out.write(blankout(part, 'P'))
else:
if message_context:
out.write(
" pgettext({p}{!r}, {p}{!r}) ".format(
message_context,
join_tokens(singular, trimmed),
p=raw_prefix,
)
)
out.write(' pgettext({p}{!r}, {p}{!r}) '.format(
message_context,
join_tokens(singular, trimmed),
p=raw_prefix,
))
else:
out.write(
" gettext({p}{!r}) ".format(
join_tokens(singular, trimmed),
p=raw_prefix,
)
)
out.write(' gettext({p}{!r}) '.format(
join_tokens(singular, trimmed),
p=raw_prefix,
))
for part in singular:
out.write(blankout(part, "S"))
out.write(blankout(part, 'S'))
message_context = None
intrans = False
inplural = False
@@ -135,20 +120,20 @@ def templatize(src, origin=None):
elif pluralmatch:
inplural = True
else:
filemsg = ""
filemsg = ''
if origin:
filemsg = "file %s, " % origin
filemsg = 'file %s, ' % origin
raise SyntaxError(
"Translation blocks must not include other block tags: "
"%s (%sline %d)" % (t.contents, filemsg, t.lineno)
)
elif t.token_type == TokenType.VAR:
if inplural:
plural.append("%%(%s)s" % t.contents)
plural.append('%%(%s)s' % t.contents)
else:
singular.append("%%(%s)s" % t.contents)
singular.append('%%(%s)s' % t.contents)
elif t.token_type == TokenType.TEXT:
contents = t.contents.replace("%", "%%")
contents = t.contents.replace('%', '%%')
if inplural:
plural.append(contents)
else:
@@ -157,13 +142,13 @@ def templatize(src, origin=None):
# Handle comment tokens (`{# ... #}`) plus other constructs on
# the same line:
if comment_lineno_cache is not None:
cur_lineno = t.lineno + t.contents.count("\n")
cur_lineno = t.lineno + t.contents.count('\n')
if comment_lineno_cache == cur_lineno:
if t.token_type != TokenType.COMMENT:
for c in lineno_comment_map[comment_lineno_cache]:
filemsg = ""
filemsg = ''
if origin:
filemsg = "file %s, " % origin
filemsg = 'file %s, ' % origin
warn_msg = (
"The translator-targeted comment '%s' "
"(%sline %d) was ignored, because it wasn't "
@@ -172,9 +157,7 @@ def templatize(src, origin=None):
warnings.warn(warn_msg, TranslatorCommentWarning)
lineno_comment_map[comment_lineno_cache] = []
else:
out.write(
"# %s" % " | ".join(lineno_comment_map[comment_lineno_cache])
)
out.write('# %s' % ' | '.join(lineno_comment_map[comment_lineno_cache]))
comment_lineno_cache = None
if t.token_type == TokenType.BLOCK:
@@ -187,7 +170,7 @@ def templatize(src, origin=None):
g = g.strip('"')
elif g[0] == "'":
g = g.strip("'")
g = g.replace("%", "%%")
g = g.replace('%', '%%')
if imatch[2]:
# A context is provided
context_match = context_re.match(imatch[2])
@@ -196,17 +179,15 @@ def templatize(src, origin=None):
message_context = message_context.strip('"')
elif message_context[0] == "'":
message_context = message_context.strip("'")
out.write(
" pgettext({p}{!r}, {p}{!r}) ".format(
message_context, g, p=raw_prefix
)
)
out.write(' pgettext({p}{!r}, {p}{!r}) '.format(
message_context, g, p=raw_prefix
))
message_context = None
else:
out.write(" gettext({p}{!r}) ".format(g, p=raw_prefix))
out.write(' gettext({p}{!r}) '.format(g, p=raw_prefix))
elif bmatch:
for fmatch in constant_re.findall(t.contents):
out.write(" _(%s) " % fmatch)
out.write(' _(%s) ' % fmatch)
if bmatch[1]:
# A context is provided
context_match = context_re.match(bmatch[1])
@@ -217,30 +198,30 @@ def templatize(src, origin=None):
message_context = message_context.strip("'")
intrans = True
inplural = False
trimmed = "trimmed" in t.split_contents()
trimmed = 'trimmed' in t.split_contents()
singular = []
plural = []
elif cmatches:
for cmatch in cmatches:
out.write(" _(%s) " % cmatch)
elif t.contents == "comment":
out.write(' _(%s) ' % cmatch)
elif t.contents == 'comment':
incomment = True
else:
out.write(blankout(t.contents, "B"))
out.write(blankout(t.contents, 'B'))
elif t.token_type == TokenType.VAR:
parts = t.contents.split("|")
parts = t.contents.split('|')
cmatch = constant_re.match(parts[0])
if cmatch:
out.write(" _(%s) " % cmatch[1])
out.write(' _(%s) ' % cmatch[1])
for p in parts[1:]:
if p.find(":_(") >= 0:
out.write(" %s " % p.split(":", 1)[1])
if p.find(':_(') >= 0:
out.write(' %s ' % p.split(':', 1)[1])
else:
out.write(blankout(p, "F"))
out.write(blankout(p, 'F'))
elif t.token_type == TokenType.COMMENT:
if t.contents.lstrip().startswith(TRANSLATOR_COMMENT_MARK):
lineno_comment_map.setdefault(t.lineno, []).append(t.contents)
comment_lineno_cache = t.lineno
else:
out.write(blankout(t.contents, "X"))
out.write(blankout(t.contents, 'X'))
return out.getvalue()
@@ -32,23 +32,18 @@ CONTEXT_SEPARATOR = "\x04"
# Format of Accept-Language header values. From RFC 2616, section 14.4 and 3.9
# and RFC 3066, section 2.1
accept_language_re = _lazy_re_compile(
r"""
# "en", "en-au", "x-y-z", "es-419", "*"
([A-Za-z]{1,8}(?:-[A-Za-z0-9]{1,8})*|\*)
# Optional "q=1.00", "q=0.8"
(?:\s*;\s*q=(0(?:\.\d{,3})?|1(?:\.0{,3})?))?
# Multiple accepts per header.
(?:\s*,\s*|$)
""",
re.VERBOSE,
)
accept_language_re = _lazy_re_compile(r'''
([A-Za-z]{1,8}(?:-[A-Za-z0-9]{1,8})*|\*) # "en", "en-au", "x-y-z", "es-419", "*"
(?:\s*;\s*q=(0(?:\.\d{,3})?|1(?:\.0{,3})?))? # Optional "q=1.00", "q=0.8"
(?:\s*,\s*|$) # Multiple accepts per header.
''', re.VERBOSE)
language_code_re = _lazy_re_compile(
r"^[a-z]{1,8}(?:-[a-z0-9]{1,8})*(?:@[a-z0-9]{1,20})?$", re.IGNORECASE
r'^[a-z]{1,8}(?:-[a-z0-9]{1,8})*(?:@[a-z0-9]{1,20})?$',
re.IGNORECASE
)
language_code_prefix_re = _lazy_re_compile(r"^/(\w+([@-]\w+)?)(/|$)")
language_code_prefix_re = _lazy_re_compile(r'^/(\w+([@-]\w+)?)(/|$)')
@receiver(setting_changed)
@@ -57,7 +52,7 @@ def reset_cache(**kwargs):
Reset global state when LANGUAGES setting has been changed, as some
languages should no longer be accepted.
"""
if kwargs["setting"] in ("LANGUAGES", "LANGUAGE_CODE"):
if kwargs['setting'] in ('LANGUAGES', 'LANGUAGE_CODE'):
check_for_language.cache_clear()
get_languages.cache_clear()
get_supported_language_variant.cache_clear()
@@ -68,7 +63,6 @@ class TranslationCatalog:
Simulate a dict for DjangoTranslation._catalog so as multiple catalogs
with different plural equations are kept separate.
"""
def __init__(self, trans=None):
self._catalogs = [trans._catalog.copy()] if trans else [{}]
self._plurals = [trans.plural] if trans else [lambda n: int(n != 1)]
@@ -130,8 +124,7 @@ class DjangoTranslation(gettext_module.GNUTranslations):
requested language and add a fallback to the default language, if it's
different from the requested language.
"""
domain = "django"
domain = 'django'
def __init__(self, language, domain=None, localedirs=None):
"""Create a GNUTranslations() using many locale directories"""
@@ -147,12 +140,10 @@ class DjangoTranslation(gettext_module.GNUTranslations):
# pluralization: anything except one is pluralized.
self.plural = lambda n: int(n != 1)
if self.domain == "django":
if self.domain == 'django':
if localedirs is not None:
# A module-level cache is used for caching 'django' translations
warnings.warn(
"localedirs is ignored when domain is 'django'.", RuntimeWarning
)
warnings.warn("localedirs is ignored when domain is 'django'.", RuntimeWarning)
localedirs = None
self._init_translation_catalog()
@@ -164,16 +155,9 @@ class DjangoTranslation(gettext_module.GNUTranslations):
self._add_installed_apps_translations()
self._add_local_translations()
if (
self.__language == settings.LANGUAGE_CODE
and self.domain == "django"
and self._catalog is None
):
if self.__language == settings.LANGUAGE_CODE and self.domain == 'django' and self._catalog is None:
# default lang should have at least one translation file available.
raise OSError(
"No translation files found for default language %s."
% settings.LANGUAGE_CODE
)
raise OSError('No translation files found for default language %s.' % settings.LANGUAGE_CODE)
self._add_fallback(localedirs)
if self._catalog is None:
# No catalogs found for this language, set an empty catalog.
@@ -200,7 +184,7 @@ class DjangoTranslation(gettext_module.GNUTranslations):
def _init_translation_catalog(self):
"""Create a base catalog using global django translations."""
settingsfile = sys.modules[settings.__module__].__file__
localedir = os.path.join(os.path.dirname(settingsfile), "locale")
localedir = os.path.join(os.path.dirname(settingsfile), 'locale')
translation = self._new_gnu_trans(localedir)
self.merge(translation)
@@ -212,10 +196,9 @@ class DjangoTranslation(gettext_module.GNUTranslations):
raise AppRegistryNotReady(
"The translation infrastructure cannot be initialized before the "
"apps registry is ready. Check that you don't make non-lazy "
"gettext calls at import time."
)
"gettext calls at import time.")
for app_config in app_configs:
localedir = os.path.join(app_config.path, "locale")
localedir = os.path.join(app_config.path, 'locale')
if os.path.exists(localedir):
translation = self._new_gnu_trans(localedir)
self.merge(translation)
@@ -230,11 +213,9 @@ class DjangoTranslation(gettext_module.GNUTranslations):
"""Set the GNUTranslations() fallback with the default language."""
# Don't set a fallback for the default language or any English variant
# (as it's empty, so it'll ALWAYS fall back to the default language)
if self.__language == settings.LANGUAGE_CODE or self.__language.startswith(
"en"
):
if self.__language == settings.LANGUAGE_CODE or self.__language.startswith('en'):
return
if self.domain == "django":
if self.domain == 'django':
# Get from cache
default_translation = translation(settings.LANGUAGE_CODE)
else:
@@ -245,7 +226,7 @@ class DjangoTranslation(gettext_module.GNUTranslations):
def merge(self, other):
"""Merge another translation into this catalog."""
if not getattr(other, "_catalog", None):
if not getattr(other, '_catalog', None):
return # NullTranslations() has no _catalog
if self._catalog is None:
# Take plural and _info from first catalog found (generally Django's).
@@ -340,7 +321,7 @@ def get_language_bidi():
if lang is None:
return False
else:
base_lang = get_language().split("-")[0]
base_lang = get_language().split('-')[0]
return base_lang in settings.LANGUAGES_BIDI
@@ -368,7 +349,7 @@ def gettext(message):
"""
global _default
eol_message = message.replace("\r\n", "\n").replace("\r", "\n")
eol_message = message.replace('\r\n', '\n').replace('\r', '\n')
if eol_message:
_default = _default or translation(settings.LANGUAGE_CODE)
@@ -378,7 +359,7 @@ def gettext(message):
else:
# Return an empty value of the corresponding type if an empty message
# is given, instead of metadata, which is the default gettext behavior.
result = type(message)("")
result = type(message)('')
if isinstance(message, SafeData):
return mark_safe(result)
@@ -423,15 +404,13 @@ def ngettext(singular, plural, number):
Return a string of the translation of either the singular or plural,
based on the number.
"""
return do_ntranslate(singular, plural, number, "ngettext")
return do_ntranslate(singular, plural, number, 'ngettext')
def npgettext(context, singular, plural, number):
msgs_with_ctxt = (
"%s%s%s" % (context, CONTEXT_SEPARATOR, singular),
"%s%s%s" % (context, CONTEXT_SEPARATOR, plural),
number,
)
msgs_with_ctxt = ("%s%s%s" % (context, CONTEXT_SEPARATOR, singular),
"%s%s%s" % (context, CONTEXT_SEPARATOR, plural),
number)
result = ngettext(*msgs_with_ctxt)
if CONTEXT_SEPARATOR in result:
# Translation not found
@@ -444,11 +423,10 @@ def all_locale_paths():
Return a list of paths to user-provides languages files.
"""
globalpath = os.path.join(
os.path.dirname(sys.modules[settings.__module__].__file__), "locale"
)
os.path.dirname(sys.modules[settings.__module__].__file__), 'locale')
app_paths = []
for app_config in apps.get_app_configs():
locale_path = os.path.join(app_config.path, "locale")
locale_path = os.path.join(app_config.path, 'locale')
if os.path.exists(locale_path):
app_paths.append(locale_path)
return [globalpath, *settings.LOCALE_PATHS, *app_paths]
@@ -469,7 +447,7 @@ def check_for_language(lang_code):
if lang_code is None or not language_code_re.search(lang_code):
return False
return any(
gettext_module.find("django", path, [to_locale(lang_code)]) is not None
gettext_module.find('django', path, [to_locale(lang_code)]) is not None
for path in all_locale_paths()
)
@@ -496,17 +474,14 @@ def get_supported_language_variant(lang_code, strict=False):
<https://www.djangoproject.com/weblog/2007/oct/26/security-fix/>.
"""
if lang_code:
# If 'zh-hant-tw' is not supported, try special fallback or subsequent
# language codes i.e. 'zh-hant' and 'zh'.
# If 'fr-ca' is not supported, try special fallback or language-only 'fr'.
possible_lang_codes = [lang_code]
try:
possible_lang_codes.extend(LANG_INFO[lang_code]["fallback"])
possible_lang_codes.extend(LANG_INFO[lang_code]['fallback'])
except KeyError:
pass
i = None
while (i := lang_code.rfind("-", 0, i)) > -1:
possible_lang_codes.append(lang_code[:i])
generic_lang_code = possible_lang_codes[-1]
generic_lang_code = lang_code.split('-')[0]
possible_lang_codes.append(generic_lang_code)
supported_lang_codes = get_languages()
for code in possible_lang_codes:
@@ -515,7 +490,7 @@ def get_supported_language_variant(lang_code, strict=False):
if not strict:
# if fr-fr is not supported, try fr-ca.
for supported_code in supported_lang_codes:
if supported_code.startswith(generic_lang_code + "-"):
if supported_code.startswith(generic_lang_code + '-'):
return supported_code
raise LookupError(lang_code)
@@ -553,11 +528,7 @@ def get_language_from_request(request, check_path=False):
return lang_code
lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME)
if (
lang_code is not None
and lang_code in get_languages()
and check_for_language(lang_code)
):
if lang_code is not None and lang_code in get_languages() and check_for_language(lang_code):
return lang_code
try:
@@ -565,9 +536,9 @@ def get_language_from_request(request, check_path=False):
except LookupError:
pass
accept = request.META.get("HTTP_ACCEPT_LANGUAGE", "")
accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
for accept_lang, unused in parse_accept_lang_header(accept):
if accept_lang == "*":
if accept_lang == '*':
break
if not language_code_re.search(accept_lang):
@@ -597,7 +568,7 @@ def parse_accept_lang_header(lang_string):
if pieces[-1]:
return ()
for i in range(0, len(pieces) - 1, 3):
first, lang, priority = pieces[i : i + 3]
first, lang, priority = pieces[i:i + 3]
if first:
return ()
if priority: