From: benselme Date: Fri, 9 Jan 2015 19:56:31 +0000 (-0500) Subject: Fixed import and format_timedelta to handle new time unit patterns in cldr-24. X-Git-Tag: dev-2a51c9b95d06~51^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9327e0824a1bbed538e73d42b971988f8214b490;p=thirdparty%2Fbabel.git Fixed import and format_timedelta to handle new time unit patterns in cldr-24. Fixed tests to account for various minor changes in cldr-24. --- diff --git a/babel/dates.py b/babel/dates.py index 73d54fa5..bb215d1e 100644 --- a/babel/dates.py +++ b/babel/dates.py @@ -19,6 +19,7 @@ from __future__ import division import re +import warnings import pytz as _pytz from datetime import date, datetime, time, timedelta @@ -705,7 +706,7 @@ TIMEDELTA_UNITS = ( def format_timedelta(delta, granularity='second', threshold=.85, - add_direction=False, format='medium', + add_direction=False, format='long', locale=LC_TIME): """Return a time delta according to the rules of the given locale. @@ -750,25 +751,34 @@ def format_timedelta(delta, granularity='second', threshold=.85, positive timedelta will include the information about it being in the future, a negative will be information about the value being in the past. - :param format: the format (currently only "medium" and "short" are supported) + :param format: the format (currently only "long" and "short" are supported, + "medium" is deprecated, currently converted to "long" to + maintain compatibility) :param locale: a `Locale` object or a locale identifier """ - if format not in ('short', 'medium'): + if format not in ('short', 'medium', 'long'): raise TypeError('Format can only be one of "short" or "medium"') + if format == 'medium': + warnings.warn('"medium" value for format param of format_timedelta' + ' is deprecated. Use "long" instead', + category=DeprecationWarning) + format = 'long' if isinstance(delta, timedelta): seconds = int((delta.days * 86400) + delta.seconds) else: seconds = delta locale = Locale.parse(locale) - def _iter_choices(unit): + def _iter_patterns(a_unit): if add_direction: + unit_rel_patterns = locale._data['date_fields'][a_unit] if seconds >= 0: - yield unit + '-future' + yield unit_rel_patterns['future'] else: - yield unit + '-past' - yield unit + ':' + format - yield unit + yield unit_rel_patterns['past'] + a_unit = 'duration-' + a_unit + yield locale._data['unit_patterns'].get(a_unit + ':' + format) + yield locale._data['unit_patterns'].get(a_unit) for unit, secs_per_unit in TIMEDELTA_UNITS: value = abs(seconds) / secs_per_unit @@ -778,8 +788,7 @@ def format_timedelta(delta, granularity='second', threshold=.85, value = int(round(value)) plural_form = locale.plural_form(value) pattern = None - for choice in _iter_choices(unit): - patterns = locale._data['unit_patterns'].get(choice) + for patterns in _iter_patterns(unit): if patterns is not None: pattern = patterns[plural_form] break diff --git a/scripts/import_cldr.py b/scripts/import_cldr.py index 082393ce..63780412 100755 --- a/scripts/import_cldr.py +++ b/scripts/import_cldr.py @@ -609,14 +609,25 @@ def main(): # unit_patterns = data.setdefault('unit_patterns', {}) - for elem in tree.findall('.//units/unit'): - unit_type = elem.attrib['type'] - for pattern in elem.findall('unitPattern'): - box = unit_type - if 'alt' in pattern.attrib: - box += ':' + pattern.attrib['alt'] - unit_patterns.setdefault(box, {})[pattern.attrib['count']] = \ - text_type(pattern.text) + for elem in tree.findall('.//units/unitLength'): + unit_length_type = elem.attrib['type'] + for unit in elem.findall('unit'): + unit_type = unit.attrib['type'] + for pattern in unit.findall('unitPattern'): + box = unit_type + box += ':' + unit_length_type + unit_patterns.setdefault(box, {})[pattern.attrib['count']] = \ + text_type(pattern.text) + + date_fields = data.setdefault('date_fields', {}) + for elem in tree.findall('.//dates/fields/field'): + field_type = elem.attrib['type'] + date_fields.setdefault(field_type, {}) + for rel_time in elem.findall('relativeTime'): + rel_time_type = rel_time.attrib['type'] + for pattern in rel_time.findall('relativeTimePattern'): + date_fields[field_type].setdefault(rel_time_type, {})\ + [pattern.attrib['count']] = text_type(pattern.text) outfile = open(data_filename, 'wb') try: diff --git a/tests/test_core.py b/tests/test_core.py index ac2611dc..7e16765f 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -220,7 +220,7 @@ class TestLocaleClass: def test_datetime_formats_property(self): assert Locale('en').datetime_formats['full'] == u"{1} 'at' {0}" - assert Locale('th').datetime_formats['medium'] == u'{1}, {0}' + assert Locale('th').datetime_formats['medium'] == u'{1} {0}' def test_plural_form_property(self): assert Locale('en').plural_form(1) == 'one' diff --git a/tests/test_dates.py b/tests/test_dates.py index 7b897a13..b18bf507 100644 --- a/tests/test_dates.py +++ b/tests/test_dates.py @@ -191,25 +191,25 @@ class DateTimeFormatTestCase(unittest.TestCase): tz = timezone('Europe/Paris') dt = datetime(2007, 4, 1, 15, 30, tzinfo=tz) fmt = dates.DateTimeFormat(dt, locale='fr_FR') - self.assertEqual('Heure : France', fmt['v']) + self.assertEqual('heure : France', fmt['v']) def test_timezone_location_format(self): tz = timezone('Europe/Paris') dt = datetime(2007, 4, 1, 15, 30, tzinfo=tz) fmt = dates.DateTimeFormat(dt, locale='fr_FR') - self.assertEqual('Heure : France', fmt['VVVV']) + self.assertEqual('heure : France', fmt['VVVV']) def test_timezone_walltime_short(self): tz = timezone('Europe/Paris') t = time(15, 30, tzinfo=tz) fmt = dates.DateTimeFormat(t, locale='fr_FR') - self.assertEqual('Heure : France', fmt['v']) + self.assertEqual('heure : France', fmt['v']) def test_timezone_walltime_long(self): tz = timezone('Europe/Paris') t = time(15, 30, tzinfo=tz) fmt = dates.DateTimeFormat(t, locale='fr_FR') - self.assertEqual(u'heure de l\u2019Europe centrale', fmt['vvvv']) + self.assertEqual(u'heure d\u2019Europe centrale', fmt['vvvv']) def test_hour_formatting(self): l = 'en_US' @@ -265,7 +265,6 @@ class FormatTimeTestCase(unittest.TestCase): formatted_time = dates.format_time(epoch, format='long', locale='en_US') self.assertEqual(u'3:30:29 PM +0000', formatted_time) - def test_with_date_fields_in_pattern(self): self.assertRaises(AttributeError, dates.format_time, date(2007, 4, 1), "yyyy-MM-dd HH:mm", locale='en_US') @@ -305,7 +304,7 @@ class FormatTimedeltaTestCase(unittest.TestCase): string = dates.format_timedelta(timedelta(hours=1), locale='en', add_direction=True) - self.assertEqual('In 1 hour', string) + self.assertEqual('in 1 hour', string) string = dates.format_timedelta(timedelta(hours=-1), locale='en', add_direction=True) @@ -336,14 +335,14 @@ def test_get_period_names(): def test_get_day_names(): assert dates.get_day_names('wide', locale='en_US')[1] == u'Tuesday' - assert dates.get_day_names('abbreviated', locale='es')[1] == u'mar' + assert dates.get_day_names('abbreviated', locale='es')[1] == u'mar.' de = dates.get_day_names('narrow', context='stand-alone', locale='de_DE') assert de[1] == u'D' def test_get_month_names(): assert dates.get_month_names('wide', locale='en_US')[1] == u'January' - assert dates.get_month_names('abbreviated', locale='es')[1] == u'ene' + assert dates.get_month_names('abbreviated', locale='es')[1] == u'ene.' de = dates.get_month_names('narrow', context='stand-alone', locale='de_DE') assert de[1] == u'J' @@ -477,7 +476,7 @@ def test_format_time(): t = time(15, 30) paris = dates.format_time(t, format='full', tzinfo=timezone('Europe/Paris'), locale='fr_FR') - assert paris == u'15:30:00 heure normale de l\u2019Europe centrale' + assert paris == u'15:30:00 heure normale d\u2019Europe centrale' us_east = dates.format_time(t, format='full', tzinfo=timezone('US/Eastern'), locale='en_US') assert us_east == u'3:30:00 PM Eastern Standard Time'