comparison babel/messages/extract.py @ 569:1b801a0cb2cb trunk

Support for context-aware methods during message extraction (fixes #229, patch by David Rios)
author fschwarz
date Mon, 26 Sep 2011 20:01:01 +0000
parents 86524be05b60
children 99983baf1067
comparison
equal deleted inserted replaced
568:39ff5164e8ea 569:1b801a0cb2cb
39 'ngettext': (1, 2), 39 'ngettext': (1, 2),
40 'ugettext': None, 40 'ugettext': None,
41 'ungettext': (1, 2), 41 'ungettext': (1, 2),
42 'dgettext': (2,), 42 'dgettext': (2,),
43 'dngettext': (2, 3), 43 'dngettext': (2, 3),
44 'N_': None 44 'N_': None,
45 'pgettext': ((1, 'c'), 2)
45 } 46 }
46 47
47 DEFAULT_MAPPING = [('**.py', 'python')] 48 DEFAULT_MAPPING = [('**.py', 'python')]
48 49
49 empty_msgid_warning = ( 50 empty_msgid_warning = (
128 performed; the function is passed the filename, the name 129 performed; the function is passed the filename, the name
129 of the extraction method and and the options dictionary as 130 of the extraction method and and the options dictionary as
130 positional arguments, in that order 131 positional arguments, in that order
131 :param strip_comment_tags: a flag that if set to `True` causes all comment 132 :param strip_comment_tags: a flag that if set to `True` causes all comment
132 tags to be removed from the collected comments. 133 tags to be removed from the collected comments.
133 :return: an iterator over ``(filename, lineno, funcname, message)`` tuples 134 :return: an iterator over ``(filename, lineno, funcname, message, context)``
135 tuples
134 :rtype: ``iterator`` 136 :rtype: ``iterator``
135 :see: `pathmatch` 137 :see: `pathmatch`
136 """ 138 """
137 if options_map is None: 139 if options_map is None:
138 options_map = {} 140 options_map = {}
156 for opattern, odict in options_map.items(): 158 for opattern, odict in options_map.items():
157 if pathmatch(opattern, filename): 159 if pathmatch(opattern, filename):
158 options = odict 160 options = odict
159 if callback: 161 if callback:
160 callback(filename, method, options) 162 callback(filename, method, options)
161 for lineno, message, comments in \ 163 for lineno, message, comments, context in \
162 extract_from_file(method, filepath, 164 extract_from_file(method, filepath,
163 keywords=keywords, 165 keywords=keywords,
164 comment_tags=comment_tags, 166 comment_tags=comment_tags,
165 options=options, 167 options=options,
166 strip_comment_tags= 168 strip_comment_tags=
167 strip_comment_tags): 169 strip_comment_tags):
168 yield filename, lineno, message, comments 170 yield filename, lineno, message, comments, context
169 break 171 break
170 172
171 173
172 def extract_from_file(method, filename, keywords=DEFAULT_KEYWORDS, 174 def extract_from_file(method, filename, keywords=DEFAULT_KEYWORDS,
173 comment_tags=(), options=None, strip_comment_tags=False): 175 comment_tags=(), options=None, strip_comment_tags=False):
217 ... ''' 219 ... '''
218 220
219 >>> from StringIO import StringIO 221 >>> from StringIO import StringIO
220 >>> for message in extract('python', StringIO(source)): 222 >>> for message in extract('python', StringIO(source)):
221 ... print message 223 ... print message
222 (3, u'Hello, world!', []) 224 (3, u'Hello, world!', [], None)
223 225
224 :param method: a string specifying the extraction method (.e.g. "python"); 226 :param method: a string specifying the extraction method (.e.g. "python");
225 if this is a simple name, the extraction function will be 227 if this is a simple name, the extraction function will be
226 looked up by entry point; if it is an explicit reference 228 looked up by entry point; if it is an explicit reference
227 to a function (of the form ``package.module:funcname`` or 229 to a function (of the form ``package.module:funcname`` or
277 messages = [messages] 279 messages = [messages]
278 if not messages: 280 if not messages:
279 continue 281 continue
280 282
281 # Validate the messages against the keyword's specification 283 # Validate the messages against the keyword's specification
284 context = None
282 msgs = [] 285 msgs = []
283 invalid = False 286 invalid = False
284 # last_index is 1 based like the keyword spec 287 # last_index is 1 based like the keyword spec
285 last_index = len(messages) 288 last_index = len(messages)
286 for index in spec: 289 for index in spec:
290 if isinstance(index, tuple):
291 context = messages[index[0] - 1]
292 continue
287 if last_index < index: 293 if last_index < index:
288 # Not enough arguments 294 # Not enough arguments
289 invalid = True 295 invalid = True
290 break 296 break
291 message = messages[index - 1] 297 message = messages[index - 1]
294 break 300 break
295 msgs.append(message) 301 msgs.append(message)
296 if invalid: 302 if invalid:
297 continue 303 continue
298 304
299 first_msg_index = spec[0] - 1 305 # keyword spec indexes are 1 based, therefore '-1'
306 if isinstance(spec[0], tuple):
307 # context-aware *gettext method
308 first_msg_index = spec[1] - 1
309 else:
310 first_msg_index = spec[0] - 1
300 if not messages[first_msg_index]: 311 if not messages[first_msg_index]:
301 # An empty string msgid isn't valid, emit a warning 312 # An empty string msgid isn't valid, emit a warning
302 where = '%s:%i' % (hasattr(fileobj, 'name') and \ 313 where = '%s:%i' % (hasattr(fileobj, 'name') and \
303 fileobj.name or '(unknown)', lineno) 314 fileobj.name or '(unknown)', lineno)
304 print >> sys.stderr, empty_msgid_warning % where 315 print >> sys.stderr, empty_msgid_warning % where
308 if len(messages) == 1: 319 if len(messages) == 1:
309 messages = messages[0] 320 messages = messages[0]
310 321
311 if strip_comment_tags: 322 if strip_comment_tags:
312 _strip_comment_tags(comments, comment_tags) 323 _strip_comment_tags(comments, comment_tags)
313 yield lineno, messages, comments 324 yield lineno, messages, comments, context
314 325
315 326
316 def extract_nothing(fileobj, keywords, comment_tags, options): 327 def extract_nothing(fileobj, keywords, comment_tags, options):
317 """Pseudo extractor that does not actually extract anything, but simply 328 """Pseudo extractor that does not actually extract anything, but simply
318 returns an empty list. 329 returns an empty list.
Copyright (C) 2012-2017 Edgewall Software