[PATCH 4 of 4] templater: look up symbols/resources as if they were separated (issue5699)

Yuya Nishihara yuya at tcha.org
Thu Dec 21 10:08:47 EST 2017


# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1513862259 -32400
#      Thu Dec 21 22:17:39 2017 +0900
# Node ID 9d50cfedc380d05dfbe0ed8b9360603b61b3c601
# Parent  c06827f22f361f8e1ff3431c18ed0734708149ed
templater: look up symbols/resources as if they were separated (issue5699)

It wouldn't be easy to split the mapping dict into (symbols, resources). This
patch instead rejects invalid lookup taking resources.keys() as source of
truth.

The doctest is updated since mapping['repo'] is now reserved for a repo
object.

diff --git a/mercurial/formatter.py b/mercurial/formatter.py
--- a/mercurial/formatter.py
+++ b/mercurial/formatter.py
@@ -94,14 +94,14 @@ Nested example:
 
 >>> def subrepos(ui, fm):
 ...     fm.startitem()
-...     fm.write(b'repo', b'[%s]\\n', b'baz')
+...     fm.write(b'reponame', b'[%s]\\n', b'baz')
 ...     files(ui, fm.nested(b'files'))
 ...     fm.end()
 >>> show(subrepos)
 [baz]
 foo
 bar
->>> show(subrepos, template=b'{repo}: {join(files % "{path}", ", ")}\\n')
+>>> show(subrepos, template=b'{reponame}: {join(files % "{path}", ", ")}\\n')
 baz: foo, bar
 """
 
@@ -491,7 +491,9 @@ def templateresources(ui, repo=None):
     and function"""
     return {
         'cache': {},  # for templatekw/funcs to store reusable data
+        'ctx': None,
         'repo': repo,
+        'revcache': None,  # per-ctx cache; set later
         'ui': ui,
     }
 
diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -1320,7 +1320,9 @@ class engine(object):
 
     def symbol(self, mapping, key):
         """Resolve symbol to value or function; None if nothing found"""
-        v = mapping.get(key)
+        v = None
+        if key not in self._resources:
+            v = mapping.get(key)
         if v is None:
             v = self._defaults.get(key)
         return v
@@ -1328,11 +1330,13 @@ class engine(object):
     def resource(self, mapping, key):
         """Return internal data (e.g. cache) used for keyword/function
         evaluation"""
-        v = mapping.get(key)
+        v = None
+        if key in self._resources:
+            v = mapping.get(key)
         if v is None:
             v = self._resources.get(key)
         if v is None:
-            raise KeyError
+            raise error.Abort(_('template resource not available: %s') % key)
         return v
 
     def _load(self, t):
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
@@ -206,7 +206,13 @@ never cause crash:
 
 Internal resources shouldn't be exposed (issue5699):
 
-  $ hg log -r. -T '{cache}{repo}{templ}{ui}'
+  $ hg log -r. -T '{cache}{ctx}{repo}{revcache}{templ}{ui}'
+
+Never crash on internal resource not available:
+
+  $ hg --cwd .. debugtemplate '{"c0bebeef"|shortest}\n'
+  abort: template resource not available: ctx
+  [255]
 
 Quoting for ui.logtemplate
 


More information about the Mercurial-devel mailing list