diff mercurial/templatefuncs.py @ 38239: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
line wrap: on
line diff
--- 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):