测试gitnore
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
import datetime
|
||||
import decimal
|
||||
import functools
|
||||
import re
|
||||
import unicodedata
|
||||
from importlib import import_module
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils import dateformat, numberformat
|
||||
from django.utils import dateformat, datetime_safe, numberformat
|
||||
from django.utils.functional import lazy
|
||||
from django.utils.translation import check_for_language, get_language, to_locale
|
||||
from django.utils.translation import (
|
||||
check_for_language, get_language, to_locale,
|
||||
)
|
||||
|
||||
# format_cache is a mapping from (format_type, lang) to the format string.
|
||||
# By using the cache, it is possible to avoid running get_format_modules
|
||||
@@ -17,35 +17,33 @@ _format_cache = {}
|
||||
_format_modules_cache = {}
|
||||
|
||||
ISO_INPUT_FORMATS = {
|
||||
"DATE_INPUT_FORMATS": ["%Y-%m-%d"],
|
||||
"TIME_INPUT_FORMATS": ["%H:%M:%S", "%H:%M:%S.%f", "%H:%M"],
|
||||
"DATETIME_INPUT_FORMATS": [
|
||||
"%Y-%m-%d %H:%M:%S",
|
||||
"%Y-%m-%d %H:%M:%S.%f",
|
||||
"%Y-%m-%d %H:%M",
|
||||
"%Y-%m-%d",
|
||||
'DATE_INPUT_FORMATS': ['%Y-%m-%d'],
|
||||
'TIME_INPUT_FORMATS': ['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'],
|
||||
'DATETIME_INPUT_FORMATS': [
|
||||
'%Y-%m-%d %H:%M:%S',
|
||||
'%Y-%m-%d %H:%M:%S.%f',
|
||||
'%Y-%m-%d %H:%M',
|
||||
'%Y-%m-%d'
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
FORMAT_SETTINGS = frozenset(
|
||||
[
|
||||
"DECIMAL_SEPARATOR",
|
||||
"THOUSAND_SEPARATOR",
|
||||
"NUMBER_GROUPING",
|
||||
"FIRST_DAY_OF_WEEK",
|
||||
"MONTH_DAY_FORMAT",
|
||||
"TIME_FORMAT",
|
||||
"DATE_FORMAT",
|
||||
"DATETIME_FORMAT",
|
||||
"SHORT_DATE_FORMAT",
|
||||
"SHORT_DATETIME_FORMAT",
|
||||
"YEAR_MONTH_FORMAT",
|
||||
"DATE_INPUT_FORMATS",
|
||||
"TIME_INPUT_FORMATS",
|
||||
"DATETIME_INPUT_FORMATS",
|
||||
]
|
||||
)
|
||||
FORMAT_SETTINGS = frozenset([
|
||||
'DECIMAL_SEPARATOR',
|
||||
'THOUSAND_SEPARATOR',
|
||||
'NUMBER_GROUPING',
|
||||
'FIRST_DAY_OF_WEEK',
|
||||
'MONTH_DAY_FORMAT',
|
||||
'TIME_FORMAT',
|
||||
'DATE_FORMAT',
|
||||
'DATETIME_FORMAT',
|
||||
'SHORT_DATE_FORMAT',
|
||||
'SHORT_DATETIME_FORMAT',
|
||||
'YEAR_MONTH_FORMAT',
|
||||
'DATE_INPUT_FORMATS',
|
||||
'TIME_INPUT_FORMATS',
|
||||
'DATETIME_INPUT_FORMATS',
|
||||
])
|
||||
|
||||
|
||||
def reset_format_cache():
|
||||
@@ -72,29 +70,30 @@ def iter_format_modules(lang, format_module_path=None):
|
||||
if isinstance(format_module_path, str):
|
||||
format_module_path = [format_module_path]
|
||||
for path in format_module_path:
|
||||
format_locations.append(path + ".%s")
|
||||
format_locations.append("django.conf.locale.%s")
|
||||
format_locations.append(path + '.%s')
|
||||
format_locations.append('django.conf.locale.%s')
|
||||
locale = to_locale(lang)
|
||||
locales = [locale]
|
||||
if "_" in locale:
|
||||
locales.append(locale.split("_")[0])
|
||||
if '_' in locale:
|
||||
locales.append(locale.split('_')[0])
|
||||
for location in format_locations:
|
||||
for loc in locales:
|
||||
try:
|
||||
yield import_module("%s.formats" % (location % loc))
|
||||
yield import_module('%s.formats' % (location % loc))
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
def get_format_modules(lang=None):
|
||||
def get_format_modules(lang=None, reverse=False):
|
||||
"""Return a list of the format modules found."""
|
||||
if lang is None:
|
||||
lang = get_language()
|
||||
if lang not in _format_modules_cache:
|
||||
_format_modules_cache[lang] = list(
|
||||
iter_format_modules(lang, settings.FORMAT_MODULE_PATH)
|
||||
)
|
||||
return _format_modules_cache[lang]
|
||||
_format_modules_cache[lang] = list(iter_format_modules(lang, settings.FORMAT_MODULE_PATH))
|
||||
modules = _format_modules_cache[lang]
|
||||
if reverse:
|
||||
return list(reversed(modules))
|
||||
return modules
|
||||
|
||||
|
||||
def get_format(format_type, lang=None, use_l10n=None):
|
||||
@@ -106,14 +105,7 @@ def get_format(format_type, lang=None, use_l10n=None):
|
||||
If use_l10n is provided and is not None, it forces the value to
|
||||
be localized (or not), overriding the value of settings.USE_L10N.
|
||||
"""
|
||||
use_l10n = use_l10n or (
|
||||
use_l10n is None
|
||||
and (
|
||||
settings._USE_L10N_INTERNAL
|
||||
if hasattr(settings, "_USE_L10N_INTERNAL")
|
||||
else settings.USE_L10N
|
||||
)
|
||||
)
|
||||
use_l10n = use_l10n or (use_l10n is None and settings.USE_L10N)
|
||||
if use_l10n and lang is None:
|
||||
lang = get_language()
|
||||
cache_key = (format_type, lang)
|
||||
@@ -157,9 +149,7 @@ def date_format(value, format=None, use_l10n=None):
|
||||
If use_l10n is provided and is not None, that will force the value to
|
||||
be localized (or not), overriding the value of settings.USE_L10N.
|
||||
"""
|
||||
return dateformat.format(
|
||||
value, get_format(format or "DATE_FORMAT", use_l10n=use_l10n)
|
||||
)
|
||||
return dateformat.format(value, get_format(format or 'DATE_FORMAT', use_l10n=use_l10n))
|
||||
|
||||
|
||||
def time_format(value, format=None, use_l10n=None):
|
||||
@@ -169,9 +159,7 @@ def time_format(value, format=None, use_l10n=None):
|
||||
If use_l10n is provided and is not None, it forces the value to
|
||||
be localized (or not), overriding the value of settings.USE_L10N.
|
||||
"""
|
||||
return dateformat.time_format(
|
||||
value, get_format(format or "TIME_FORMAT", use_l10n=use_l10n)
|
||||
)
|
||||
return dateformat.time_format(value, get_format(format or 'TIME_FORMAT', use_l10n=use_l10n))
|
||||
|
||||
|
||||
def number_format(value, decimal_pos=None, use_l10n=None, force_grouping=False):
|
||||
@@ -181,21 +169,16 @@ def number_format(value, decimal_pos=None, use_l10n=None, force_grouping=False):
|
||||
If use_l10n is provided and is not None, it forces the value to
|
||||
be localized (or not), overriding the value of settings.USE_L10N.
|
||||
"""
|
||||
use_l10n = use_l10n or (
|
||||
use_l10n is None
|
||||
and (
|
||||
settings._USE_L10N_INTERNAL
|
||||
if hasattr(settings, "_USE_L10N_INTERNAL")
|
||||
else settings.USE_L10N
|
||||
)
|
||||
)
|
||||
lang = get_language() if use_l10n else None
|
||||
if use_l10n or (use_l10n is None and settings.USE_L10N):
|
||||
lang = get_language()
|
||||
else:
|
||||
lang = None
|
||||
return numberformat.format(
|
||||
value,
|
||||
get_format("DECIMAL_SEPARATOR", lang, use_l10n=use_l10n),
|
||||
get_format('DECIMAL_SEPARATOR', lang, use_l10n=use_l10n),
|
||||
decimal_pos,
|
||||
get_format("NUMBER_GROUPING", lang, use_l10n=use_l10n),
|
||||
get_format("THOUSAND_SEPARATOR", lang, use_l10n=use_l10n),
|
||||
get_format('NUMBER_GROUPING', lang, use_l10n=use_l10n),
|
||||
get_format('THOUSAND_SEPARATOR', lang, use_l10n=use_l10n),
|
||||
force_grouping=force_grouping,
|
||||
use_l10n=use_l10n,
|
||||
)
|
||||
@@ -218,11 +201,11 @@ def localize(value, use_l10n=None):
|
||||
return str(value)
|
||||
return number_format(value, use_l10n=use_l10n)
|
||||
elif isinstance(value, datetime.datetime):
|
||||
return date_format(value, "DATETIME_FORMAT", use_l10n=use_l10n)
|
||||
return date_format(value, 'DATETIME_FORMAT', use_l10n=use_l10n)
|
||||
elif isinstance(value, datetime.date):
|
||||
return date_format(value, use_l10n=use_l10n)
|
||||
elif isinstance(value, datetime.time):
|
||||
return time_format(value, "TIME_FORMAT", use_l10n=use_l10n)
|
||||
return time_format(value, 'TIME_FORMAT', use_l10n=use_l10n)
|
||||
return value
|
||||
|
||||
|
||||
@@ -238,52 +221,19 @@ def localize_input(value, default=None):
|
||||
elif isinstance(value, (decimal.Decimal, float, int)):
|
||||
return number_format(value)
|
||||
elif isinstance(value, datetime.datetime):
|
||||
format = default or get_format("DATETIME_INPUT_FORMATS")[0]
|
||||
format = sanitize_strftime_format(format)
|
||||
value = datetime_safe.new_datetime(value)
|
||||
format = default or get_format('DATETIME_INPUT_FORMATS')[0]
|
||||
return value.strftime(format)
|
||||
elif isinstance(value, datetime.date):
|
||||
format = default or get_format("DATE_INPUT_FORMATS")[0]
|
||||
format = sanitize_strftime_format(format)
|
||||
value = datetime_safe.new_date(value)
|
||||
format = default or get_format('DATE_INPUT_FORMATS')[0]
|
||||
return value.strftime(format)
|
||||
elif isinstance(value, datetime.time):
|
||||
format = default or get_format("TIME_INPUT_FORMATS")[0]
|
||||
format = default or get_format('TIME_INPUT_FORMATS')[0]
|
||||
return value.strftime(format)
|
||||
return value
|
||||
|
||||
|
||||
@functools.lru_cache()
|
||||
def sanitize_strftime_format(fmt):
|
||||
"""
|
||||
Ensure that certain specifiers are correctly padded with leading zeros.
|
||||
|
||||
For years < 1000 specifiers %C, %F, %G, and %Y don't work as expected for
|
||||
strftime provided by glibc on Linux as they don't pad the year or century
|
||||
with leading zeros. Support for specifying the padding explicitly is
|
||||
available, however, which can be used to fix this issue.
|
||||
|
||||
FreeBSD, macOS, and Windows do not support explicitly specifying the
|
||||
padding, but return four digit years (with leading zeros) as expected.
|
||||
|
||||
This function checks whether the %Y produces a correctly padded string and,
|
||||
if not, makes the following substitutions:
|
||||
|
||||
- %C → %02C
|
||||
- %F → %010F
|
||||
- %G → %04G
|
||||
- %Y → %04Y
|
||||
|
||||
See https://bugs.python.org/issue13305 for more details.
|
||||
"""
|
||||
if datetime.date(1, 1, 1).strftime("%Y") == "0001":
|
||||
return fmt
|
||||
mapping = {"C": 2, "F": 10, "G": 4, "Y": 4}
|
||||
return re.sub(
|
||||
r"((?:^|[^%])(?:%%)*)%([CFGY])",
|
||||
lambda m: r"%s%%0%s%s" % (m[1], mapping[m[2]], m[2]),
|
||||
fmt,
|
||||
)
|
||||
|
||||
|
||||
def sanitize_separators(value):
|
||||
"""
|
||||
Sanitize a value according to the current decimal and
|
||||
@@ -291,26 +241,19 @@ def sanitize_separators(value):
|
||||
"""
|
||||
if isinstance(value, str):
|
||||
parts = []
|
||||
decimal_separator = get_format("DECIMAL_SEPARATOR")
|
||||
decimal_separator = get_format('DECIMAL_SEPARATOR')
|
||||
if decimal_separator in value:
|
||||
value, decimals = value.split(decimal_separator, 1)
|
||||
parts.append(decimals)
|
||||
if settings.USE_THOUSAND_SEPARATOR:
|
||||
thousand_sep = get_format("THOUSAND_SEPARATOR")
|
||||
if (
|
||||
thousand_sep == "."
|
||||
and value.count(".") == 1
|
||||
and len(value.split(".")[-1]) != 3
|
||||
):
|
||||
# Special case where we suspect a dot meant decimal separator
|
||||
# (see #22171).
|
||||
thousand_sep = get_format('THOUSAND_SEPARATOR')
|
||||
if thousand_sep == '.' and value.count('.') == 1 and len(value.split('.')[-1]) != 3:
|
||||
# Special case where we suspect a dot meant decimal separator (see #22171)
|
||||
pass
|
||||
else:
|
||||
for replacement in {
|
||||
thousand_sep,
|
||||
unicodedata.normalize("NFKD", thousand_sep),
|
||||
}:
|
||||
value = value.replace(replacement, "")
|
||||
thousand_sep, unicodedata.normalize('NFKD', thousand_sep)}:
|
||||
value = value.replace(replacement, '')
|
||||
parts.append(value)
|
||||
value = ".".join(reversed(parts))
|
||||
value = '.'.join(reversed(parts))
|
||||
return value
|
||||
|
||||
Reference in New Issue
Block a user