templater: always join() over a wrapped object (BC)
authorYuya Nishihara <yuya@tcha.org>
Sat, 21 Apr 2018 17:00:21 +0900
changeset 38227 1c8098cf560a
parent 38226 7824783a6d5e
child 38228 8bded7eae26c
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.
mercurial/templatefuncs.py
tests/test-command-template.t
--- 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):
--- 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'