comparison mercurial/templatefuncs.py @ 38227:1c8098cf560a

templater: always join() over a wrapped object (BC) This is a behavior change in a sense that join() of a byte string is no longer "implementation dependent." Before, if a byte string was backed by a lazy generator, join() would concatenate each chunk with the specified separator, which seems wrong. The new behavior is always join() each byte. TypeError on join() over uniterable is also fixed.
author Yuya Nishihara <yuya@tcha.org>
date Sat, 21 Apr 2018 17:00:21 +0900
parents d48b80d58848
children ead71b15efd5
comparison
equal deleted inserted replaced
38226:7824783a6d5e 38227:1c8098cf560a
34 dateutil, 34 dateutil,
35 stringutil, 35 stringutil,
36 ) 36 )
37 37
38 evalrawexp = templateutil.evalrawexp 38 evalrawexp = templateutil.evalrawexp
39 evalwrapped = templateutil.evalwrapped
39 evalfuncarg = templateutil.evalfuncarg 40 evalfuncarg = templateutil.evalfuncarg
40 evalboolean = templateutil.evalboolean 41 evalboolean = templateutil.evalboolean
41 evaldate = templateutil.evaldate 42 evaldate = templateutil.evaldate
42 evalinteger = templateutil.evalinteger 43 evalinteger = templateutil.evalinteger
43 evalstring = templateutil.evalstring 44 evalstring = templateutil.evalstring
325 """Join items in a list with a delimiter.""" 326 """Join items in a list with a delimiter."""
326 if not (1 <= len(args) <= 2): 327 if not (1 <= len(args) <= 2):
327 # i18n: "join" is a keyword 328 # i18n: "join" is a keyword
328 raise error.ParseError(_("join expects one or two arguments")) 329 raise error.ParseError(_("join expects one or two arguments"))
329 330
330 joinset = evalrawexp(context, mapping, args[0]) 331 joinset = evalwrapped(context, mapping, args[0])
331 joiner = " " 332 joiner = " "
332 if len(args) > 1: 333 if len(args) > 1:
333 joiner = evalstring(context, mapping, args[1]) 334 joiner = evalstring(context, mapping, args[1])
334 if isinstance(joinset, templateutil.wrapped): 335 return joinset.join(context, mapping, joiner)
335 return joinset.join(context, mapping, joiner)
336 # TODO: rethink about join() of a byte string, which had no defined
337 # behavior since a string may be either a bytes or a generator.
338 # TODO: fix type error on join() of non-iterable
339 joinset = templateutil.unwrapvalue(context, mapping, joinset)
340 return templateutil.joinitems(pycompat.maybebytestr(joinset), joiner)
341 336
342 @templatefunc('label(label, expr)') 337 @templatefunc('label(label, expr)')
343 def label(context, mapping, args): 338 def label(context, mapping, args):
344 """Apply a label to generated content. Content with 339 """Apply a label to generated content. Content with
345 a label applied can result in additional post-processing, such as 340 a label applied can result in additional post-processing, such as