From 3e6d9a70e11041ad6737630281098866462ed1e3 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Thu, 1 Oct 2020 15:54:08 +0300 Subject: [PATCH 1/5] Switch downloader to CLDR 37 --- scripts/download_import_cldr.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/download_import_cldr.py b/scripts/download_import_cldr.py index 434b04f80..531a04c62 100755 --- a/scripts/download_import_cldr.py +++ b/scripts/download_import_cldr.py @@ -13,9 +13,9 @@ from urllib import urlretrieve -URL = 'http://unicode.org/Public/cldr/36/core.zip' -FILENAME = 'cldr-core-36.zip' -FILESUM = '07279e56c1f4266d140b907ef3ec379dce0a99542303a9628562ac5fe460ba43' +URL = 'http://unicode.org/Public/cldr/37/core.zip' +FILENAME = 'cldr-core-37.zip' +FILESUM = 'ba93f5ba256a61a6f8253397c6c4b1a9b9e77531f013cc7ffa7977b5f7e4da57' BLKSIZE = 131072 From 462444f35756551f83809dab7f7424a907033a9e Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Thu, 1 Oct 2020 16:27:02 +0300 Subject: [PATCH 2/5] Adapt things to new compound pattern format --- babel/units.py | 9 ++++++--- scripts/import_cldr.py | 20 +++++++++++++++++--- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/babel/units.py b/babel/units.py index 89c491365..07637358c 100644 --- a/babel/units.py +++ b/babel/units.py @@ -75,8 +75,10 @@ def format_unit(value, measurement_unit, length='long', format=None, locale=LC_N u'12 metri' >>> format_unit(15.5, 'length-mile', locale='fi_FI') u'15,5 mailia' - >>> format_unit(1200, 'pressure-inch-hg', locale='nb') - u'1\\xa0200 tommer kvikks\\xf8lv' + >>> format_unit(1200, 'pressure-millimeter-ofhg', locale='nb') + u'1\\xa0200 millimeter kvikks\\xf8lv' + >>> format_unit(270, 'ton', locale='en') + u'270 tons' Number formats may be overridden with the ``format`` parameter. @@ -271,6 +273,7 @@ def format_compound_unit( else: # Bare denominator formatted_denominator = format_decimal(denominator_value, format=format, locale=locale) - per_pattern = locale._data["compound_unit_patterns"].get("per", {}).get(length, "{0}/{1}") + # TODO: this doesn't support "compound_variations" (or "prefix"), and will fall back to the "x/y" representation + per_pattern = locale._data["compound_unit_patterns"].get("per", {}).get(length, {}).get("compound", "{0}/{1}") return per_pattern.format(formatted_numerator, formatted_denominator) diff --git a/scripts/import_cldr.py b/scripts/import_cldr.py index 7ea6481a2..aab2888e1 100755 --- a/scripts/import_cldr.py +++ b/scripts/import_cldr.py @@ -853,9 +853,23 @@ def parse_unit_patterns(data, tree): for unit in elem.findall('compoundUnit'): unit_type = unit.attrib['type'] - compound_patterns.setdefault(unit_type, {})[unit_length_type] = ( - _text(unit.find('compoundUnitPattern')) - ) + compound_unit_info = {} + compound_variations = {} + for child in unit.getchildren(): + if child.tag == "unitPrefixPattern": + compound_unit_info['prefix'] = _text(child) + elif child.tag == "compoundUnitPattern": + compound_variations[None] = _text(child) + elif child.tag == "compoundUnitPattern1": + compound_variations[child.attrib.get('count')] = _text(child) + if compound_variations: + compound_variation_values = set(compound_variations.values()) + if len(compound_variation_values) == 1: + # shortcut: if all compound variations are the same, only store one + compound_unit_info['compound'] = next(iter(compound_variation_values)) + else: + compound_unit_info['compound_variations'] = compound_variations + compound_patterns.setdefault(unit_type, {})[unit_length_type] = compound_unit_info def parse_date_fields(data, tree): From 31abefa1009ee8f176a7fcd9311935ea806bc1a0 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Fri, 2 Oct 2020 10:56:37 +0300 Subject: [PATCH 3/5] Correct default timedelta format to 'long' Augments 9327e0824a1bbed538e73d42b971988f8214b490 --- babel/support.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/babel/support.py b/babel/support.py index 47f812d8a..8d905ed64 100644 --- a/babel/support.py +++ b/babel/support.py @@ -79,7 +79,7 @@ def time(self, time=None, format='medium'): return format_time(time, format, tzinfo=self.tzinfo, locale=self.locale) def timedelta(self, delta, granularity='second', threshold=.85, - format='medium', add_direction=False): + format='long', add_direction=False): """Return a time delta according to the rules of the given locale. >>> from datetime import timedelta From acf1caeed35c180ce7c14f822a23ab297931feab Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Fri, 2 Oct 2020 10:56:59 +0300 Subject: [PATCH 4/5] Skip deprecated l*gettext functions on Python 3.8+ --- tests/test_support.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/test_support.py b/tests/test_support.py index 1b74ae8bc..966cb4e62 100644 --- a/tests/test_support.py +++ b/tests/test_support.py @@ -17,6 +17,7 @@ import tempfile import unittest import pytest +import sys from datetime import date, datetime, timedelta from babel import support @@ -26,6 +27,7 @@ get_arg_spec = (inspect.getargspec if PY2 else inspect.getfullargspec) +SKIP_LGETTEXT = sys.version_info >= (3, 8) @pytest.mark.usefixtures("os_environ") class TranslationsTestCase(unittest.TestCase): @@ -76,6 +78,7 @@ def test_upgettext(self): self.assertEqualTypeToo(u'VohCTX', self.translations.upgettext('foo', 'foo')) + @pytest.mark.skipif(SKIP_LGETTEXT, reason="lgettext is deprecated") def test_lpgettext(self): self.assertEqualTypeToo(b'Voh', self.translations.lgettext('foo')) self.assertEqualTypeToo(b'VohCTX', self.translations.lpgettext('foo', @@ -105,6 +108,7 @@ def test_unpgettext(self): self.translations.unpgettext('foo', 'foo1', 'foos1', 2)) + @pytest.mark.skipif(SKIP_LGETTEXT, reason="lgettext is deprecated") def test_lnpgettext(self): self.assertEqualTypeToo(b'Voh1', self.translations.lngettext('foo1', 'foos1', 1)) @@ -129,6 +133,7 @@ def test_dupgettext(self): self.assertEqualTypeToo( u'VohCTXD', self.translations.dupgettext('messages1', 'foo', 'foo')) + @pytest.mark.skipif(SKIP_LGETTEXT, reason="lgettext is deprecated") def test_ldpgettext(self): self.assertEqualTypeToo( b'VohD', self.translations.ldgettext('messages1', 'foo')) @@ -159,6 +164,7 @@ def test_dunpgettext(self): u'VohsCTXD1', self.translations.dunpgettext('messages1', 'foo', 'foo1', 'foos1', 2)) + @pytest.mark.skipif(SKIP_LGETTEXT, reason="lgettext is deprecated") def test_ldnpgettext(self): self.assertEqualTypeToo( b'VohD1', self.translations.ldngettext('messages1', 'foo1', 'foos1', 1)) @@ -197,7 +203,11 @@ def setUp(self): self.null_translations = support.NullTranslations(fp=fp) def method_names(self): - return [name for name in dir(self.translations) if 'gettext' in name] + names = [name for name in dir(self.translations) if 'gettext' in name] + if SKIP_LGETTEXT: + # Remove deprecated l*gettext functions + names = [name for name in names if not name.startswith('l')] + return names def test_same_methods(self): for name in self.method_names(): From 2b615f7ea7d3c1383e26d1cea402f43895750843 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Fri, 2 Oct 2020 12:29:48 +0300 Subject: [PATCH 5/5] Ignore lack of coverage on lines that e.g. raise warnings --- .coveragerc | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .coveragerc diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 000000000..a3d8ae65e --- /dev/null +++ b/.coveragerc @@ -0,0 +1,5 @@ +[report] +exclude_lines = + NotImplemented + pragma: no cover + warnings.warn \ No newline at end of file