Mercurial > hg > mercurial-source
annotate mercurial/templateutil.py @ 38008:54355c243042
templatefilters: allow declaration of input data type
Currently filters take an unwrapped value, which should have no hybrid magic
but actually it does because stringify() relies on it. The 'intype' allows
us to pre-process the magic by .e.g. evalstring() keeping filter functions
as simple as they are now.
stringify() is ported as an example. More follow.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 18 Mar 2018 15:14:58 +0900 |
parents | 0fb28899e81a |
children | 67efce231633 |
rev | line source |
---|---|
37699
da2977e674a3
templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37698
diff
changeset
|
1 # templateutil.py - utility for template evaluation |
1909
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
2 # |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
4 # |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
8223
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
10263 | 6 # GNU General Public License version 2 or any later version. |
1909
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
7 |
37699
da2977e674a3
templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37698
diff
changeset
|
8 from __future__ import absolute_import |
26569
7eb357b5f774
templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26375
diff
changeset
|
9 |
17982
e06e9fd2d99f
template engine: convert generator-based iterator to list-based iterator
Weiwen <weiwen@fb.com>
parents:
17890
diff
changeset
|
10 import types |
26569
7eb357b5f774
templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26375
diff
changeset
|
11 |
7eb357b5f774
templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26375
diff
changeset
|
12 from .i18n import _ |
7eb357b5f774
templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26375
diff
changeset
|
13 from . import ( |
7eb357b5f774
templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26375
diff
changeset
|
14 error, |
31394
bb77654dc7ae
py3: replace os.sep with pycompat.ossep (part 3 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
31111
diff
changeset
|
15 pycompat, |
26569
7eb357b5f774
templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26375
diff
changeset
|
16 util, |
7eb357b5f774
templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26375
diff
changeset
|
17 ) |
37870
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37860
diff
changeset
|
18 from .utils import ( |
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37860
diff
changeset
|
19 stringutil, |
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37860
diff
changeset
|
20 ) |
13177
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
21 |
37230
717a279c0c21
templater: specialize ResourceUnavailable error so that it can be caught
Yuya Nishihara <yuya@tcha.org>
parents:
37229
diff
changeset
|
22 class ResourceUnavailable(error.Abort): |
717a279c0c21
templater: specialize ResourceUnavailable error so that it can be caught
Yuya Nishihara <yuya@tcha.org>
parents:
37229
diff
changeset
|
23 pass |
717a279c0c21
templater: specialize ResourceUnavailable error so that it can be caught
Yuya Nishihara <yuya@tcha.org>
parents:
37229
diff
changeset
|
24 |
37229
8dbd97aef915
templater: move specialized exception types to top
Yuya Nishihara <yuya@tcha.org>
parents:
37031
diff
changeset
|
25 class TemplateNotFound(error.Abort): |
8dbd97aef915
templater: move specialized exception types to top
Yuya Nishihara <yuya@tcha.org>
parents:
37031
diff
changeset
|
26 pass |
8dbd97aef915
templater: move specialized exception types to top
Yuya Nishihara <yuya@tcha.org>
parents:
37031
diff
changeset
|
27 |
37707
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
28 class hybrid(object): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
29 """Wrapper for list or dict to support legacy template |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
30 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
31 This class allows us to handle both: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
32 - "{files}" (legacy command-line-specific list hack) and |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
33 - "{files % '{file}\n'}" (hgweb-style with inlining and function support) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
34 and to access raw values: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
35 - "{ifcontains(file, files, ...)}", "{ifcontains(key, extras, ...)}" |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
36 - "{get(extras, key)}" |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
37 - "{files|json}" |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
38 """ |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
39 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
40 def __init__(self, gen, values, makemap, joinfmt, keytype=None): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
41 if gen is not None: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
42 self.gen = gen # generator or function returning generator |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
43 self._values = values |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
44 self._makemap = makemap |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
45 self.joinfmt = joinfmt |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
46 self.keytype = keytype # hint for 'x in y' where type(x) is unresolved |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
47 def gen(self): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
48 """Default generator to stringify this as {join(self, ' ')}""" |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
49 for i, x in enumerate(self._values): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
50 if i > 0: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
51 yield ' ' |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
52 yield self.joinfmt(x) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
53 def itermaps(self): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
54 makemap = self._makemap |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
55 for x in self._values: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
56 yield makemap(x) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
57 def __contains__(self, x): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
58 return x in self._values |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
59 def __getitem__(self, key): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
60 return self._values[key] |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
61 def __len__(self): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
62 return len(self._values) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
63 def __iter__(self): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
64 return iter(self._values) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
65 def __getattr__(self, name): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
66 if name not in (r'get', r'items', r'iteritems', r'iterkeys', |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
67 r'itervalues', r'keys', r'values'): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
68 raise AttributeError(name) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
69 return getattr(self._values, name) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
70 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
71 class mappable(object): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
72 """Wrapper for non-list/dict object to support map operation |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
73 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
74 This class allows us to handle both: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
75 - "{manifest}" |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
76 - "{manifest % '{rev}:{node}'}" |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
77 - "{manifest.rev}" |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
78 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
79 Unlike a hybrid, this does not simulate the behavior of the underling |
37949
0fb28899e81a
templater: factor out unwrapastype() from evalastype()
Yuya Nishihara <yuya@tcha.org>
parents:
37948
diff
changeset
|
80 value. Use unwrapvalue(), unwrapastype(), or unwraphybrid() to obtain |
0fb28899e81a
templater: factor out unwrapastype() from evalastype()
Yuya Nishihara <yuya@tcha.org>
parents:
37948
diff
changeset
|
81 the inner object. |
37707
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
82 """ |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
83 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
84 def __init__(self, gen, key, value, makemap): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
85 if gen is not None: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
86 self.gen = gen # generator or function returning generator |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
87 self._key = key |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
88 self._value = value # may be generator of strings |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
89 self._makemap = makemap |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
90 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
91 def gen(self): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
92 yield pycompat.bytestr(self._value) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
93 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
94 def tomap(self): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
95 return self._makemap(self._key) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
96 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
97 def itermaps(self): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
98 yield self.tomap() |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
99 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
100 def hybriddict(data, key='key', value='value', fmt=None, gen=None): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
101 """Wrap data to support both dict-like and string-like operations""" |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
102 prefmt = pycompat.identity |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
103 if fmt is None: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
104 fmt = '%s=%s' |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
105 prefmt = pycompat.bytestr |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
106 return hybrid(gen, data, lambda k: {key: k, value: data[k]}, |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
107 lambda k: fmt % (prefmt(k), prefmt(data[k]))) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
108 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
109 def hybridlist(data, name, fmt=None, gen=None): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
110 """Wrap data to support both list-like and string-like operations""" |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
111 prefmt = pycompat.identity |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
112 if fmt is None: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
113 fmt = '%s' |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
114 prefmt = pycompat.bytestr |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
115 return hybrid(gen, data, lambda x: {name: x}, lambda x: fmt % prefmt(x)) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
116 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
117 def unwraphybrid(thing): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
118 """Return an object which can be stringified possibly by using a legacy |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
119 template""" |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
120 gen = getattr(thing, 'gen', None) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
121 if gen is None: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
122 return thing |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
123 if callable(gen): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
124 return gen() |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
125 return gen |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
126 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
127 def unwrapvalue(thing): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
128 """Move the inner value object out of the wrapper""" |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
129 if not util.safehasattr(thing, '_value'): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
130 return thing |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
131 return thing._value |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
132 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
133 def wraphybridvalue(container, key, value): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
134 """Wrap an element of hybrid container to be mappable |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
135 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
136 The key is passed to the makemap function of the given container, which |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
137 should be an item generated by iter(container). |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
138 """ |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
139 makemap = getattr(container, '_makemap', None) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
140 if makemap is None: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
141 return value |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
142 if util.safehasattr(value, '_makemap'): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
143 # a nested hybrid list/dict, which has its own way of map operation |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
144 return value |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
145 return mappable(None, key, value, makemap) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
146 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
147 def compatdict(context, mapping, name, data, key='key', value='value', |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
148 fmt=None, plural=None, separator=' '): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
149 """Wrap data like hybriddict(), but also supports old-style list template |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
150 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
151 This exists for backward compatibility with the old-style template. Use |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
152 hybriddict() for new template keywords. |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
153 """ |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
154 c = [{key: k, value: v} for k, v in data.iteritems()] |
37854
aa97e06a1912
templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents:
37805
diff
changeset
|
155 f = _showcompatlist(context, mapping, name, c, plural, separator) |
37707
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
156 return hybriddict(data, key=key, value=value, fmt=fmt, gen=f) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
157 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
158 def compatlist(context, mapping, name, data, element=None, fmt=None, |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
159 plural=None, separator=' '): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
160 """Wrap data like hybridlist(), but also supports old-style list template |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
161 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
162 This exists for backward compatibility with the old-style template. Use |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
163 hybridlist() for new template keywords. |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
164 """ |
37854
aa97e06a1912
templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents:
37805
diff
changeset
|
165 f = _showcompatlist(context, mapping, name, data, plural, separator) |
37707
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
166 return hybridlist(data, name=element or name, fmt=fmt, gen=f) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
167 |
37854
aa97e06a1912
templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents:
37805
diff
changeset
|
168 def _showcompatlist(context, mapping, name, values, plural=None, separator=' '): |
aa97e06a1912
templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents:
37805
diff
changeset
|
169 """Return a generator that renders old-style list template |
aa97e06a1912
templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents:
37805
diff
changeset
|
170 |
37707
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
171 name is name of key in template map. |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
172 values is list of strings or dicts. |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
173 plural is plural of name, if not simply name + 's'. |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
174 separator is used to join values as a string |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
175 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
176 expansion works like this, given name 'foo'. |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
177 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
178 if values is empty, expand 'no_foos'. |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
179 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
180 if 'foo' not in template map, return values as a string, |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
181 joined by 'separator'. |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
182 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
183 expand 'start_foos'. |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
184 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
185 for each value, expand 'foo'. if 'last_foo' in template |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
186 map, expand it instead of 'foo' for last key. |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
187 |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
188 expand 'end_foos'. |
37854
aa97e06a1912
templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents:
37805
diff
changeset
|
189 """ |
37707
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
190 if not plural: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
191 plural = name + 's' |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
192 if not values: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
193 noname = 'no_' + plural |
37854
aa97e06a1912
templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents:
37805
diff
changeset
|
194 if context.preload(noname): |
aa97e06a1912
templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents:
37805
diff
changeset
|
195 yield context.process(noname, mapping) |
37707
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
196 return |
37854
aa97e06a1912
templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents:
37805
diff
changeset
|
197 if not context.preload(name): |
37707
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
198 if isinstance(values[0], bytes): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
199 yield separator.join(values) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
200 else: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
201 for v in values: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
202 r = dict(v) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
203 r.update(mapping) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
204 yield r |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
205 return |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
206 startname = 'start_' + plural |
37854
aa97e06a1912
templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents:
37805
diff
changeset
|
207 if context.preload(startname): |
aa97e06a1912
templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents:
37805
diff
changeset
|
208 yield context.process(startname, mapping) |
37707
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
209 def one(v, tag=name): |
37860
2891079fb0c0
templater: factor out function to create mapping dict for nested evaluation
Yuya Nishihara <yuya@tcha.org>
parents:
37859
diff
changeset
|
210 vmapping = {} |
37707
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
211 try: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
212 vmapping.update(v) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
213 # Python 2 raises ValueError if the type of v is wrong. Python |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
214 # 3 raises TypeError. |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
215 except (AttributeError, TypeError, ValueError): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
216 try: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
217 # Python 2 raises ValueError trying to destructure an e.g. |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
218 # bytes. Python 3 raises TypeError. |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
219 for a, b in v: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
220 vmapping[a] = b |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
221 except (TypeError, ValueError): |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
222 vmapping[name] = v |
37860
2891079fb0c0
templater: factor out function to create mapping dict for nested evaluation
Yuya Nishihara <yuya@tcha.org>
parents:
37859
diff
changeset
|
223 vmapping = context.overlaymap(mapping, vmapping) |
37854
aa97e06a1912
templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents:
37805
diff
changeset
|
224 return context.process(tag, vmapping) |
37707
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
225 lastname = 'last_' + name |
37854
aa97e06a1912
templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents:
37805
diff
changeset
|
226 if context.preload(lastname): |
37707
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
227 last = values.pop() |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
228 else: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
229 last = None |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
230 for v in values: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
231 yield one(v) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
232 if last is not None: |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
233 yield one(last, tag=lastname) |
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
234 endname = 'end_' + plural |
37854
aa97e06a1912
templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents:
37805
diff
changeset
|
235 if context.preload(endname): |
aa97e06a1912
templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents:
37805
diff
changeset
|
236 yield context.process(endname, mapping) |
37707
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
237 |
37943
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
238 def flatten(thing): |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
239 """Yield a single stream from a possibly nested set of iterators""" |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
240 thing = unwraphybrid(thing) |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
241 if isinstance(thing, bytes): |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
242 yield thing |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
243 elif isinstance(thing, str): |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
244 # We can only hit this on Python 3, and it's here to guard |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
245 # against infinite recursion. |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
246 raise error.ProgrammingError('Mercurial IO including templates is done' |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
247 ' with bytes, not strings, got %r' % thing) |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
248 elif thing is None: |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
249 pass |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
250 elif not util.safehasattr(thing, '__iter__'): |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
251 yield pycompat.bytestr(thing) |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
252 else: |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
253 for i in thing: |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
254 i = unwraphybrid(i) |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
255 if isinstance(i, bytes): |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
256 yield i |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
257 elif i is None: |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
258 pass |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
259 elif not util.safehasattr(i, '__iter__'): |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
260 yield pycompat.bytestr(i) |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
261 else: |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
262 for j in flatten(i): |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
263 yield j |
888507ec655e
templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents:
37890
diff
changeset
|
264 |
37706
6ff6e1d6b5b8
templater: move stringify() to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37699
diff
changeset
|
265 def stringify(thing): |
6ff6e1d6b5b8
templater: move stringify() to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37699
diff
changeset
|
266 """Turn values into bytes by converting into text and concatenating them""" |
37944
e09d2183e226
templateutil: reimplement stringify() using flatten()
Yuya Nishihara <yuya@tcha.org>
parents:
37943
diff
changeset
|
267 if isinstance(thing, bytes): |
e09d2183e226
templateutil: reimplement stringify() using flatten()
Yuya Nishihara <yuya@tcha.org>
parents:
37943
diff
changeset
|
268 return thing # retain localstr to be round-tripped |
e09d2183e226
templateutil: reimplement stringify() using flatten()
Yuya Nishihara <yuya@tcha.org>
parents:
37943
diff
changeset
|
269 return b''.join(flatten(thing)) |
37706
6ff6e1d6b5b8
templater: move stringify() to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37699
diff
changeset
|
270 |
32706
2abc556dbe92
templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents:
32705
diff
changeset
|
271 def findsymbolicname(arg): |
2abc556dbe92
templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents:
32705
diff
changeset
|
272 """Find symbolic name for the given compiled expression; returns None |
2abc556dbe92
templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents:
32705
diff
changeset
|
273 if nothing found reliably""" |
2abc556dbe92
templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents:
32705
diff
changeset
|
274 while True: |
2abc556dbe92
templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents:
32705
diff
changeset
|
275 func, data = arg |
2abc556dbe92
templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents:
32705
diff
changeset
|
276 if func is runsymbol: |
2abc556dbe92
templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents:
32705
diff
changeset
|
277 return data |
2abc556dbe92
templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents:
32705
diff
changeset
|
278 elif func is runfilter: |
2abc556dbe92
templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents:
32705
diff
changeset
|
279 arg = data[0] |
2abc556dbe92
templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents:
32705
diff
changeset
|
280 else: |
2abc556dbe92
templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents:
32705
diff
changeset
|
281 return None |
2abc556dbe92
templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents:
32705
diff
changeset
|
282 |
35109
e60c601953d7
templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents:
35108
diff
changeset
|
283 def evalrawexp(context, mapping, arg): |
e60c601953d7
templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents:
35108
diff
changeset
|
284 """Evaluate given argument as a bare template object which may require |
e60c601953d7
templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents:
35108
diff
changeset
|
285 further processing (such as folding generator of strings)""" |
26720
604a7c941103
templater: extract helper that evaluates filter or function argument
Yuya Nishihara <yuya@tcha.org>
parents:
26693
diff
changeset
|
286 func, data = arg |
35109
e60c601953d7
templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents:
35108
diff
changeset
|
287 return func(context, mapping, data) |
e60c601953d7
templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents:
35108
diff
changeset
|
288 |
e60c601953d7
templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents:
35108
diff
changeset
|
289 def evalfuncarg(context, mapping, arg): |
e60c601953d7
templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents:
35108
diff
changeset
|
290 """Evaluate given argument as value type""" |
37947
0023da2910c9
templater: extract type conversion from evalfuncarg()
Yuya Nishihara <yuya@tcha.org>
parents:
37946
diff
changeset
|
291 return _unwrapvalue(evalrawexp(context, mapping, arg)) |
0023da2910c9
templater: extract type conversion from evalfuncarg()
Yuya Nishihara <yuya@tcha.org>
parents:
37946
diff
changeset
|
292 |
0023da2910c9
templater: extract type conversion from evalfuncarg()
Yuya Nishihara <yuya@tcha.org>
parents:
37946
diff
changeset
|
293 # TODO: unify this with unwrapvalue() once the bug of templatefunc.join() |
0023da2910c9
templater: extract type conversion from evalfuncarg()
Yuya Nishihara <yuya@tcha.org>
parents:
37946
diff
changeset
|
294 # is fixed. we can't do that right now because join() has to take a generator |
0023da2910c9
templater: extract type conversion from evalfuncarg()
Yuya Nishihara <yuya@tcha.org>
parents:
37946
diff
changeset
|
295 # of byte strings as it is, not a lazy byte string. |
0023da2910c9
templater: extract type conversion from evalfuncarg()
Yuya Nishihara <yuya@tcha.org>
parents:
37946
diff
changeset
|
296 def _unwrapvalue(thing): |
37707
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
297 thing = unwrapvalue(thing) |
35109
e60c601953d7
templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents:
35108
diff
changeset
|
298 # evalrawexp() may return string, generator of strings or arbitrary object |
e60c601953d7
templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents:
35108
diff
changeset
|
299 # such as date tuple, but filter does not want generator. |
26720
604a7c941103
templater: extract helper that evaluates filter or function argument
Yuya Nishihara <yuya@tcha.org>
parents:
26693
diff
changeset
|
300 if isinstance(thing, types.GeneratorType): |
604a7c941103
templater: extract helper that evaluates filter or function argument
Yuya Nishihara <yuya@tcha.org>
parents:
26693
diff
changeset
|
301 thing = stringify(thing) |
604a7c941103
templater: extract helper that evaluates filter or function argument
Yuya Nishihara <yuya@tcha.org>
parents:
26693
diff
changeset
|
302 return thing |
604a7c941103
templater: extract helper that evaluates filter or function argument
Yuya Nishihara <yuya@tcha.org>
parents:
26693
diff
changeset
|
303 |
30586
034412ca28c3
templater: fix if() to not evaluate False as bool('False')
Yuya Nishihara <yuya@tcha.org>
parents:
30585
diff
changeset
|
304 def evalboolean(context, mapping, arg): |
30587
cc11079644fc
templater: make pad() evaluate boolean argument (BC)
Yuya Nishihara <yuya@tcha.org>
parents:
30586
diff
changeset
|
305 """Evaluate given argument as boolean, but also takes boolean literals""" |
30586
034412ca28c3
templater: fix if() to not evaluate False as bool('False')
Yuya Nishihara <yuya@tcha.org>
parents:
30585
diff
changeset
|
306 func, data = arg |
30587
cc11079644fc
templater: make pad() evaluate boolean argument (BC)
Yuya Nishihara <yuya@tcha.org>
parents:
30586
diff
changeset
|
307 if func is runsymbol: |
cc11079644fc
templater: make pad() evaluate boolean argument (BC)
Yuya Nishihara <yuya@tcha.org>
parents:
30586
diff
changeset
|
308 thing = func(context, mapping, data, default=None) |
cc11079644fc
templater: make pad() evaluate boolean argument (BC)
Yuya Nishihara <yuya@tcha.org>
parents:
30586
diff
changeset
|
309 if thing is None: |
cc11079644fc
templater: make pad() evaluate boolean argument (BC)
Yuya Nishihara <yuya@tcha.org>
parents:
30586
diff
changeset
|
310 # not a template keyword, takes as a boolean literal |
37870
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37860
diff
changeset
|
311 thing = stringutil.parsebool(data) |
30587
cc11079644fc
templater: make pad() evaluate boolean argument (BC)
Yuya Nishihara <yuya@tcha.org>
parents:
30586
diff
changeset
|
312 else: |
cc11079644fc
templater: make pad() evaluate boolean argument (BC)
Yuya Nishihara <yuya@tcha.org>
parents:
30586
diff
changeset
|
313 thing = func(context, mapping, data) |
37707
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
314 thing = unwrapvalue(thing) |
30586
034412ca28c3
templater: fix if() to not evaluate False as bool('False')
Yuya Nishihara <yuya@tcha.org>
parents:
30585
diff
changeset
|
315 if isinstance(thing, bool): |
034412ca28c3
templater: fix if() to not evaluate False as bool('False')
Yuya Nishihara <yuya@tcha.org>
parents:
30585
diff
changeset
|
316 return thing |
034412ca28c3
templater: fix if() to not evaluate False as bool('False')
Yuya Nishihara <yuya@tcha.org>
parents:
30585
diff
changeset
|
317 # other objects are evaluated as strings, which means 0 is True, but |
034412ca28c3
templater: fix if() to not evaluate False as bool('False')
Yuya Nishihara <yuya@tcha.org>
parents:
30585
diff
changeset
|
318 # empty dict/list should be False as they are expected to be '' |
034412ca28c3
templater: fix if() to not evaluate False as bool('False')
Yuya Nishihara <yuya@tcha.org>
parents:
30585
diff
changeset
|
319 return bool(stringify(thing)) |
034412ca28c3
templater: fix if() to not evaluate False as bool('False')
Yuya Nishihara <yuya@tcha.org>
parents:
30585
diff
changeset
|
320 |
35364
ee0d74083a22
templater: store revisions as ints so min/max won't compare them as strings
Yuya Nishihara <yuya@tcha.org>
parents:
35319
diff
changeset
|
321 def evalinteger(context, mapping, arg, err=None): |
37948
9ab3491f84c2
templater: extract unwrapinteger() function from evalinteger()
Yuya Nishihara <yuya@tcha.org>
parents:
37947
diff
changeset
|
322 return unwrapinteger(evalrawexp(context, mapping, arg), err) |
9ab3491f84c2
templater: extract unwrapinteger() function from evalinteger()
Yuya Nishihara <yuya@tcha.org>
parents:
37947
diff
changeset
|
323 |
9ab3491f84c2
templater: extract unwrapinteger() function from evalinteger()
Yuya Nishihara <yuya@tcha.org>
parents:
37947
diff
changeset
|
324 def unwrapinteger(thing, err=None): |
9ab3491f84c2
templater: extract unwrapinteger() function from evalinteger()
Yuya Nishihara <yuya@tcha.org>
parents:
37947
diff
changeset
|
325 thing = _unwrapvalue(thing) |
29014
a6c2310b3827
templater: factor out function that evaluates argument as integer
Yuya Nishihara <yuya@tcha.org>
parents:
29005
diff
changeset
|
326 try: |
37948
9ab3491f84c2
templater: extract unwrapinteger() function from evalinteger()
Yuya Nishihara <yuya@tcha.org>
parents:
37947
diff
changeset
|
327 return int(thing) |
29015
ac371d4c007f
templater: drop redundant type conversion when evaluating integer argument
Yuya Nishihara <yuya@tcha.org>
parents:
29014
diff
changeset
|
328 except (TypeError, ValueError): |
35364
ee0d74083a22
templater: store revisions as ints so min/max won't compare them as strings
Yuya Nishihara <yuya@tcha.org>
parents:
35319
diff
changeset
|
329 raise error.ParseError(err or _('not an integer')) |
29014
a6c2310b3827
templater: factor out function that evaluates argument as integer
Yuya Nishihara <yuya@tcha.org>
parents:
29005
diff
changeset
|
330 |
29019
ccedb17a5657
templater: factor out thin helper that evaluates argument as string
Yuya Nishihara <yuya@tcha.org>
parents:
29017
diff
changeset
|
331 def evalstring(context, mapping, arg): |
35109
e60c601953d7
templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents:
35108
diff
changeset
|
332 return stringify(evalrawexp(context, mapping, arg)) |
29019
ccedb17a5657
templater: factor out thin helper that evaluates argument as string
Yuya Nishihara <yuya@tcha.org>
parents:
29017
diff
changeset
|
333 |
29044
9a9dd71e882c
templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents:
29020
diff
changeset
|
334 def evalstringliteral(context, mapping, arg): |
9a9dd71e882c
templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents:
29020
diff
changeset
|
335 """Evaluate given argument as string template, but returns symbol name |
9a9dd71e882c
templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents:
29020
diff
changeset
|
336 if it is unknown""" |
9a9dd71e882c
templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents:
29020
diff
changeset
|
337 func, data = arg |
9a9dd71e882c
templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents:
29020
diff
changeset
|
338 if func is runsymbol: |
9a9dd71e882c
templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents:
29020
diff
changeset
|
339 thing = func(context, mapping, data, default=data) |
9a9dd71e882c
templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents:
29020
diff
changeset
|
340 else: |
9a9dd71e882c
templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents:
29020
diff
changeset
|
341 thing = func(context, mapping, data) |
9a9dd71e882c
templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents:
29020
diff
changeset
|
342 return stringify(thing) |
9a9dd71e882c
templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents:
29020
diff
changeset
|
343 |
37949
0fb28899e81a
templater: factor out unwrapastype() from evalastype()
Yuya Nishihara <yuya@tcha.org>
parents:
37948
diff
changeset
|
344 _unwrapfuncbytype = { |
38008
54355c243042
templatefilters: allow declaration of input data type
Yuya Nishihara <yuya@tcha.org>
parents:
37949
diff
changeset
|
345 None: _unwrapvalue, |
37949
0fb28899e81a
templater: factor out unwrapastype() from evalastype()
Yuya Nishihara <yuya@tcha.org>
parents:
37948
diff
changeset
|
346 bytes: stringify, |
0fb28899e81a
templater: factor out unwrapastype() from evalastype()
Yuya Nishihara <yuya@tcha.org>
parents:
37948
diff
changeset
|
347 int: unwrapinteger, |
35364
ee0d74083a22
templater: store revisions as ints so min/max won't compare them as strings
Yuya Nishihara <yuya@tcha.org>
parents:
35319
diff
changeset
|
348 } |
ee0d74083a22
templater: store revisions as ints so min/max won't compare them as strings
Yuya Nishihara <yuya@tcha.org>
parents:
35319
diff
changeset
|
349 |
37949
0fb28899e81a
templater: factor out unwrapastype() from evalastype()
Yuya Nishihara <yuya@tcha.org>
parents:
37948
diff
changeset
|
350 def unwrapastype(thing, typ): |
0fb28899e81a
templater: factor out unwrapastype() from evalastype()
Yuya Nishihara <yuya@tcha.org>
parents:
37948
diff
changeset
|
351 """Move the inner value object out of the wrapper and coerce its type""" |
35364
ee0d74083a22
templater: store revisions as ints so min/max won't compare them as strings
Yuya Nishihara <yuya@tcha.org>
parents:
35319
diff
changeset
|
352 try: |
37949
0fb28899e81a
templater: factor out unwrapastype() from evalastype()
Yuya Nishihara <yuya@tcha.org>
parents:
37948
diff
changeset
|
353 f = _unwrapfuncbytype[typ] |
35364
ee0d74083a22
templater: store revisions as ints so min/max won't compare them as strings
Yuya Nishihara <yuya@tcha.org>
parents:
35319
diff
changeset
|
354 except KeyError: |
ee0d74083a22
templater: store revisions as ints so min/max won't compare them as strings
Yuya Nishihara <yuya@tcha.org>
parents:
35319
diff
changeset
|
355 raise error.ProgrammingError('invalid type specified: %r' % typ) |
37949
0fb28899e81a
templater: factor out unwrapastype() from evalastype()
Yuya Nishihara <yuya@tcha.org>
parents:
37948
diff
changeset
|
356 return f(thing) |
35364
ee0d74083a22
templater: store revisions as ints so min/max won't compare them as strings
Yuya Nishihara <yuya@tcha.org>
parents:
35319
diff
changeset
|
357 |
25393
829faf8ab605
templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents:
25392
diff
changeset
|
358 def runinteger(context, mapping, data): |
829faf8ab605
templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents:
25392
diff
changeset
|
359 return int(data) |
829faf8ab605
templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents:
25392
diff
changeset
|
360 |
13177
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
361 def runstring(context, mapping, data): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
362 return data |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
363 |
28610
7ed3a3c0cef1
templater: abort if infinite recursion detected while evaluation (issue4758)
Yuya Nishihara <yuya@tcha.org>
parents:
28547
diff
changeset
|
364 def _recursivesymbolblocker(key): |
7ed3a3c0cef1
templater: abort if infinite recursion detected while evaluation (issue4758)
Yuya Nishihara <yuya@tcha.org>
parents:
28547
diff
changeset
|
365 def showrecursion(**args): |
7ed3a3c0cef1
templater: abort if infinite recursion detected while evaluation (issue4758)
Yuya Nishihara <yuya@tcha.org>
parents:
28547
diff
changeset
|
366 raise error.Abort(_("recursive reference '%s' in template") % key) |
7ed3a3c0cef1
templater: abort if infinite recursion detected while evaluation (issue4758)
Yuya Nishihara <yuya@tcha.org>
parents:
28547
diff
changeset
|
367 return showrecursion |
7ed3a3c0cef1
templater: abort if infinite recursion detected while evaluation (issue4758)
Yuya Nishihara <yuya@tcha.org>
parents:
28547
diff
changeset
|
368 |
29044
9a9dd71e882c
templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents:
29020
diff
changeset
|
369 def runsymbol(context, mapping, key, default=''): |
36250
d6cfa722b044
templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents:
36197
diff
changeset
|
370 v = context.symbol(mapping, key) |
19770
0361163efbaf
templater: support using templates with non-standard names from map file
Alexander Plavin <alexander@plav.in>
parents:
19390
diff
changeset
|
371 if v is None: |
28610
7ed3a3c0cef1
templater: abort if infinite recursion detected while evaluation (issue4758)
Yuya Nishihara <yuya@tcha.org>
parents:
28547
diff
changeset
|
372 # put poison to cut recursion. we can't move this to parsing phase |
7ed3a3c0cef1
templater: abort if infinite recursion detected while evaluation (issue4758)
Yuya Nishihara <yuya@tcha.org>
parents:
28547
diff
changeset
|
373 # because "x = {x}" is allowed if "x" is a keyword. (issue4758) |
7ed3a3c0cef1
templater: abort if infinite recursion detected while evaluation (issue4758)
Yuya Nishihara <yuya@tcha.org>
parents:
28547
diff
changeset
|
374 safemapping = mapping.copy() |
7ed3a3c0cef1
templater: abort if infinite recursion detected while evaluation (issue4758)
Yuya Nishihara <yuya@tcha.org>
parents:
28547
diff
changeset
|
375 safemapping[key] = _recursivesymbolblocker(key) |
19770
0361163efbaf
templater: support using templates with non-standard names from map file
Alexander Plavin <alexander@plav.in>
parents:
19390
diff
changeset
|
376 try: |
28610
7ed3a3c0cef1
templater: abort if infinite recursion detected while evaluation (issue4758)
Yuya Nishihara <yuya@tcha.org>
parents:
28547
diff
changeset
|
377 v = context.process(key, safemapping) |
19770
0361163efbaf
templater: support using templates with non-standard names from map file
Alexander Plavin <alexander@plav.in>
parents:
19390
diff
changeset
|
378 except TemplateNotFound: |
29044
9a9dd71e882c
templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents:
29020
diff
changeset
|
379 v = default |
37231
e8d37838f5df
templatekw: add 'requires' flag to switch to exception-safe interface
Yuya Nishihara <yuya@tcha.org>
parents:
37230
diff
changeset
|
380 if callable(v) and getattr(v, '_requires', None) is None: |
e8d37838f5df
templatekw: add 'requires' flag to switch to exception-safe interface
Yuya Nishihara <yuya@tcha.org>
parents:
37230
diff
changeset
|
381 # old templatekw: expand all keywords and resources |
37856
1101d6747d2d
templater: drop 'templ' from resources dict
Yuya Nishihara <yuya@tcha.org>
parents:
37854
diff
changeset
|
382 # (TODO: deprecate this after porting web template keywords to new API) |
37859
44757e6dad93
templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents:
37856
diff
changeset
|
383 props = {k: context._resources.lookup(context, mapping, k) |
44757e6dad93
templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents:
37856
diff
changeset
|
384 for k in context._resources.knownkeys()} |
37856
1101d6747d2d
templater: drop 'templ' from resources dict
Yuya Nishihara <yuya@tcha.org>
parents:
37854
diff
changeset
|
385 # pass context to _showcompatlist() through templatekw._showlist() |
1101d6747d2d
templater: drop 'templ' from resources dict
Yuya Nishihara <yuya@tcha.org>
parents:
37854
diff
changeset
|
386 props['templ'] = context |
36251
32c278eb876f
templater: keep default resources per template engine (API)
Yuya Nishihara <yuya@tcha.org>
parents:
36250
diff
changeset
|
387 props.update(mapping) |
36374
dadbf213a765
py3: convert dict keys' to str before passing as kwargs
Pulkit Goyal <7895pulkit@gmail.com>
parents:
36264
diff
changeset
|
388 return v(**pycompat.strkwargs(props)) |
37231
e8d37838f5df
templatekw: add 'requires' flag to switch to exception-safe interface
Yuya Nishihara <yuya@tcha.org>
parents:
37230
diff
changeset
|
389 if callable(v): |
e8d37838f5df
templatekw: add 'requires' flag to switch to exception-safe interface
Yuya Nishihara <yuya@tcha.org>
parents:
37230
diff
changeset
|
390 # new templatekw |
e8d37838f5df
templatekw: add 'requires' flag to switch to exception-safe interface
Yuya Nishihara <yuya@tcha.org>
parents:
37230
diff
changeset
|
391 try: |
e8d37838f5df
templatekw: add 'requires' flag to switch to exception-safe interface
Yuya Nishihara <yuya@tcha.org>
parents:
37230
diff
changeset
|
392 return v(context, mapping) |
e8d37838f5df
templatekw: add 'requires' flag to switch to exception-safe interface
Yuya Nishihara <yuya@tcha.org>
parents:
37230
diff
changeset
|
393 except ResourceUnavailable: |
e8d37838f5df
templatekw: add 'requires' flag to switch to exception-safe interface
Yuya Nishihara <yuya@tcha.org>
parents:
37230
diff
changeset
|
394 # unsupported keyword is mapped to empty just like unknown keyword |
e8d37838f5df
templatekw: add 'requires' flag to switch to exception-safe interface
Yuya Nishihara <yuya@tcha.org>
parents:
37230
diff
changeset
|
395 return None |
13177
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
396 return v |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
397 |
26138
a7dd6692e5cb
templater: move runtemplate function out of buildmap/runmap pair
Yuya Nishihara <yuya@tcha.org>
parents:
26123
diff
changeset
|
398 def runtemplate(context, mapping, template): |
35109
e60c601953d7
templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents:
35108
diff
changeset
|
399 for arg in template: |
e60c601953d7
templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents:
35108
diff
changeset
|
400 yield evalrawexp(context, mapping, arg) |
26138
a7dd6692e5cb
templater: move runtemplate function out of buildmap/runmap pair
Yuya Nishihara <yuya@tcha.org>
parents:
26123
diff
changeset
|
401 |
13177
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
402 def runfilter(context, mapping, data): |
26721
c990afab2243
templater: drop unneeded destructuring of argument tuple at buildfilter
Yuya Nishihara <yuya@tcha.org>
parents:
26720
diff
changeset
|
403 arg, filt = data |
38008
54355c243042
templatefilters: allow declaration of input data type
Yuya Nishihara <yuya@tcha.org>
parents:
37949
diff
changeset
|
404 thing = evalrawexp(context, mapping, arg) |
17383
099c778ceb33
templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents:
17334
diff
changeset
|
405 try: |
38008
54355c243042
templatefilters: allow declaration of input data type
Yuya Nishihara <yuya@tcha.org>
parents:
37949
diff
changeset
|
406 thing = unwrapastype(thing, getattr(filt, '_intype', None)) |
24387
6c55e37ba5f2
templater: allow piping generator-type function output to filters
Yuya Nishihara <yuya@tcha.org>
parents:
24342
diff
changeset
|
407 return filt(thing) |
17383
099c778ceb33
templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents:
17334
diff
changeset
|
408 except (ValueError, AttributeError, TypeError): |
32706
2abc556dbe92
templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents:
32705
diff
changeset
|
409 sym = findsymbolicname(arg) |
2abc556dbe92
templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents:
32705
diff
changeset
|
410 if sym: |
2abc556dbe92
templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents:
32705
diff
changeset
|
411 msg = (_("template filter '%s' is not compatible with keyword '%s'") |
35621
d3ea6a1c798f
templater: use pycompat.sysbytes to bytes-ify some __name__ attrs
Augie Fackler <augie@google.com>
parents:
35591
diff
changeset
|
412 % (pycompat.sysbytes(filt.__name__), sym)) |
17383
099c778ceb33
templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents:
17334
diff
changeset
|
413 else: |
35621
d3ea6a1c798f
templater: use pycompat.sysbytes to bytes-ify some __name__ attrs
Augie Fackler <augie@google.com>
parents:
35591
diff
changeset
|
414 msg = (_("incompatible use of template filter '%s'") |
d3ea6a1c798f
templater: use pycompat.sysbytes to bytes-ify some __name__ attrs
Augie Fackler <augie@google.com>
parents:
35591
diff
changeset
|
415 % pycompat.sysbytes(filt.__name__)) |
32706
2abc556dbe92
templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents:
32705
diff
changeset
|
416 raise error.Abort(msg) |
13177
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
417 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
418 def runmap(context, mapping, data): |
35109
e60c601953d7
templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents:
35108
diff
changeset
|
419 darg, targ = data |
e60c601953d7
templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents:
35108
diff
changeset
|
420 d = evalrawexp(context, mapping, darg) |
28546
ac8c0ee5c3b8
templater: make _hybrid not callable to avoid conflicting semantics
Yuya Nishihara <yuya@tcha.org>
parents:
28292
diff
changeset
|
421 if util.safehasattr(d, 'itermaps'): |
29020
7cb2f2438f85
templater: handle exception when applying map operator to non-iterable object
Yuya Nishihara <yuya@tcha.org>
parents:
29019
diff
changeset
|
422 diter = d.itermaps() |
7cb2f2438f85
templater: handle exception when applying map operator to non-iterable object
Yuya Nishihara <yuya@tcha.org>
parents:
29019
diff
changeset
|
423 else: |
7cb2f2438f85
templater: handle exception when applying map operator to non-iterable object
Yuya Nishihara <yuya@tcha.org>
parents:
29019
diff
changeset
|
424 try: |
7cb2f2438f85
templater: handle exception when applying map operator to non-iterable object
Yuya Nishihara <yuya@tcha.org>
parents:
29019
diff
changeset
|
425 diter = iter(d) |
7cb2f2438f85
templater: handle exception when applying map operator to non-iterable object
Yuya Nishihara <yuya@tcha.org>
parents:
29019
diff
changeset
|
426 except TypeError: |
35109
e60c601953d7
templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents:
35108
diff
changeset
|
427 sym = findsymbolicname(darg) |
35107
e473f482b9b3
templater: use helper function to get name of non-iterable keyword
Yuya Nishihara <yuya@tcha.org>
parents:
35070
diff
changeset
|
428 if sym: |
e473f482b9b3
templater: use helper function to get name of non-iterable keyword
Yuya Nishihara <yuya@tcha.org>
parents:
35070
diff
changeset
|
429 raise error.ParseError(_("keyword '%s' is not iterable") % sym) |
29020
7cb2f2438f85
templater: handle exception when applying map operator to non-iterable object
Yuya Nishihara <yuya@tcha.org>
parents:
29019
diff
changeset
|
430 else: |
7cb2f2438f85
templater: handle exception when applying map operator to non-iterable object
Yuya Nishihara <yuya@tcha.org>
parents:
29019
diff
changeset
|
431 raise error.ParseError(_("%r is not iterable") % d) |
17631
0b241d7a8c62
templating: make new-style templating features work with command line lists
Matt Mackall <mpm@selenic.com>
parents:
17383
diff
changeset
|
432 |
32586
e6eb86b154c5
templater: provide loop counter as "index" keyword
Yuya Nishihara <yuya@tcha.org>
parents:
32585
diff
changeset
|
433 for i, v in enumerate(diter): |
32585
8f203b491bb5
templater: rename variable "i" to "v" in runmap()
Yuya Nishihara <yuya@tcha.org>
parents:
32300
diff
changeset
|
434 if isinstance(v, dict): |
37860
2891079fb0c0
templater: factor out function to create mapping dict for nested evaluation
Yuya Nishihara <yuya@tcha.org>
parents:
37859
diff
changeset
|
435 lm = context.overlaymap(mapping, v) |
2891079fb0c0
templater: factor out function to create mapping dict for nested evaluation
Yuya Nishihara <yuya@tcha.org>
parents:
37859
diff
changeset
|
436 lm['index'] = i |
35109
e60c601953d7
templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents:
35108
diff
changeset
|
437 yield evalrawexp(context, lm, targ) |
13177
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
438 else: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
439 # v is not an iterable of dicts, this happen when 'key' |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
440 # has been fully expanded already and format is useless. |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
441 # If so, return the expanded value. |
32585
8f203b491bb5
templater: rename variable "i" to "v" in runmap()
Yuya Nishihara <yuya@tcha.org>
parents:
32300
diff
changeset
|
442 yield v |
13177
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
443 |
35318
78590585c0db
templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents:
35317
diff
changeset
|
444 def runmember(context, mapping, data): |
78590585c0db
templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents:
35317
diff
changeset
|
445 darg, memb = data |
78590585c0db
templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents:
35317
diff
changeset
|
446 d = evalrawexp(context, mapping, darg) |
78590585c0db
templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents:
35317
diff
changeset
|
447 if util.safehasattr(d, 'tomap'): |
37860
2891079fb0c0
templater: factor out function to create mapping dict for nested evaluation
Yuya Nishihara <yuya@tcha.org>
parents:
37859
diff
changeset
|
448 lm = context.overlaymap(mapping, d.tomap()) |
35318
78590585c0db
templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents:
35317
diff
changeset
|
449 return runsymbol(context, lm, memb) |
35319
4c1cfe54c08d
templater: extend dot operator as a short for get(dict, key)
Yuya Nishihara <yuya@tcha.org>
parents:
35318
diff
changeset
|
450 if util.safehasattr(d, 'get'): |
37699
da2977e674a3
templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37698
diff
changeset
|
451 return getdictitem(d, memb) |
35318
78590585c0db
templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents:
35317
diff
changeset
|
452 |
78590585c0db
templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents:
35317
diff
changeset
|
453 sym = findsymbolicname(darg) |
78590585c0db
templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents:
35317
diff
changeset
|
454 if sym: |
78590585c0db
templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents:
35317
diff
changeset
|
455 raise error.ParseError(_("keyword '%s' has no member") % sym) |
78590585c0db
templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents:
35317
diff
changeset
|
456 else: |
37331
ab7f86a748e6
py3: drop b'' from error message generated by templater.runmember()
Yuya Nishihara <yuya@tcha.org>
parents:
37330
diff
changeset
|
457 raise error.ParseError(_("%r has no member") % pycompat.bytestr(d)) |
35318
78590585c0db
templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents:
35317
diff
changeset
|
458 |
30894
8e42dfde93d1
templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents:
30862
diff
changeset
|
459 def runnegate(context, mapping, data): |
8e42dfde93d1
templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents:
30862
diff
changeset
|
460 data = evalinteger(context, mapping, data, |
8e42dfde93d1
templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents:
30862
diff
changeset
|
461 _('negation needs an integer argument')) |
8e42dfde93d1
templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents:
30862
diff
changeset
|
462 return -data |
8e42dfde93d1
templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents:
30862
diff
changeset
|
463 |
8e42dfde93d1
templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents:
30862
diff
changeset
|
464 def runarithmetic(context, mapping, data): |
8e42dfde93d1
templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents:
30862
diff
changeset
|
465 func, left, right = data |
8e42dfde93d1
templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents:
30862
diff
changeset
|
466 left = evalinteger(context, mapping, left, |
8e42dfde93d1
templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents:
30862
diff
changeset
|
467 _('arithmetic only defined on integers')) |
8e42dfde93d1
templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents:
30862
diff
changeset
|
468 right = evalinteger(context, mapping, right, |
8e42dfde93d1
templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents:
30862
diff
changeset
|
469 _('arithmetic only defined on integers')) |
30895
1c01fa29630f
templater: handle division by zero in arithmetic
Simon Farnsworth <simonfar@fb.com>
parents:
30894
diff
changeset
|
470 try: |
1c01fa29630f
templater: handle division by zero in arithmetic
Simon Farnsworth <simonfar@fb.com>
parents:
30894
diff
changeset
|
471 return func(left, right) |
1c01fa29630f
templater: handle division by zero in arithmetic
Simon Farnsworth <simonfar@fb.com>
parents:
30894
diff
changeset
|
472 except ZeroDivisionError: |
1c01fa29630f
templater: handle division by zero in arithmetic
Simon Farnsworth <simonfar@fb.com>
parents:
30894
diff
changeset
|
473 raise error.Abort(_('division by zero is not defined')) |
30894
8e42dfde93d1
templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents:
30862
diff
changeset
|
474 |
37699
da2977e674a3
templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37698
diff
changeset
|
475 def getdictitem(dictarg, key): |
35317
b3073e175c17
templater: wrap get/min/max result so map operation can apply to element
Yuya Nishihara <yuya@tcha.org>
parents:
35241
diff
changeset
|
476 val = dictarg.get(key) |
b3073e175c17
templater: wrap get/min/max result so map operation can apply to element
Yuya Nishihara <yuya@tcha.org>
parents:
35241
diff
changeset
|
477 if val is None: |
b3073e175c17
templater: wrap get/min/max result so map operation can apply to element
Yuya Nishihara <yuya@tcha.org>
parents:
35241
diff
changeset
|
478 return |
37707
32f9b7e3f056
templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents:
37706
diff
changeset
|
479 return wraphybridvalue(dictarg, key, val) |