diff options
author | Aarni Koskela <akx@iki.fi> | 2016-04-12 12:48:33 +0300 |
---|---|---|
committer | Aarni Koskela <akx@iki.fi> | 2016-04-12 12:48:33 +0300 |
commit | 3086b0c016d02c128832d07bc445f088bee4a4c6 (patch) | |
tree | 5d785e9a6b6bbb11d627bfa5ec1fe5b00c0b7a80 | |
parent | 9ac2fdff0acb118f27caaec900e29fd112eef293 (diff) | |
parent | d587b88fc3bbc58bd9a4254cd638cede4de31eba (diff) | |
download | babel-3086b0c016d02c128832d07bc445f088bee4a4c6.tar.gz |
Merge pull request #387 from akx/2.3.3
2.3.3 bugfix release
-rw-r--r-- | CHANGES | 10 | ||||
-rw-r--r-- | babel/__init__.py | 2 | ||||
-rw-r--r-- | babel/messages/frontend.py | 45 | ||||
-rw-r--r-- | docs/conf.py | 2 | ||||
-rw-r--r-- | tests/messages/test_frontend.py | 55 |
5 files changed, 93 insertions, 21 deletions
@@ -1,6 +1,16 @@ Babel Changelog =============== +Version 2.3.3 +------------- + +(Bugfix release, released on April 12th) + +Bugfixes +~~~~~~~~ + +* CLI: Usage regressions that had snuck in between 2.2 and 2.3 should be no more. (https://github.com/python-babel/babel/pull/386) Thanks to @ajaeger, @sebdiem and @jcristovao for bug reports and patches. + Version 2.3.2 ------------- diff --git a/babel/__init__.py b/babel/__init__.py index d8f5c7e..7f810c7 100644 --- a/babel/__init__.py +++ b/babel/__init__.py @@ -21,4 +21,4 @@ from babel.core import UnknownLocaleError, Locale, default_locale, \ negotiate_locale, parse_locale, get_locale_identifier -__version__ = '2.3.2' +__version__ = '2.3.3' diff --git a/babel/messages/frontend.py b/babel/messages/frontend.py index 3cacec9..62e7c03 100644 --- a/babel/messages/frontend.py +++ b/babel/messages/frontend.py @@ -218,7 +218,7 @@ class extract_messages(Command): 'charset to use in the output file (default "utf-8")'), ('keywords=', 'k', 'space-separated list of keywords to look for in addition to the ' - 'defaults'), + 'defaults (may be repeated multiple times)'), ('no-default-keywords', None, 'do not include the default keywords'), ('mapping-file=', 'F', @@ -248,12 +248,12 @@ class extract_messages(Command): 'set project version in output'), ('add-comments=', 'c', 'place comment block with TAG (or those preceding keyword lines) in ' - 'output file. Separate multiple TAGs with commas(,)'), + 'output file. Separate multiple TAGs with commas(,)'), # TODO: Support repetition of this argument ('strip-comments', None, 'strip the comment TAGs from the comments.'), ('input-paths=', None, 'files or directories that should be scanned for messages. Separate multiple ' - 'files or directories with commas(,)'), + 'files or directories with commas(,)'), # TODO: Support repetition of this argument ('input-dirs=', None, # TODO (3.x): Remove me. 'alias for input-paths (does allow files as well as directories).'), ] @@ -262,12 +262,11 @@ class extract_messages(Command): 'sort-output', 'sort-by-file', 'strip-comments' ] as_args = 'input-paths' - multiple_value_options = ('add-comments',) + multiple_value_options = ('add-comments', 'keywords') def initialize_options(self): self.charset = 'utf-8' - self.keywords = '' - self._keywords = DEFAULT_KEYWORDS.copy() + self.keywords = None self.no_default_keywords = False self.mapping_file = None self.no_location = False @@ -295,13 +294,19 @@ class extract_messages(Command): 'input-dirs and input-paths are mutually exclusive' ) - if self.no_default_keywords and not self.keywords: + if self.no_default_keywords: + keywords = {} + else: + keywords = DEFAULT_KEYWORDS.copy() + + for kwarg in (self.keywords or ()): + keywords.update(parse_keywords(kwarg.split())) + + self.keywords = keywords + + if not self.keywords: raise DistutilsOptionError('you must specify new keywords if you ' 'disable the default ones') - if self.no_default_keywords: - self._keywords = {} - if self.keywords: - self._keywords.update(parse_keywords(self.keywords.split())) if not self.output_file: raise DistutilsOptionError('no output file specified') @@ -378,13 +383,13 @@ class extract_messages(Command): current_dir = os.getcwd() extracted = check_and_call_extract_file( path, method_map, options_map, - callback, self._keywords, self.add_comments, + callback, self.keywords, self.add_comments, self.strip_comments, current_dir ) else: extracted = extract_from_dir( path, method_map, options_map, - keywords=self._keywords, + keywords=self.keywords, comment_tags=self.add_comments, callback=callback, strip_comment_tags=self.strip_comments @@ -592,7 +597,7 @@ class update_catalog(Command): ('previous', None, 'keep previous msgids of translated messages') ] - boolean_options = ['ignore_obsolete', 'no_fuzzy_matching', 'previous', 'update_header_comment'] + boolean_options = ['no-wrap', 'ignore-obsolete', 'no-fuzzy-matching', 'previous', 'update-header-comment'] def initialize_options(self): self.domain = 'messages' @@ -720,6 +725,8 @@ class CommandLineInterface(object): 'update': update_catalog, } + log = None # Replaced on instance level + def run(self, argv=None): """Main entry point of the command-line interface. @@ -768,7 +775,8 @@ class CommandLineInterface(object): if cmdname not in self.commands: self.parser.error('unknown command "%s"' % cmdname) - return self._dispatch(cmdname, args[1:]) + cmdinst = self._configure_command(cmdname, args[1:]) + return cmdinst.run() def _configure_logging(self, loglevel): self.log = logging.getLogger('babel') @@ -794,14 +802,15 @@ class CommandLineInterface(object): for name, description in commands: print(format % (name, description)) - def _dispatch(self, cmdname, argv): + def _configure_command(self, cmdname, argv): """ :type cmdname: str :type argv: list[str] """ cmdclass = self.command_classes[cmdname] cmdinst = cmdclass() - cmdinst.log = self.log # Use our logger, not distutils'. + if self.log: + cmdinst.log = self.log # Use our logger, not distutils'. assert isinstance(cmdinst, Command) cmdinst.initialize_options() @@ -837,7 +846,7 @@ class CommandLineInterface(object): except DistutilsOptionError as err: parser.error(str(err)) - cmdinst.run() + return cmdinst def main(): diff --git a/docs/conf.py b/docs/conf.py index 1ade98b..fc0530f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -53,7 +53,7 @@ copyright = u'2016, The Babel Team' # The short X.Y version. version = '2.3' # The full version, including alpha/beta/rc tags. -release = '2.3.2' +release = '2.3.3' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/tests/messages/test_frontend.py b/tests/messages/test_frontend.py index df48033..4c3c4a5 100644 --- a/tests/messages/test_frontend.py +++ b/tests/messages/test_frontend.py @@ -10,7 +10,7 @@ # This software consists of voluntary contributions made by many # individuals. For the exact contribution history, see the revision # history and logs, available at http://babel.edgewall.org/log/. - +import shlex from datetime import datetime from distutils.dist import Distribution from distutils.errors import DistutilsOptionError @@ -22,9 +22,12 @@ import sys import time import unittest +import pytest + from babel import __version__ as VERSION from babel.dates import format_datetime from babel.messages import frontend, Catalog +from babel.messages.frontend import CommandLineInterface, extract_messages from babel.util import LOCALTZ from babel.messages.pofile import read_po, write_po from babel._compat import StringIO @@ -1227,3 +1230,53 @@ def test_parse_keywords(): 'dngettext': (2, 3), 'pgettext': ((1, 'c'), 2), } + + +@pytest.mark.parametrize("split", (False, True)) +def test_extract_keyword_args_384(split): + # This is a regression test for https://github.com/python-babel/babel/issues/384 + + kwarg_specs = [ + "gettext_noop", + "gettext_lazy", + "ngettext_lazy:1,2", + "ugettext_noop", + "ugettext_lazy", + "ungettext_lazy:1,2", + "pgettext_lazy:1c,2", + "npgettext_lazy:1c,2,3", + ] + + if split: # Generate a command line with multiple -ks + kwarg_text = " ".join("-k %s" % kwarg_spec for kwarg_spec in kwarg_specs) + else: # Generate a single space-separated -k + kwarg_text = "-k \"%s\"" % " ".join(kwarg_specs) + + # (Both of those invocation styles should be equivalent, so there is no parametrization from here on out) + + cmdline = "extract -F babel-django.cfg --add-comments Translators: -o django232.pot %s ." % kwarg_text + + args = shlex.split(cmdline) + cli = CommandLineInterface() + cmdinst = cli._configure_command(cmdname=args[0], argv=args[1:]) + assert isinstance(cmdinst, extract_messages) + assert set(cmdinst.keywords.keys()) == set(( + '_', + 'dgettext', + 'dngettext', + 'gettext', + 'gettext_lazy', + 'gettext_noop', + 'N_', + 'ngettext', + 'ngettext_lazy', + 'npgettext', + 'npgettext_lazy', + 'pgettext', + 'pgettext_lazy', + 'ugettext', + 'ugettext_lazy', + 'ugettext_noop', + 'ungettext', + 'ungettext_lazy', + )) |