From ca2f29cba122b3f6d64ea13669eb6210f0e457b5 Mon Sep 17 00:00:00 2001 From: Hyunjun Kim Date: Fri, 16 Aug 2013 20:08:23 +0900 Subject: Fixed typos on cli errors. --- babel/messages/frontend.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/babel/messages/frontend.py b/babel/messages/frontend.py index 144bc98..3d496f3 100755 --- a/babel/messages/frontend.py +++ b/babel/messages/frontend.py @@ -89,7 +89,7 @@ class compile_catalog(Command): raise DistutilsOptionError('you must specify either the input file ' 'or the base directory') if not self.output_file and not self.directory: - raise DistutilsOptionError('you must specify either the input file ' + raise DistutilsOptionError('you must specify either the output file ' 'or the base directory') def run(self): @@ -750,7 +750,7 @@ class CommandLineInterface(object): mo_files.append(options.output_file) else: if not options.directory: - parser.error('you must specify either the input file or ' + parser.error('you must specify either the output file or ' 'the base directory') mo_files.append(os.path.join(options.directory, options.locale, 'LC_MESSAGES', -- cgit v1.2.1 From e5a4738b5ad6b6497383c562dc102a08631d532f Mon Sep 17 00:00:00 2001 From: Hyunjun Kim Date: Fri, 16 Aug 2013 20:40:31 +0900 Subject: Fixed a typo on description for setuptools command option. --- babel/messages/frontend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/babel/messages/frontend.py b/babel/messages/frontend.py index 3d496f3..f26e985 100755 --- a/babel/messages/frontend.py +++ b/babel/messages/frontend.py @@ -65,7 +65,7 @@ class compile_catalog(Command): 'name of the input file'), ('output-file=', 'o', "name of the output file (default " - "'//LC_MESSAGES/.po')"), + "'//LC_MESSAGES/.mo')"), ('locale=', 'l', 'locale of the catalog to compile'), ('use-fuzzy', 'f', -- cgit v1.2.1 From d764b35bc3910b8f67ff811752df615afa7667f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Neuha=CC=88user?= Date: Thu, 22 Aug 2013 19:40:55 +0200 Subject: Fix tox configuration Re-using the pickled data across 2.x and 3.x causes errors when running the tests. --- tox.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 52d8df9..6d4eb03 100644 --- a/tox.ini +++ b/tox.ini @@ -4,4 +4,5 @@ envlist = py26, py27, pypy, py33 [testenv] deps = pytest -commands = py.test tests +whitelist_externals = make +commands = make clean-cldr test -- cgit v1.2.1 From 6c220383993f0612923387ed171b21449711c75f Mon Sep 17 00:00:00 2001 From: "Alexander A. Dyshev" Date: Fri, 23 Aug 2013 17:06:21 +0300 Subject: Python3 Without 'b' option, using python3 everybody will get during update: bash-3.2$ pybabel update -i messages.pot -d translations updating catalog 'translations/en/LC_MESSAGES/messages.po' based on 'messages.pot' Traceback (most recent call last): File "/home/user/.pyenv/versions/3.3.2/bin/pybabel", line 9, in load_entry_point('Babel==1.3', 'console_scripts', 'pybabel')() File "/home/user/.pyenv/versions/3.3.2/lib/python3.3/site-packages/babel/messages/frontend.py", line 1151, in main return CommandLineInterface().run(sys.argv) File "/home/user/.pyenv/versions/3.3.2/lib/python3.3/site-packages/babel/messages/frontend.py", line 665, in run return getattr(self, cmdname)(args[1:]) File "/home/user/.pyenv/versions/3.3.2/lib/python3.3/site-packages/babel/messages/frontend.py", line 1130, in update width=options.width) File "/home/user/.pyenv/versions/3.3.2/lib/python3.3/site-packages/babel/messages/pofile.py", line 444, in write_po _write(comment_header + u'\n') File "/home/user/.pyenv/versions/3.3.2/lib/python3.3/site-packages/babel/messages/pofile.py", line 388, in _write fileobj.write(text) TypeError: must be str, not bytes --- babel/messages/frontend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/babel/messages/frontend.py b/babel/messages/frontend.py index 144bc98..86274e0 100755 --- a/babel/messages/frontend.py +++ b/babel/messages/frontend.py @@ -1121,7 +1121,7 @@ class CommandLineInterface(object): tmpname = os.path.join(os.path.dirname(filename), tempfile.gettempprefix() + os.path.basename(filename)) - tmpfile = open(tmpname, 'w') + tmpfile = open(tmpname, 'wb') try: try: write_po(tmpfile, catalog, -- cgit v1.2.1 From dffa7ec421f14f73b04d35258be6b0babcca8a0e Mon Sep 17 00:00:00 2001 From: Matt Iversen Date: Sat, 19 Oct 2013 22:27:38 +1100 Subject: Update classifiers to give more detailed information about babel's version compatibility --- setup.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.py b/setup.py index c7b39c3..b89a4ec 100755 --- a/setup.py +++ b/setup.py @@ -48,7 +48,10 @@ setup( 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', + 'Programming Language :: Python :: 2.6', + 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.3', 'Topic :: Software Development :: Libraries :: Python Modules', ], packages=['babel', 'babel.messages', 'babel.localtime'], -- cgit v1.2.1 From 3ec7bb104e808d1fda16fbf9fec4b9d7efccaa3f Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Wed, 6 Nov 2013 11:32:28 +0100 Subject: Correctly parse number pattern with '-' on the end For the nl_NL locale, negative numbers would be formatted just like positive numbers by format_currency. By changing NUMBER_TOKEN to no longer have a minus sign in it, the minus sign on the end of the negative pattern for nl_NL is correctly parsed. --- babel/numbers.py | 2 +- tests/test_numbers.py | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/babel/numbers.py b/babel/numbers.py index 2f7fe16..587d640 100644 --- a/babel/numbers.py +++ b/babel/numbers.py @@ -389,7 +389,7 @@ def parse_decimal(string, locale=LC_NUMERIC): PREFIX_END = r'[^0-9@#.,]' -NUMBER_TOKEN = r'[0-9@#.\-,E+]' +NUMBER_TOKEN = r'[0-9@#.,E+]' PREFIX_PATTERN = r"(?P(?:'[^']*'|%s)*)" % PREFIX_END NUMBER_PATTERN = r"(?P%s+)" % NUMBER_TOKEN diff --git a/tests/test_numbers.py b/tests/test_numbers.py index 99e0d1b..1c4d13f 100644 --- a/tests/test_numbers.py +++ b/tests/test_numbers.py @@ -213,6 +213,7 @@ def test_get_plus_sign_symbol(): def test_get_minus_sign_symbol(): assert numbers.get_minus_sign_symbol('en_US') == u'-' + assert numbers.get_minus_sign_symbol('nl_NL') == u'-' def test_get_exponential_symbol(): @@ -247,6 +248,8 @@ def test_format_currency(): assert (numbers.format_currency(1099.98, 'EUR', u'\xa4\xa4 #,##0.00', locale='en_US') == u'EUR 1,099.98') + assert (numbers.format_currency(1099.98, 'EUR', locale='nl_NL') + != numbers.format_currency(-1099.98, 'EUR', locale='nl_NL')) def test_format_percent(): @@ -298,3 +301,8 @@ def test_parse_grouping(): assert numbers.parse_grouping('##') == (1000, 1000) assert numbers.parse_grouping('#,###') == (3, 3) assert numbers.parse_grouping('#,####,###') == (3, 4) + + +def test_parse_pattern(): + assert numbers.parse_pattern(u'¤#,##0.00;(¤#,##0.00)').suffix == (u'', u')') + assert numbers.parse_pattern(u'¤ #,##0.00;¤ #,##0.00-').suffix == (u'', u'-') -- cgit v1.2.1 From f5960f3116c6a615f44133c66cf17ed561d063f8 Mon Sep 17 00:00:00 2001 From: masklinn Date: Tue, 26 Nov 2013 19:45:35 +0100 Subject: Add links from changelog entries to their ticket via extlink Supports links to the new github (``:gh:``) and the old trac (``:trac:``). The prefixes are used to keep the same reference style as pre-extlinks in the final output (aside from a few entries at the bottom of 1.0, trac references were all in the form ``ticket #42``). --- CHANGES | 158 +++++++++++++++++++++++++++++++---------------------------- docs/conf.py | 8 ++- 2 files changed, 89 insertions(+), 77 deletions(-) diff --git a/CHANGES b/CHANGES index 7ccd8c9..7f44c5f 100644 --- a/CHANGES +++ b/CHANGES @@ -30,7 +30,7 @@ Version 1.3 - Fixed a bug in likely-subtag resolving for some common locales. This primarily makes ``zh_CN`` work again which was broken due to how it was defined in the likely subtags combined with - our broken resolving. This fixes #37. + our broken resolving. This fixes :gh:`37`. - Fixed a bug that caused pybabel to break when writing to stdout on Python 3. - Removed a stray print that was causing issues when writing to @@ -65,8 +65,8 @@ Version 1.0 - use tox for testing on different pythons - Added support for the locale plural rules defined by the CLDR. - Added `format_timedelta` function to support localized formatting of - relative times with strings such as "2 days" or "1 month" (ticket #126). -- Fixed negative offset handling of Catalog._set_mime_headers (ticket #165). + relative times with strings such as "2 days" or "1 month" (:trac:`126`). +- Fixed negative offset handling of Catalog._set_mime_headers (:trac:`165`). - Fixed the case where messages containing square brackets would break with an unpack error. - updated to CLDR 23 @@ -74,52 +74,56 @@ Version 1.0 - Fix various typos. - Sort output of list-locales. - Make the POT-Creation-Date of the catalog being updated equal to - POT-Creation-Date of the template used to update (ticket #148). + POT-Creation-Date of the template used to update (:trac:`148`). - Use a more explicit error message if no option or argument (command) is - passed to pybabel (ticket #81). -- Keep the PO-Revision-Date if it is not the default value (ticket #148). + passed to pybabel (:trac:`81`). +- Keep the PO-Revision-Date if it is not the default value (:trac:`148`). - Make --no-wrap work by reworking --width's default and mimic xgettext's - behaviour of always wrapping comments (ticket #145). -- Add --project and --version options for commandline (ticket #173). + behaviour of always wrapping comments (:trac:`145`). +- Add --project and --version options for commandline (:trac:`173`). - Add a __ne__() method to the Local class. - Explicitly sort instead of using sorted() and don't assume ordering (Jython compatibility). - Removed ValueError raising for string formatting message checkers if the - string does not contain any string formattings (ticket #150). -- Fix Serbian plural forms (ticket #213). -- Small speed improvement in format_date() (ticket #216). + string does not contain any string formattings (:trac:`150`). +- Fix Serbian plural forms (:trac:`213`). +- Small speed improvement in format_date() (:trac:`216`). - Fix so frontend.CommandLineInterface.run does not accumulate logging - handlers (#227, reported with initial patch by dfraser) -- Fix exception if environment contains an invalid locale setting (#200) -- use cPickle instead of pickle for better performance (#225) + handlers (:trac:`227`, reported with initial patch by dfraser) +- Fix exception if environment contains an invalid locale setting + (:trac:`200`) +- use cPickle instead of pickle for better performance (:trac:`225`) - Only use bankers round algorithm as a tie breaker if there are two nearest - numbers, round as usual if there is only one nearest number (#267, patch by - Martin) -- Allow disabling cache behaviour in LazyProxy (#208, initial patch from Pedro - Algarvio) -- Support for context-aware methods during message extraction (#229, patch - from David Rios) -- "init" and "update" commands support "--no-wrap" option (#289) + numbers, round as usual if there is only one nearest number (:trac:`267`, + patch by Martin) +- Allow disabling cache behaviour in LazyProxy (:trac:`208`, initial patch + from Pedro Algarvio) +- Support for context-aware methods during message extraction (:trac:`229`, + patch from David Rios) +- "init" and "update" commands support "--no-wrap" option (:trac:`289`) - fix formatting of fraction in format_decimal() if the input value is a float - with more than 7 significant digits (#183) -- fix format_date() with datetime parameter (#282, patch from Xavier Morel) -- fix format_decimal() with small Decimal values (#214, patch from George Lund) -- fix handling of messages containing '\\n' (#198) -- handle irregular multi-line msgstr (no "" as first line) gracefully (#171) -- parse_decimal() now returns Decimals not floats, API change (#178) -- no warnings when running setup.py without installed setuptools (#262) + with more than 7 significant digits (:trac:`183`) +- fix format_date() with datetime parameter (:trac:`282`, patch from Xavier + Morel) +- fix format_decimal() with small Decimal values (:trac:`214`, patch from + George Lund) +- fix handling of messages containing '\\n' (:trac:`198`) +- handle irregular multi-line msgstr (no "" as first line) gracefully + (:trac:`171`) +- parse_decimal() now returns Decimals not floats, API change (:trac:`178`) +- no warnings when running setup.py without installed setuptools (:trac:`262`) - modified Locale.__eq__ method so Locales are only equal if all of their attributes (language, territory, script, variant) are equal -- resort to hard-coded message extractors/checkers if pkg_resources is - installed but no egg-info was found (#230) -- format_time() and format_datetime() now accept also floats (#242) +- resort to hard-coded message extractors/checkers if pkg_resources is + installed but no egg-info was found (:trac:`230`) +- format_time() and format_datetime() now accept also floats (:trac:`242`) - add babel.support.NullTranslations class similar to gettext.NullTranslations - but with all of Babel's new gettext methods (#277) -- "init" and "update" commands support "--width" option (#284) -- fix 'input_dirs' option for setuptools integration (#232, initial patch by - Étienne Bersac) -- ensure .mo file header contains the same information as the source .po file - (#199) + but with all of Babel's new gettext methods (:trac:`277`) +- "init" and "update" commands support "--width" option (:trac:`284`) +- fix 'input_dirs' option for setuptools integration (:trac:`232`, initial + patch by Étienne Bersac) +- ensure .mo file header contains the same information as the source .po file + (:trac:`199`) - added support for get_language_name() on the locale objects. - added support for get_territory_name() on the locale objects. - added support for get_script_name() on the locale objects. @@ -143,31 +147,32 @@ Version 0.9.6 - Backport r493-494: documentation typo fixes. - Make the CLDR import script work with Python 2.7. - Fix various typos. -- Fixed Python 2.3 compatibility (ticket #146, #233). +- Fixed Python 2.3 compatibility (:trac:`146`, :trac:`233`). - Sort output of list-locales. - Make the POT-Creation-Date of the catalog being updated equal to - POT-Creation-Date of the template used to update (ticket #148). + POT-Creation-Date of the template used to update (:trac:`148`). - Use a more explicit error message if no option or argument (command) is - passed to pybabel (ticket #81). -- Keep the PO-Revision-Date if it is not the default value (ticket #148). + passed to pybabel (:trac:`81`). +- Keep the PO-Revision-Date if it is not the default value (:trac:`148`). - Make --no-wrap work by reworking --width's default and mimic xgettext's - behaviour of always wrapping comments (ticket #145). -- Fixed negative offset handling of Catalog._set_mime_headers (ticket #165). -- Add --project and --version options for commandline (ticket #173). + behaviour of always wrapping comments (:trac:`145`). +- Fixed negative offset handling of Catalog._set_mime_headers (:trac:`165`). +- Add --project and --version options for commandline (:trac:`173`). - Add a __ne__() method to the Local class. - Explicitly sort instead of using sorted() and don't assume ordering (Python 2.3 and Jython compatibility). - Removed ValueError raising for string formatting message checkers if the - string does not contain any string formattings (ticket #150). -- Fix Serbian plural forms (ticket #213). -- Small speed improvement in format_date() (ticket #216). + string does not contain any string formattings (:trac:`150`). +- Fix Serbian plural forms (:trac:`213`). +- Small speed improvement in format_date() (:trac:`216`). - Fix number formatting for locales where CLDR specifies alt or draft - items (ticket #217) -- Fix bad check in format_time (ticket #257, reported with patch and tests by + items (:trac:`217`) +- Fix bad check in format_time (:trac:`257`, reported with patch and tests by jomae) - Fix so frontend.CommandLineInterface.run does not accumulate logging - handlers (#227, reported with initial patch by dfraser) -- Fix exception if environment contains an invalid locale setting (#200) + handlers (:trac:`227`, reported with initial patch by dfraser) +- Fix exception if environment contains an invalid locale setting + (:trac:`200`) Version 0.9.5 @@ -179,7 +184,7 @@ Version 0.9.5 an unpack error. - Backport of r467: Fuzzy matching regarding plurals should *NOT* be checked against len(message.id) because this is always 2, instead, it's should be - checked against catalog.num_plurals (ticket #212). + checked against catalog.num_plurals (:trac:`212`). Version 0.9.4 @@ -191,17 +196,17 @@ Version 0.9.4 CLDR data are no longer imported, so the symbol code will be used instead. - Fixed quarter support in date formatting. - Fixed a serious memory leak that was introduces by the support for CLDR - aliases in 0.9.3 (ticket #128). + aliases in 0.9.3 (:trac:`128`). - Locale modifiers such as "@euro" are now stripped from locale identifiers - when parsing (ticket #136). + when parsing (:trac:`136`). - The system locales "C" and "POSIX" are now treated as aliases for "en_US_POSIX", for which the CLDR provides the appropriate data. Thanks to Manlio Perillo for the suggestion. -- Fixed JavaScript extraction for regular expression literals (ticket #138) +- Fixed JavaScript extraction for regular expression literals (:trac:`138`) and concatenated strings. - The `Translation` class in `babel.support` can now manage catalogs with different message domains, and exposes the family of `d*gettext` functions - (ticket #137). + (:trac:`137`). Version 0.9.3 @@ -211,11 +216,11 @@ Version 0.9.3 - Fixed invalid message extraction methods causing an UnboundLocalError. - Extraction method specification can now use a dot instead of the colon to - separate module and function name (ticket #105). + separate module and function name (:trac:`105`). - Fixed message catalog compilation for locales with more than two plural - forms (ticket #95). + forms (:trac:`95`). - Fixed compilation of message catalogs for locales with more than two plural - forms where the translations were empty (ticket #97). + forms where the translations were empty (:trac:`97`). - The stripping of the comment tags in comments is optional now and is done for each line in a comment. - Added a JavaScript message extractor. @@ -225,7 +230,7 @@ Version 0.9.3 correct plural forms for a locale as tuple. - Added support for alias definitions in the CLDR data files, meaning that the chance for items missing in certain locales should be greatly reduced - (ticket #68). + (:trac:`68`). Version 0.9.2 @@ -233,15 +238,15 @@ Version 0.9.2 (released on February 4th 2008) -- Fixed catalogs' charset values not being recognized (ticket #66). +- Fixed catalogs' charset values not being recognized (:trac:`66`). - Numerous improvements to the default plural forms. -- Fixed fuzzy matching when updating message catalogs (ticket #82). +- Fixed fuzzy matching when updating message catalogs (:trac:`82`). - Fixed bug in catalog updating, that in some cases pulled in translations from different catalogs based on the same template. - Location lines in PO files do no longer get wrapped at hyphens in file - names (ticket #79). + names (:trac:`79`). - Fixed division by zero error in catalog compilation on empty catalogs - (ticket #60). + (:trac:`60`). Version 0.9.1 @@ -254,7 +259,7 @@ Version 0.9.1 `ngettext`, or vice versa. - Fixed time formatting for 12 am and 12 pm. - Fixed output encoding of the `pybabel --list-locales` command. -- MO files are now written in binary mode on windows (ticket #61). +- MO files are now written in binary mode on windows (:trac:`61`). Version 0.9 @@ -264,23 +269,24 @@ Version 0.9 - The `new_catalog` distutils command has been renamed to `init_catalog` for consistency with the command-line frontend. -- Added compilation of message catalogs to MO files (ticket #21). -- Added updating of message catalogs from POT files (ticket #22). +- Added compilation of message catalogs to MO files (:trac:`21`). +- Added updating of message catalogs from POT files (:trac:`22`). - Support for significant digits in number formatting. - Apply proper "banker's rounding" in number formatting in a cross-platform manner. - The number formatting functions now also work with numbers represented by - Python `Decimal` objects (ticket #53). + Python `Decimal` objects (:trac:`53`). - Added extensible infrastructure for validating translation catalogs. - Fixed the extractor not filtering out messages that didn't validate against - the keyword's specification (ticket #39). + the keyword's specification (:trac:`39`). - Fixed the extractor raising an exception when encountering an empty string msgid. It now emits a warning to stderr. - Numerous Python message extractor fixes: it now handles nested function calls within a gettext function call correctly, uses the correct line number - for multi-line function calls, and other small fixes (tickets #38 and #39). + for multi-line function calls, and other small fixes (tickets :trac:`38` and + :trac:`39`). - Improved support for detecting Python string formatting fields in message - strings (ticket #57). + strings (:trac:`57`). - CLDR upgraded to the 1.5 release. - Improved timezone formatting. - Implemented scientific number formatting. @@ -302,21 +308,21 @@ Version 0.8.1 that way. - The character set specified in PO template files is now respected when creating new catalog files based on that template. This allows the use of - characters outside the ASCII range in POT files (ticket #17). + characters outside the ASCII range in POT files (:trac:`17`). - The default ordering of messages in generated POT files, which is based on the order those messages are found when walking the source tree, is no longer subject to differences between platforms; directory and file names are now always sorted alphabetically. - The Python message extractor now respects the special encoding comment to be - able to handle files containing non-ASCII characters (ticket #23). + able to handle files containing non-ASCII characters (:trac:`23`). - Added ``N_`` (gettext noop) to the extractor's default keywords. - Made locale string parsing more robust, and also take the script part into - account (ticket #27). + account (:trac:`27`). - Added a function to list all locales for which locale data is available. - Added a command-line option to the `pybabel` command which prints out all - available locales (ticket #24). + available locales (:trac:`24`). - The name of the command-line script has been changed from just `babel` to - `pybabel` to avoid a conflict with the OpenBabel project (ticket #34). + `pybabel` to avoid a conflict with the OpenBabel project (:trac:`34`). Version 0.8 diff --git a/docs/conf.py b/docs/conf.py index b1467c7..c84ebae 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -27,7 +27,8 @@ sys.path.append(os.path.abspath('_themes')) # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.autodoc', - 'sphinx.ext.intersphinx'] + 'sphinx.ext.intersphinx', + 'sphinx.ext.extlinks'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -254,3 +255,8 @@ texinfo_documents = [ intersphinx_mapping = { 'http://docs.python.org/2': None, } + +extlinks = { + 'gh': ('https://github.com/mitsuhiko/babel/issues/%s', '#'), + 'trac': ('http://babel.edgewall.org/ticket/%s', 'ticket #'), +} -- cgit v1.2.1 From 50f727ac2c741877235c592ce4e1f50bba08162c Mon Sep 17 00:00:00 2001 From: James Page Date: Fri, 6 Dec 2013 11:49:26 +0000 Subject: Fixup get_currency_name test This test failed in environments where no default locale can be determined; make the test deterministic and add additional test for plurality. Signed-off-by: James Page --- tests/test_numbers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_numbers.py b/tests/test_numbers.py index 99e0d1b..7faba6b 100644 --- a/tests/test_numbers.py +++ b/tests/test_numbers.py @@ -175,7 +175,8 @@ class NumberParsingTestCase(unittest.TestCase): def test_get_currency_name(): - assert numbers.get_currency_name('USD', 'en_US') == u'US dollars' + assert numbers.get_currency_name('USD', locale='en_US') == u'US Dollar' + assert numbers.get_currency_name('USD', count=2, locale='en_US') == u'US dollars' def test_get_currency_symbol(): -- cgit v1.2.1 From b004036f8b2624235af20ba601607efa8c3db3ca Mon Sep 17 00:00:00 2001 From: Alex Morega Date: Mon, 6 Jan 2014 21:19:47 +0200 Subject: use fallback plural if none is defined in CLDR fixes #69 --- babel/core.py | 4 +++- tests/test_plural.py | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/babel/core.py b/babel/core.py index 56dbf55..4ada466 100644 --- a/babel/core.py +++ b/babel/core.py @@ -13,12 +13,14 @@ import os from babel import localedata from babel._compat import pickle, string_types +from babel.plural import PluralRule __all__ = ['UnknownLocaleError', 'Locale', 'default_locale', 'negotiate_locale', 'parse_locale'] _global_data = None +_default_plural_rule = PluralRule({}) def _raise_no_data_error(): @@ -737,7 +739,7 @@ class Locale(object): >>> Locale('ru').plural_form(100) 'many' """ - return self._data['plural_form'] + return self._data.get('plural_form', _default_plural_rule) def default_locale(category=None, aliases=LOCALE_ALIASES): diff --git a/tests/test_plural.py b/tests/test_plural.py index 5fe67a5..7f31fd9 100644 --- a/tests/test_plural.py +++ b/tests/test_plural.py @@ -90,3 +90,11 @@ def test_plural_within_rules(): assert p(7) == 'few' assert p(8) == 'few' assert p(9) == 'few' + + +def test_locales_with_no_plural_rules_have_default(): + from babel import Locale + aa_plural = Locale.parse('aa').plural_form + assert aa_plural(1) == 'other' + assert aa_plural(2) == 'other' + assert aa_plural(15) == 'other' -- cgit v1.2.1 From e92bbba373e6d56383723f71dd8d531c4cdd2806 Mon Sep 17 00:00:00 2001 From: Alex Morega Date: Mon, 6 Jan 2014 21:41:25 +0200 Subject: extract _parse_datetime_header function --- babel/messages/catalog.py | 84 +++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 54 deletions(-) diff --git a/babel/messages/catalog.py b/babel/messages/catalog.py index 501763b..82c08c8 100644 --- a/babel/messages/catalog.py +++ b/babel/messages/catalog.py @@ -40,6 +40,34 @@ PYTHON_FORMAT = re.compile(r'''(?x) ''') +def _parse_datetime_header(value): + value, tzoffset, _ = re.split('([+-]\d{4})$', value, 1) + + tt = time.strptime(value, '%Y-%m-%d %H:%M') + ts = time.mktime(tt) + + # Separate the offset into a sign component, hours, and # minutes + plus_minus_s, rest = tzoffset[0], tzoffset[1:] + hours_offset_s, mins_offset_s = rest[:2], rest[2:] + + # Make them all integers + plus_minus = int(plus_minus_s + '1') + hours_offset = int(hours_offset_s) + mins_offset = int(mins_offset_s) + + # Calculate net offset + net_mins_offset = hours_offset * 60 + net_mins_offset += mins_offset + net_mins_offset *= plus_minus + + # Create an offset object + tzoffset = FixedOffsetTimezone(net_mins_offset) + + # Store the offset in a datetime object + dt = datetime.fromtimestamp(ts) + return dt.replace(tzinfo=tzoffset) + + class Message(object): """Representation of a single message in a catalog.""" @@ -379,63 +407,11 @@ class Catalog(object): self._num_plurals = int(params.get('nplurals', 2)) self._plural_expr = params.get('plural', '(n != 1)') elif name == 'pot-creation-date': - # FIXME: this should use dates.parse_datetime as soon as that - # is ready - value, tzoffset, _ = re.split('([+-]\d{4})$', value, 1) - - tt = time.strptime(value, '%Y-%m-%d %H:%M') - ts = time.mktime(tt) - - # Separate the offset into a sign component, hours, and minutes - plus_minus_s, rest = tzoffset[0], tzoffset[1:] - hours_offset_s, mins_offset_s = rest[:2], rest[2:] - - # Make them all integers - plus_minus = int(plus_minus_s + '1') - hours_offset = int(hours_offset_s) - mins_offset = int(mins_offset_s) - - # Calculate net offset - net_mins_offset = hours_offset * 60 - net_mins_offset += mins_offset - net_mins_offset *= plus_minus - - # Create an offset object - tzoffset = FixedOffsetTimezone(net_mins_offset) - - # Store the offset in a datetime object - dt = datetime.fromtimestamp(ts) - self.creation_date = dt.replace(tzinfo=tzoffset) + self.creation_date = _parse_datetime_header(value) elif name == 'po-revision-date': # Keep the value if it's not the default one if 'YEAR' not in value: - # FIXME: this should use dates.parse_datetime as soon as - # that is ready - value, tzoffset, _ = re.split('([+-]\d{4})$', value, 1) - tt = time.strptime(value, '%Y-%m-%d %H:%M') - ts = time.mktime(tt) - - # Separate the offset into a sign component, hours, and - # minutes - plus_minus_s, rest = tzoffset[0], tzoffset[1:] - hours_offset_s, mins_offset_s = rest[:2], rest[2:] - - # Make them all integers - plus_minus = int(plus_minus_s + '1') - hours_offset = int(hours_offset_s) - mins_offset = int(mins_offset_s) - - # Calculate net offset - net_mins_offset = hours_offset * 60 - net_mins_offset += mins_offset - net_mins_offset *= plus_minus - - # Create an offset object - tzoffset = FixedOffsetTimezone(net_mins_offset) - - # Store the offset in a datetime object - dt = datetime.fromtimestamp(ts) - self.revision_date = dt.replace(tzinfo=tzoffset) + self.revision_date = _parse_datetime_header(value) mime_headers = property(_get_mime_headers, _set_mime_headers, doc="""\ The MIME headers of the catalog, used for the special ``msgid ""`` entry. -- cgit v1.2.1 From 1df64dfe5d9e10f6725362d467278c5eb02e5162 Mon Sep 17 00:00:00 2001 From: Alex Morega Date: Mon, 6 Jan 2014 21:43:33 +0200 Subject: rewrite regexp parsing --- babel/messages/catalog.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/babel/messages/catalog.py b/babel/messages/catalog.py index 82c08c8..756d64c 100644 --- a/babel/messages/catalog.py +++ b/babel/messages/catalog.py @@ -41,12 +41,13 @@ PYTHON_FORMAT = re.compile(r'''(?x) def _parse_datetime_header(value): - value, tzoffset, _ = re.split('([+-]\d{4})$', value, 1) + match = re.match(r'^(?P.*)(?P[+-]\d{4})$', value) - tt = time.strptime(value, '%Y-%m-%d %H:%M') + tt = time.strptime(match.group('datetime'), '%Y-%m-%d %H:%M') ts = time.mktime(tt) # Separate the offset into a sign component, hours, and # minutes + tzoffset = match.group('tzoffset') plus_minus_s, rest = tzoffset[0], tzoffset[1:] hours_offset_s, mins_offset_s = rest[:2], rest[2:] -- cgit v1.2.1 From 88c564228d30a6cda6368cf2077341fea0c6c6d2 Mon Sep 17 00:00:00 2001 From: Alex Morega Date: Mon, 6 Jan 2014 21:55:27 +0200 Subject: parse datetime values with no timezone info fixes #56 --- babel/messages/catalog.py | 35 +++++++++++++++++++---------------- tests/messages/test_catalog.py | 14 ++++++++++++++ 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/babel/messages/catalog.py b/babel/messages/catalog.py index 756d64c..67c5425 100644 --- a/babel/messages/catalog.py +++ b/babel/messages/catalog.py @@ -41,32 +41,35 @@ PYTHON_FORMAT = re.compile(r'''(?x) def _parse_datetime_header(value): - match = re.match(r'^(?P.*)(?P[+-]\d{4})$', value) + match = re.match(r'^(?P.*?)(?P[+-]\d{4})?$', value) tt = time.strptime(match.group('datetime'), '%Y-%m-%d %H:%M') ts = time.mktime(tt) + dt = datetime.fromtimestamp(ts) # Separate the offset into a sign component, hours, and # minutes tzoffset = match.group('tzoffset') - plus_minus_s, rest = tzoffset[0], tzoffset[1:] - hours_offset_s, mins_offset_s = rest[:2], rest[2:] + if tzoffset is not None: + plus_minus_s, rest = tzoffset[0], tzoffset[1:] + hours_offset_s, mins_offset_s = rest[:2], rest[2:] - # Make them all integers - plus_minus = int(plus_minus_s + '1') - hours_offset = int(hours_offset_s) - mins_offset = int(mins_offset_s) + # Make them all integers + plus_minus = int(plus_minus_s + '1') + hours_offset = int(hours_offset_s) + mins_offset = int(mins_offset_s) - # Calculate net offset - net_mins_offset = hours_offset * 60 - net_mins_offset += mins_offset - net_mins_offset *= plus_minus + # Calculate net offset + net_mins_offset = hours_offset * 60 + net_mins_offset += mins_offset + net_mins_offset *= plus_minus - # Create an offset object - tzoffset = FixedOffsetTimezone(net_mins_offset) + # Create an offset object + tzoffset = FixedOffsetTimezone(net_mins_offset) - # Store the offset in a datetime object - dt = datetime.fromtimestamp(ts) - return dt.replace(tzinfo=tzoffset) + # Store the offset in a datetime object + dt = dt.replace(tzinfo=tzoffset) + + return dt class Message(object): diff --git a/tests/messages/test_catalog.py b/tests/messages/test_catalog.py index fcac34d..aac71ee 100644 --- a/tests/messages/test_catalog.py +++ b/tests/messages/test_catalog.py @@ -454,3 +454,17 @@ def test_catalog_update(): assert not 'head' in cat assert list(cat.obsolete.values())[0].id == 'head' + + +def test_datetime_parsing(): + val1 = catalog._parse_datetime_header('2006-06-28 23:24+0200') + assert val1.year == 2006 + assert val1.month == 6 + assert val1.day == 28 + assert val1.tzinfo.zone == 'Etc/GMT+120' + + val2 = catalog._parse_datetime_header('2006-06-28 23:24') + assert val2.year == 2006 + assert val2.month == 6 + assert val2.day == 28 + assert val2.tzinfo is None -- cgit v1.2.1 From 764f68b42a0f2dc0ad82152f84008503e2ac0d3d Mon Sep 17 00:00:00 2001 From: Alex Morega Date: Mon, 6 Jan 2014 22:39:22 +0200 Subject: re-enable doctests --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f2cdc96..48120c6 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ test: import-cldr - @py.test tests + @py.test test-env: @virtualenv test-env -- cgit v1.2.1 From 2eb475f835375c1b3b7fefcb7d8aad7047d7fda7 Mon Sep 17 00:00:00 2001 From: Alex Morega Date: Mon, 6 Jan 2014 22:48:15 +0200 Subject: specify locale otherwise, running tests in another locale fails fixes #45, thanks @Arfrever! --- babel/dates.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/babel/dates.py b/babel/dates.py index 72674e8..73d54fa 100644 --- a/babel/dates.py +++ b/babel/dates.py @@ -733,9 +733,9 @@ def format_timedelta(delta, granularity='second', threshold=.85, In addition directional information can be provided that informs the user if the date is in the past or in the future: - >>> format_timedelta(timedelta(hours=1), add_direction=True) + >>> format_timedelta(timedelta(hours=1), add_direction=True, locale='en') u'In 1 hour' - >>> format_timedelta(timedelta(hours=-1), add_direction=True) + >>> format_timedelta(timedelta(hours=-1), add_direction=True, locale='en') u'1 hour ago' :param delta: a ``timedelta`` object representing the time difference to -- cgit v1.2.1 From 2af2c176b09b0fd90b91e6678e2afaf1355f838b Mon Sep 17 00:00:00 2001 From: Alex Morega Date: Mon, 6 Jan 2014 23:15:45 +0200 Subject: change spelling of the encoding Apparently jython doesn't understand "utf_8". Fixes #46. --- babel/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/babel/util.py b/babel/util.py index f46ee2b..a65fce3 100644 --- a/babel/util.py +++ b/babel/util.py @@ -80,7 +80,7 @@ def parse_encoding(fp): raise SyntaxError( "python refuses to compile code with both a UTF8 " "byte-order-mark and a magic encoding comment") - return 'utf_8' + return 'utf-8' elif m: return m.group(1).decode('latin-1') else: -- cgit v1.2.1 From 7bad77ded77f658c2b8a478e4a35a672d143606e Mon Sep 17 00:00:00 2001 From: Alex Morega Date: Tue, 7 Jan 2014 08:16:16 +0200 Subject: fix warning for deprecated array.tostring fixes #75 --- Makefile | 2 +- babel/_compat.py | 5 +++++ babel/messages/mofile.py | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 48120c6..5bb68a9 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ test: import-cldr - @py.test + @PYTHONWARNINGS=default py.test test-env: @virtualenv test-env diff --git a/babel/_compat.py b/babel/_compat.py index 86096da..0f7640d 100644 --- a/babel/_compat.py +++ b/babel/_compat.py @@ -1,4 +1,5 @@ import sys +import array PY2 = sys.version_info[0] == 2 @@ -26,6 +27,8 @@ if not PY2: cmp = lambda a, b: (a > b) - (a < b) + array_tobytes = array.array.tobytes + else: text_type = unicode string_types = (str, unicode) @@ -47,5 +50,7 @@ else: cmp = cmp + array_tobytes = array.array.tostring + number_types = integer_types + (float,) diff --git a/babel/messages/mofile.py b/babel/messages/mofile.py index 5dd20ae..1850328 100644 --- a/babel/messages/mofile.py +++ b/babel/messages/mofile.py @@ -13,7 +13,7 @@ import array import struct from babel.messages.catalog import Catalog, Message -from babel._compat import range_type +from babel._compat import range_type, array_tobytes LE_MAGIC = 0x950412de @@ -206,4 +206,4 @@ def write_mo(fileobj, catalog, use_fuzzy=False): 7 * 4, # start of key index 7 * 4 + len(messages) * 8, # start of value index 0, 0 # size and offset of hash table - ) + array.array("i", offsets).tostring() + ids + strs) + ) + array_tobytes(array.array("i", offsets)) + ids + strs) -- cgit v1.2.1 From c21a3323d27f17556cd997a0f9279c6d0ec65be3 Mon Sep 17 00:00:00 2001 From: Alex Morega Date: Wed, 8 Jan 2014 13:24:40 +0200 Subject: correctly handle 'C.UTF-8' locale fixes #57 --- babel/core.py | 2 +- tests/test_core.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/babel/core.py b/babel/core.py index 4ada466..df38572 100644 --- a/babel/core.py +++ b/babel/core.py @@ -777,7 +777,7 @@ def default_locale(category=None, aliases=LOCALE_ALIASES): # the LANGUAGE variable may contain a colon-separated list of # language codes; we just pick the language on the list locale = locale.split(':')[0] - if locale in ('C', 'POSIX'): + if locale.split('.')[0] in ('C', 'POSIX'): locale = 'en_US_POSIX' elif aliases and locale in aliases: locale = aliases[locale] diff --git a/tests/test_core.py b/tests/test_core.py index ec3f9ea..ac2611d 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -238,6 +238,10 @@ def test_default_locale(os_environ): os_environ['LC_MESSAGES'] = 'POSIX' assert default_locale('LC_MESSAGES') == 'en_US_POSIX' + for value in ['C', 'C.UTF-8', 'POSIX']: + os_environ['LANGUAGE'] = value + assert default_locale() == 'en_US_POSIX' + def test_negotiate_locale(): assert (core.negotiate_locale(['de_DE', 'en_US'], ['de_DE', 'de_AT']) == -- cgit v1.2.1 From 514d41c0e73c58d43ace3ec310585bc48775196a Mon Sep 17 00:00:00 2001 From: Alex Morega Date: Wed, 15 Jan 2014 22:12:19 +0200 Subject: read/write all PO files in binary mode as pointed out in #52 --- babel/messages/frontend.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/babel/messages/frontend.py b/babel/messages/frontend.py index cead694..cd79ebf 100755 --- a/babel/messages/frontend.py +++ b/babel/messages/frontend.py @@ -128,7 +128,7 @@ class compile_catalog(Command): for idx, (locale, po_file) in enumerate(po_files): mo_file = mo_files[idx] - infile = open(po_file, 'r') + infile = open(po_file, 'rb') try: catalog = read_po(infile, locale) finally: @@ -439,7 +439,7 @@ class init_catalog(Command): log.info('creating catalog %r based on %r', self.output_file, self.input_file) - infile = open(self.input_file, 'r') + infile = open(self.input_file, 'rb') try: # Although reading from the catalog template, read_po must be fed # the locale in order to correctly calculate plurals @@ -554,7 +554,7 @@ class update_catalog(Command): if not domain: domain = os.path.splitext(os.path.basename(self.input_file))[0] - infile = open(self.input_file, 'U') + infile = open(self.input_file, 'rb') try: template = read_po(infile) finally: @@ -566,7 +566,7 @@ class update_catalog(Command): for locale, filename in po_files: log.info('updating catalog %r based on %r', filename, self.input_file) - infile = open(filename, 'U') + infile = open(filename, 'rb') try: catalog = read_po(infile, locale=locale, domain=domain) finally: @@ -577,7 +577,7 @@ class update_catalog(Command): tmpname = os.path.join(os.path.dirname(filename), tempfile.gettempprefix() + os.path.basename(filename)) - tmpfile = open(tmpname, 'w') + tmpfile = open(tmpname, 'wb') try: try: write_po(tmpfile, catalog, @@ -760,7 +760,7 @@ class CommandLineInterface(object): for idx, (locale, po_file) in enumerate(po_files): mo_file = mo_files[idx] - infile = open(po_file, 'r') + infile = open(po_file, 'rb') try: catalog = read_po(infile, locale) finally: -- cgit v1.2.1