# HG changeset patch # User Yuya Nishihara # Date 2018-04-21 08:00:21 # 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 --git a/mercurial/templatefuncs.py b/mercurial/templatefuncs.py --- a/mercurial/templatefuncs.py +++ b/mercurial/templatefuncs.py @@ -36,6 +36,7 @@ from .utils import ( ) evalrawexp = templateutil.evalrawexp +evalwrapped = templateutil.evalwrapped evalfuncarg = templateutil.evalfuncarg evalboolean = templateutil.evalboolean evaldate = templateutil.evaldate @@ -327,17 +328,11 @@ def join(context, mapping, args): # 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 --git a/tests/test-command-template.t b/tests/test-command-template.t --- a/tests/test-command-template.t +++ b/tests/test-command-template.t @@ -3249,6 +3249,17 @@ Test manifest/get() can be join()-ed as $ 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'