Patchwork [3,of,5] templater: move getdictitem() to hybrid class

login
register
mail settings
Submitter Yuya Nishihara
Date June 5, 2018, 1:18 p.m.
Message ID <8d50ec6e8b832fec6b9d.1528204737@mimosa>
Download mbox | patch
Permalink /patch/31983/
State Accepted
Headers show

Comments

Yuya Nishihara - June 5, 2018, 1:18 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1521563984 -32400
#      Wed Mar 21 01:39:44 2018 +0900
# Node ID 8d50ec6e8b832fec6b9dc42cd1d7be2ff53199b9
# Parent  e666247f5c2b95a10a84123257fbe2b8af05c1e5
templater: move getdictitem() to hybrid class

Since a raw dict will never be returned by evalwrapped(), we don't need
to support d.get(key).

Patch

diff --git a/mercurial/templatefuncs.py b/mercurial/templatefuncs.py
--- a/mercurial/templatefuncs.py
+++ b/mercurial/templatefuncs.py
@@ -262,12 +262,12 @@  def get(context, mapping, args):
         raise error.ParseError(_("get() expects two arguments"))
 
     dictarg = evalwrapped(context, mapping, args[0])
-    if not util.safehasattr(dictarg, 'get'):
+    if not util.safehasattr(dictarg, 'getmember'):
         # i18n: "get" is a keyword
         raise error.ParseError(_("get() expects a dict as first argument"))
 
     key = evalfuncarg(context, mapping, args[1])
-    return templateutil.getdictitem(dictarg, key)
+    return dictarg.getmember(context, mapping, key)
 
 @templatefunc('if(expr, then[, else])')
 def if_(context, mapping, args):
diff --git a/mercurial/templateutil.py b/mercurial/templateutil.py
--- a/mercurial/templateutil.py
+++ b/mercurial/templateutil.py
@@ -128,6 +128,17 @@  class hybrid(wrapped):
         self._joinfmt = joinfmt
         self.keytype = keytype  # hint for 'x in y' where type(x) is unresolved
 
+    def getmember(self, context, mapping, key):
+        # TODO: maybe split hybrid list/dict types?
+        if not util.safehasattr(self._values, 'get'):
+            raise error.ParseError(_('not a dictionary'))
+        return self._wrapvalue(key, self._values.get(key))
+
+    def _wrapvalue(self, key, val):
+        if val is None:
+            return
+        return wraphybridvalue(self, key, val)
+
     def itermaps(self, context):
         makemap = self._makemap
         for x in self._values:
@@ -667,8 +678,8 @@  def runmember(context, mapping, data):
         lm = context.overlaymap(mapping, d.tomap())
         return runsymbol(context, lm, memb)
     try:
-        if util.safehasattr(d, 'get'):
-            return getdictitem(d, memb)
+        if util.safehasattr(d, 'getmember'):
+            return d.getmember(context, mapping, memb)
         raise error.ParseError
     except error.ParseError:
         sym = findsymbolicname(darg)
@@ -693,12 +704,6 @@  def runarithmetic(context, mapping, data
     except ZeroDivisionError:
         raise error.Abort(_('division by zero is not defined'))
 
-def getdictitem(dictarg, key):
-    val = dictarg.get(key)
-    if val is None:
-        return
-    return wraphybridvalue(dictarg, key, val)
-
 def joinitems(itemiter, sep):
     """Join items with the separator; Returns generator of bytes"""
     first = True