* 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 Pedro
+ * 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)
Version 0.9.6
http://svn.edgewall.org/repos/babel/tags/0.9.6/
'ungettext': (1, 2),
'dgettext': (2,),
'dngettext': (2, 3),
- 'N_': None
+ 'N_': None,
+ 'pgettext': ((1, 'c'), 2)
}
DEFAULT_MAPPING = [('**.py', 'python')]
positional arguments, in that order
:param strip_comment_tags: a flag that if set to `True` causes all comment
tags to be removed from the collected comments.
- :return: an iterator over ``(filename, lineno, funcname, message)`` tuples
+ :return: an iterator over ``(filename, lineno, funcname, message, context)``
+ tuples
:rtype: ``iterator``
:see: `pathmatch`
"""
options = odict
if callback:
callback(filename, method, options)
- for lineno, message, comments in \
+ for lineno, message, comments, context in \
extract_from_file(method, filepath,
keywords=keywords,
comment_tags=comment_tags,
options=options,
strip_comment_tags=
strip_comment_tags):
- yield filename, lineno, message, comments
+ yield filename, lineno, message, comments, context
break
>>> from StringIO import StringIO
>>> for message in extract('python', StringIO(source)):
... print message
- (3, u'Hello, world!', [])
+ (3, u'Hello, world!', [], None)
:param method: a string specifying the extraction method (.e.g. "python");
if this is a simple name, the extraction function will be
continue
# Validate the messages against the keyword's specification
+ context = None
msgs = []
invalid = False
# last_index is 1 based like the keyword spec
last_index = len(messages)
for index in spec:
+ if isinstance(index, tuple):
+ context = messages[index[0] - 1]
+ continue
if last_index < index:
# Not enough arguments
invalid = True
if invalid:
continue
- first_msg_index = spec[0] - 1
+ # keyword spec indexes are 1 based, therefore '-1'
+ if isinstance(spec[0], tuple):
+ # context-aware *gettext method
+ first_msg_index = spec[1] - 1
+ else:
+ first_msg_index = spec[0] - 1
if not messages[first_msg_index]:
# An empty string msgid isn't valid, emit a warning
where = '%s:%i' % (hasattr(fileobj, 'name') and \
if strip_comment_tags:
_strip_comment_tags(comments, comment_tags)
- yield lineno, messages, comments
+ yield lineno, messages, comments, context
def extract_nothing(fileobj, keywords, comment_tags, options):
callback=callback,
strip_comment_tags=
self.strip_comments)
- for filename, lineno, message, comments in extracted:
+ for filename, lineno, message, comments, context in extracted:
filepath = os.path.normpath(os.path.join(dirname, filename))
catalog.add(message, None, [(filepath, lineno)],
- auto_comments=comments)
+ auto_comments=comments, context=context)
log.info('writing PO template file to %s' % self.output_file)
write_po(outfile, catalog, width=self.width,
callback=callback,
strip_comment_tags=
options.strip_comment_tags)
- for filename, lineno, message, comments in extracted:
+ for filename, lineno, message, comments, context in extracted:
filepath = os.path.normpath(os.path.join(dirname, filename))
catalog.add(message, None, [(filepath, lineno)],
- auto_comments=comments)
+ auto_comments=comments, context=context)
if options.output not in (None, '-'):
self.log.info('writing PO template file to %s' % options.output)
def parse_keywords(strings=[]):
"""Parse keywords specifications from the given list of strings.
- >>> kw = parse_keywords(['_', 'dgettext:2', 'dngettext:2,3']).items()
+ >>> kw = parse_keywords(['_', 'dgettext:2', 'dngettext:2,3', 'pgettext:1c,2']).items()
>>> kw.sort()
>>> for keyword, indices in kw:
... print (keyword, indices)
('_', None)
('dgettext', (2,))
('dngettext', (2, 3))
+ ('pgettext', ((1, 'c'), 2))
"""
keywords = {}
for string in strings:
funcname, indices = string, None
if funcname not in keywords:
if indices:
- indices = tuple([(int(x)) for x in indices.split(',')])
+ inds = []
+ for x in indices.split(','):
+ if x[-1] == 'c':
+ inds.append((int(x[:-1]), 'c'))
+ else:
+ inds.append(int(x))
+ indices = tuple(inds)
keywords[funcname] = indices
return keywords
list(extract.extract('javascript', buf, extract.DEFAULT_KEYWORDS,
[], {}))
- self.assertEqual([(1, 'simple', []),
- (2, 'simple', []),
- (3, ('s', 'p'), [])], messages)
+ self.assertEqual([(1, 'simple', [], None),
+ (2, 'simple', [], None),
+ (3, ('s', 'p'), [], None)], messages)
def test_various_calls(self):
buf = StringIO("""\
messages = \
list(extract.extract('javascript', buf, extract.DEFAULT_KEYWORDS, [],
{}))
- self.assertEqual([(5, (u'bunny', u'bunnies'), []),
- (8, u'Rabbit', []),
- (10, (u'Page', u'Pages'), [])], messages)
+ self.assertEqual([(5, (u'bunny', u'bunnies'), [], None),
+ (8, u'Rabbit', [], None),
+ (10, (u'Page', u'Pages'), [], None)], messages)
def test_message_with_line_comment(self):
buf = StringIO("""\
messages = \
list(extract.extract('python', buf, extract.DEFAULT_KEYWORDS, [],
{}))
- self.assertEqual([(5, (u'bunny', u'bunnies'), []),
- (8, u'Rabbit', []),
- (10, (u'Page', u'Pages'), [])], messages)
+ self.assertEqual([(5, (u'bunny', u'bunnies'), [], None),
+ (8, u'Rabbit', [], None),
+ (10, (u'Page', u'Pages'), [], None)], messages)
def test_invalid_extract_method(self):
buf = StringIO('')
finally:
sys.stderr = stderr
+ def test_warn_if_empty_string_msgid_found_in_context_aware_extraction_method(self):
+ buf = StringIO("\nmsg = pgettext('ctxt', '')\n")
+ stderr = sys.stderr
+ sys.stderr = StringIO()
+ try:
+ messages = extract.extract('python', buf)
+ self.assertEqual([], list(messages))
+ assert 'warning: Empty msgid.' in sys.stderr.getvalue()
+ finally:
+ sys.stderr = stderr
+
def suite():
suite = unittest.TestSuite()