# HG changeset patch # User Yuya Nishihara # Date 1524297621 -32400 # Node ID 1c8098cf560a8f9c66be06247613a577351513e1 # Parent 7824783a6d5e780f2b4cf38c9ae13943a84aeb93 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. diff -r 7824783a6d5e -r 1c8098cf560a mercurial/templatefuncs.py --- a/mercurial/templatefuncs.py Tue Mar 20 23:56:26 2018 +0900 +++ b/mercurial/templatefuncs.py Sat Apr 21 17:00:21 2018 +0900 @@ -36,6 +36,7 @@ ) evalrawexp = templateutil.evalrawexp +evalwrapped = templateutil.evalwrapped evalfuncarg = templateutil.evalfuncarg evalboolean = templateutil.evalboolean evaldate = templateutil.evaldate @@ -327,17 +328,11 @@ # i18n: "join" is a keyword raise error.ParseError(_("join expects one or two arguments")) - joinset = evalrawexp(context, mapping, args[0]) + joinset = evalwrapped(context, mapping, args[0]) joiner = " " if len(args) > 1: joiner = evalstring(context, mapping, args[1]) - if isinstance(joinset, templateutil.wrapped): - return joinset.join(context, mapping, joiner) - # TODO: rethink about join() of a byte string, which had no defined - # behavior since a string may be either a bytes or a generator. - # TODO: fix type error on join() of non-iterable - joinset = templateutil.unwrapvalue(context, mapping, joinset) - return templateutil.joinitems(pycompat.maybebytestr(joinset), joiner) + return joinset.join(context, mapping, joiner) @templatefunc('label(label, expr)') def label(context, mapping, args): diff -r 7824783a6d5e -r 1c8098cf560a tests/test-command-template.t --- a/tests/test-command-template.t Tue Mar 20 23:56:26 2018 +0900 +++ b/tests/test-command-template.t Sat Apr 21 17:00:21 2018 +0900 @@ -3249,6 +3249,17 @@ $ hg log -R latesttag -r tip -T '{join(get(extras, "branch"), "")}\n' default +Test join() over string + + $ hg log -R latesttag -r tip -T '{join(rev|stringify, ".")}\n' + 1.1 + +Test join() over uniterable + + $ hg log -R latesttag -r tip -T '{join(rev, "")}\n' + hg: parse error: 11 is not iterable + [255] + Test min/max of integers $ hg log -R latesttag -l1 -T '{min(revset("9:10"))}\n'