Patchwork [2,of,2] templatefuncs: do not stringify result of if*() expression

login
register
mail settings
Submitter Yuya Nishihara
Date March 19, 2018, 1:46 p.m.
Message ID <3e0eb7c1020aa020f578.1521467176@mimosa>
Download mbox | patch
Permalink /patch/29622/
State Accepted
Headers show

Comments

Yuya Nishihara - March 19, 2018, 1:46 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1521465040 -32400
#      Mon Mar 19 22:10:40 2018 +0900
# Node ID 3e0eb7c1020aa020f5781bee23cad4f78a8f03ef
# Parent  cb8ab2dddf79e4ff203e22b4130ceca5b88bb14b
templatefuncs: do not stringify result of if*() expression

Returning a generator means that the result is a byte string. I can't find
any reason to make the "if" condition lazy since it is evaluated anyway
when {if()} has to be evaluated. So let's simply make if*() return an input
expression unmodified.

Patch

diff --git a/mercurial/templatefuncs.py b/mercurial/templatefuncs.py
--- a/mercurial/templatefuncs.py
+++ b/mercurial/templatefuncs.py
@@ -248,9 +248,9 @@  def if_(context, mapping, args):
 
     test = evalboolean(context, mapping, args[0])
     if test:
-        yield evalrawexp(context, mapping, args[1])
+        return evalrawexp(context, mapping, args[1])
     elif len(args) == 3:
-        yield evalrawexp(context, mapping, args[2])
+        return evalrawexp(context, mapping, args[2])
 
 @templatefunc('ifcontains(needle, haystack, then[, else])')
 def ifcontains(context, mapping, args):
@@ -269,9 +269,9 @@  def ifcontains(context, mapping, args):
         found = False
 
     if found:
-        yield evalrawexp(context, mapping, args[2])
+        return evalrawexp(context, mapping, args[2])
     elif len(args) == 4:
-        yield evalrawexp(context, mapping, args[3])
+        return evalrawexp(context, mapping, args[3])
 
 @templatefunc('ifeq(expr1, expr2, then[, else])')
 def ifeq(context, mapping, args):
@@ -284,9 +284,9 @@  def ifeq(context, mapping, args):
     test = evalstring(context, mapping, args[0])
     match = evalstring(context, mapping, args[1])
     if test == match:
-        yield evalrawexp(context, mapping, args[2])
+        return evalrawexp(context, mapping, args[2])
     elif len(args) == 4:
-        yield evalrawexp(context, mapping, args[3])
+        return evalrawexp(context, mapping, args[3])
 
 @templatefunc('join(list, sep)')
 def join(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
@@ -3242,6 +3242,35 @@  Test min/max of integers
   $ hg log -R latesttag -l1 -T '{max(revset("9:10"))}\n'
   10
 
+Test min/max of if() result
+
+  $ cd latesttag
+  $ hg log -l1 -T '{min(if(true, revset("9:10"), ""))}\n'
+  9
+  $ hg log -l1 -T '{max(if(false, "", revset("9:10")))}\n'
+  10
+  $ hg log -l1 -T '{min(ifcontains("a", "aa", revset("9:10"), ""))}\n'
+  9
+  $ hg log -l1 -T '{max(ifcontains("a", "bb", "", revset("9:10")))}\n'
+  10
+  $ hg log -l1 -T '{min(ifeq(0, 0, revset("9:10"), ""))}\n'
+  9
+  $ hg log -l1 -T '{max(ifeq(0, 1, "", revset("9:10")))}\n'
+  10
+  $ cd ..
+
+Test laziness of if() then/else clause
+
+  $ hg debugtemplate '{count(0)}'
+  abort: incompatible use of template filter 'count'
+  [255]
+  $ hg debugtemplate '{if(true, "", count(0))}'
+  $ hg debugtemplate '{if(false, count(0), "")}'
+  $ hg debugtemplate '{ifcontains("a", "aa", "", count(0))}'
+  $ hg debugtemplate '{ifcontains("a", "bb", count(0), "")}'
+  $ hg debugtemplate '{ifeq(0, 0, "", count(0))}'
+  $ hg debugtemplate '{ifeq(0, 1, count(0), "")}'
+
 Test dot operator precedence:
 
   $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n'