----- Original Message -----
From: "Vratislav Podzimek" vpodzime@redhat.com To: anaconda-patches@lists.fedorahosted.org Sent: Thursday, October 9, 2014 5:41:37 AM Subject: [PATCH 1/2 v3] A function for resolving date format and order
It's not that easy to get right order of date fields (year, month, day) and their formats so we should better have it in a standalone function with tests.
Related: rhbz#1044233 Signed-off-by: Vratislav Podzimek vpodzime@redhat.com
pyanaconda/localization.py | 87 +++++++++++++++++++++++++++++ tests/pyanaconda_tests/localization_test.py | 17 ++++++ 2 files changed, 104 insertions(+)
diff --git a/pyanaconda/localization.py b/pyanaconda/localization.py index c95fa1d..2a2ed96 100644 --- a/pyanaconda/localization.py +++ b/pyanaconda/localization.py @@ -26,6 +26,7 @@ import re import langtable import locale as locale_mod import glob +from collections import namedtuple
from pyanaconda import constants from pyanaconda.iutil import upcase_first_letter @@ -469,3 +470,89 @@ def load_firmware_language(lang):
log.debug("Using UEFI PlatformLang '%s' ('%s') as our language.", d, locales[0]) setup_locale(locales[0], lang)
+_DateFieldSpec = namedtuple("DateFieldSpec", ["format", "suffix"])
+def resolve_date_format(year, month, day, fail_safe=True):
- """
- Puts the year, month and day objects in the right order according to the
- currently set locale and provides format specification for each of the
- fields.
- :param year: any object or value representing year
- :type year: object
- :param month: any object or value representing month
- :type month: object
- :param day: any object or value representing day
- :type day: object
- :param bool fail_safe: whether to fall back to default in case of
invalid
format or raise exception instead
- :returns: a pair where the first field contains a tuple with the year,
month
and day objects/values put in the right order and where the
second
field contains a tuple with three :class:`_DateFieldSpec`
objects
specifying formats respectively to the first (year, month,
day)
field
- :rtype: tuple
- :raise ValueError: in case currently set locale has unsupported date
format and fail_safe is set to False
- """
- fail_safe_default = "%Y-%m-%d"
This looks like a should-be-capitalized constant.
- def order_terms_formats(fmt_str):
# see date (1), 'O' (not '0') is a mystery, 'E' is Buddhist
calendar, '(.*)'
# is an arbitrary suffix
field_spec_re = re.compile(r'([-_0OE^#]*)([yYmbBde])(.*)')
ordered_terms = []
ordered_formats = []
Please move these down to above the for loop that is their first use.
# see date (1)
fmt_str = fmt_str.replace("%F", "%Y-%m-%d")
# e.g. "%d.%m.%Y" -> ['d.', 'm.', 'Y']
fields = fmt_str.split("%")[1:]
for field in fields:
match = field_spec_re.match(field)
if not match:
# ignore fields we are not interested in (like %A for
weekday name, etc.)
continue
prefix, item, suffix = match.groups()
if item in ("d", "e"):
# "e" is the same as "_d"
ordered_terms.append(day)
elif item in ("Y", "y"):
# 4-digit year, 2-digit year
ordered_terms.append(year)
elif item in ("m", "b", "B"):
# month number, short month name, long month name
ordered_terms.append(month)
# "%" + prefix + item gives a format for date/time formatting
functions
ordered_formats.append(_DateFieldSpec("%" + prefix + item,
suffix.strip()))
if len(ordered_terms) != 3 or len(ordered_formats) != 3:
raise ValueError("Not all fields successfully identified in the
format '%s'" % fmt_str)
return (tuple(ordered_terms), tuple(ordered_formats))
- fmt_str = locale_mod.nl_langinfo(locale_mod.D_FMT)
- if not fmt_str or "%" not in fmt_str:
if fail_safe:
# use some sane default
fmt_str = fail_safe_default
else:
raise ValueError("Invalid date format string for current locale:
'%s'" % fmt_str)
- try:
return order_terms_formats(fmt_str)
- except ValueError:
if not fail_safe:
raise
else:
# if this call fails too, something is going terribly wrong and
we
# should be informed about it
return order_terms_formats(fail_safe_default)
diff --git a/tests/pyanaconda_tests/localization_test.py b/tests/pyanaconda_tests/localization_test.py index 00ff31d..521fb4a 100644 --- a/tests/pyanaconda_tests/localization_test.py +++ b/tests/pyanaconda_tests/localization_test.py @@ -19,6 +19,8 @@ #
from pyanaconda import localization +from pyanaconda.iutil import execReadlines +import locale as locale_mod import unittest
class ParsingTests(unittest.TestCase): @@ -139,3 +141,18 @@ class LangcodeLocaleMatchingTests(unittest.TestCase): # no matches self.assertIsNone(localization.find_best_locale_match("pt_BR", ["en_BR", "en"])) self.assertIsNone(localization.find_best_locale_match("cs_CZ.UTF-8", ["en", "en.UTF-8"]))
- def resolve_date_format_test(self):
"""All locales' date formats should be properly resolved."""
locales = (line.strip() for line in execReadlines("locale", ["-a"]))
for locale in locales:
try:
locale_mod.setlocale(locale_mod.LC_ALL, locale)
except locale_mod.Error:
# cannot set locale (a bug in the locale module?)
continue
(order, formats) = localization.resolve_date_format(1, 2, 3,
fail_safe=False)
for i in (1, 2, 3):
self.assertIn(i, order)
-- 1.9.3
anaconda-patches mailing list anaconda-patches@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/anaconda-patches
Other than inline comments above, ack.
- mulhern