annotate mercurial/templateutil.py @ 43679:7cf332318f62

encoding: make getcols() raise exception explicitly This helps pytype. File "mercurial/encoding.py", line 329, in getcols: bad option in return type [bad-return-type] Expected: bytes Actually returned: None
author Yuya Nishihara <yuya@tcha.org>
date Sat, 16 Nov 2019 15:43:21 +0900
parents 70d42e2ad9b4
children fc1fa3a07af6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
36913
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36912
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
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9842
diff changeset
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
36913
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36912
diff changeset
8 from __future__ import absolute_import
25985
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
9
37273
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
10 import abc
17982
e06e9fd2d99f template engine: convert generator-based iterator to list-based iterator
Weiwen <weiwen@fb.com>
parents: 17890
diff changeset
11 import types
25985
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
12
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
13 from .i18n import _
43089
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
14 from .pycompat import getattr
25985
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
15 from . import (
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
16 error,
30615
bb77654dc7ae py3: replace os.sep with pycompat.ossep (part 3 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30332
diff changeset
17 pycompat,
25985
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
18 util,
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
19 )
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
20 from .utils import (
37224
67efce231633 templater: factor out function that parses argument as date tuple
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
21 dateutil,
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
22 stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
23 )
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
24
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
25
36444
717a279c0c21 templater: specialize ResourceUnavailable error so that it can be caught
Yuya Nishihara <yuya@tcha.org>
parents: 36443
diff changeset
26 class ResourceUnavailable(error.Abort):
717a279c0c21 templater: specialize ResourceUnavailable error so that it can be caught
Yuya Nishihara <yuya@tcha.org>
parents: 36443
diff changeset
27 pass
717a279c0c21 templater: specialize ResourceUnavailable error so that it can be caught
Yuya Nishihara <yuya@tcha.org>
parents: 36443
diff changeset
28
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
29
36443
8dbd97aef915 templater: move specialized exception types to top
Yuya Nishihara <yuya@tcha.org>
parents: 36245
diff changeset
30 class TemplateNotFound(error.Abort):
8dbd97aef915 templater: move specialized exception types to top
Yuya Nishihara <yuya@tcha.org>
parents: 36245
diff changeset
31 pass
8dbd97aef915 templater: move specialized exception types to top
Yuya Nishihara <yuya@tcha.org>
parents: 36245
diff changeset
32
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
33
43474
70d42e2ad9b4 pytype: don't warn us about ignored-on-py3 metaclasses
Augie Fackler <augie@google.com>
parents: 43464
diff changeset
34 class wrapped(object): # pytype: disable=ignored-metaclass
37273
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
35 """Object requiring extra conversion prior to displaying or processing
37279
26f6fc179e62 templater: define interface for objects requiring unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 37278
diff changeset
36 as value
26f6fc179e62 templater: define interface for objects requiring unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 37278
diff changeset
37
38270
630c62804383 templater: inline unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 38269
diff changeset
38 Use unwrapvalue() or unwrapastype() to obtain the inner object.
37279
26f6fc179e62 templater: define interface for objects requiring unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 37278
diff changeset
39 """
37273
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
40
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
41 __metaclass__ = abc.ABCMeta
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
42
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
43 @abc.abstractmethod
38267
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
44 def contains(self, context, mapping, item):
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
45 """Test if the specified item is in self
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
46
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
47 The item argument may be a wrapped object.
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
48 """
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
49
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
50 @abc.abstractmethod
38243
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
51 def getmember(self, context, mapping, key):
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
52 """Return a member item for the specified key
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
53
38244
688fbb758ba9 templater: resolve type of dict key in getmember()
Yuya Nishihara <yuya@tcha.org>
parents: 38243
diff changeset
54 The key argument may be a wrapped object.
38243
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
55 A returned object may be either a wrapped object or a pure value
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
56 depending on the self type.
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
57 """
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
58
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
59 @abc.abstractmethod
38265
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
60 def getmin(self, context, mapping):
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
61 """Return the smallest item, which may be either a wrapped or a pure
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
62 value depending on the self type"""
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
63
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
64 @abc.abstractmethod
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
65 def getmax(self, context, mapping):
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
66 """Return the largest item, which may be either a wrapped or a pure
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
67 value depending on the self type"""
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
68
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
69 @abc.abstractmethod
38448
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
70 def filter(self, context, mapping, select):
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
71 """Return new container of the same type which includes only the
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
72 selected elements
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
73
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
74 select() takes each item as a wrapped object and returns True/False.
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
75 """
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
76
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
77 @abc.abstractmethod
37324
c2f74b8f6b7f templater: pass context to itermaps() for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 37323
diff changeset
78 def itermaps(self, context):
37323
8c31b434697f templater: define interface for objects which act as iterator of mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37279
diff changeset
79 """Yield each template mapping"""
8c31b434697f templater: define interface for objects which act as iterator of mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37279
diff changeset
80
8c31b434697f templater: define interface for objects which act as iterator of mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37279
diff changeset
81 @abc.abstractmethod
37327
ebf139cbd4a1 templater: abstract away from joinfmt
Yuya Nishihara <yuya@tcha.org>
parents: 37326
diff changeset
82 def join(self, context, mapping, sep):
ebf139cbd4a1 templater: abstract away from joinfmt
Yuya Nishihara <yuya@tcha.org>
parents: 37326
diff changeset
83 """Join items with the separator; Returns a bytes or (possibly nested)
ebf139cbd4a1 templater: abstract away from joinfmt
Yuya Nishihara <yuya@tcha.org>
parents: 37326
diff changeset
84 generator of bytes
ebf139cbd4a1 templater: abstract away from joinfmt
Yuya Nishihara <yuya@tcha.org>
parents: 37326
diff changeset
85
ebf139cbd4a1 templater: abstract away from joinfmt
Yuya Nishihara <yuya@tcha.org>
parents: 37326
diff changeset
86 A pre-configured template may be rendered per item if this container
ebf139cbd4a1 templater: abstract away from joinfmt
Yuya Nishihara <yuya@tcha.org>
parents: 37326
diff changeset
87 holds unprintable items.
ebf139cbd4a1 templater: abstract away from joinfmt
Yuya Nishihara <yuya@tcha.org>
parents: 37326
diff changeset
88 """
ebf139cbd4a1 templater: abstract away from joinfmt
Yuya Nishihara <yuya@tcha.org>
parents: 37326
diff changeset
89
ebf139cbd4a1 templater: abstract away from joinfmt
Yuya Nishihara <yuya@tcha.org>
parents: 37326
diff changeset
90 @abc.abstractmethod
37273
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
91 def show(self, context, mapping):
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
92 """Return a bytes or (possibly nested) generator of bytes representing
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
93 the underlying object
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
94
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
95 A pre-configured template may be rendered if the underlying object is
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
96 not printable.
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
97 """
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
98
37279
26f6fc179e62 templater: define interface for objects requiring unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 37278
diff changeset
99 @abc.abstractmethod
38289
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
100 def tobool(self, context, mapping):
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
101 """Return a boolean representation of the inner value"""
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
102
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
103 @abc.abstractmethod
37279
26f6fc179e62 templater: define interface for objects requiring unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 37278
diff changeset
104 def tovalue(self, context, mapping):
26f6fc179e62 templater: define interface for objects requiring unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 37278
diff changeset
105 """Move the inner value object out or create a value representation
26f6fc179e62 templater: define interface for objects requiring unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 37278
diff changeset
106
26f6fc179e62 templater: define interface for objects requiring unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 37278
diff changeset
107 A returned value must be serializable by templaterfilters.json().
26f6fc179e62 templater: define interface for objects requiring unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 37278
diff changeset
108 """
26f6fc179e62 templater: define interface for objects requiring unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 37278
diff changeset
109
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
110
43474
70d42e2ad9b4 pytype: don't warn us about ignored-on-py3 metaclasses
Augie Fackler <augie@google.com>
parents: 43464
diff changeset
111 class mappable(object): # pytype: disable=ignored-metaclass
38284
e72697893c93 templater: promote tomap() to an interface type
Yuya Nishihara <yuya@tcha.org>
parents: 38283
diff changeset
112 """Object which can be converted to a single template mapping"""
e72697893c93 templater: promote tomap() to an interface type
Yuya Nishihara <yuya@tcha.org>
parents: 38283
diff changeset
113
43464
3e57809d3251 templateutil: fix a missing ABCMeta assignment
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
114 __metaclass__ = abc.ABCMeta
3e57809d3251 templateutil: fix a missing ABCMeta assignment
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
115
38284
e72697893c93 templater: promote tomap() to an interface type
Yuya Nishihara <yuya@tcha.org>
parents: 38283
diff changeset
116 def itermaps(self, context):
e72697893c93 templater: promote tomap() to an interface type
Yuya Nishihara <yuya@tcha.org>
parents: 38283
diff changeset
117 yield self.tomap(context)
e72697893c93 templater: promote tomap() to an interface type
Yuya Nishihara <yuya@tcha.org>
parents: 38283
diff changeset
118
e72697893c93 templater: promote tomap() to an interface type
Yuya Nishihara <yuya@tcha.org>
parents: 38283
diff changeset
119 @abc.abstractmethod
e72697893c93 templater: promote tomap() to an interface type
Yuya Nishihara <yuya@tcha.org>
parents: 38283
diff changeset
120 def tomap(self, context):
e72697893c93 templater: promote tomap() to an interface type
Yuya Nishihara <yuya@tcha.org>
parents: 38283
diff changeset
121 """Create a single template mapping representing this"""
e72697893c93 templater: promote tomap() to an interface type
Yuya Nishihara <yuya@tcha.org>
parents: 38283
diff changeset
122
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
123
38226
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
124 class wrappedbytes(wrapped):
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
125 """Wrapper for byte string"""
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
126
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
127 def __init__(self, value):
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
128 self._value = value
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
129
38267
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
130 def contains(self, context, mapping, item):
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
131 item = stringify(context, mapping, item)
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
132 return item in self._value
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
133
38243
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
134 def getmember(self, context, mapping, key):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
135 raise error.ParseError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
136 _(b'%r is not a dictionary') % pycompat.bytestr(self._value)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
137 )
38243
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
138
38265
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
139 def getmin(self, context, mapping):
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
140 return self._getby(context, mapping, min)
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
141
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
142 def getmax(self, context, mapping):
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
143 return self._getby(context, mapping, max)
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
144
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
145 def _getby(self, context, mapping, func):
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
146 if not self._value:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
147 raise error.ParseError(_(b'empty string'))
38265
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
148 return func(pycompat.iterbytestr(self._value))
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
149
38448
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
150 def filter(self, context, mapping, select):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
151 raise error.ParseError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
152 _(b'%r is not filterable') % pycompat.bytestr(self._value)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
153 )
38448
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
154
38226
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
155 def itermaps(self, context):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
156 raise error.ParseError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
157 _(b'%r is not iterable of mappings') % pycompat.bytestr(self._value)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
158 )
38226
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
159
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
160 def join(self, context, mapping, sep):
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
161 return joinitems(pycompat.iterbytestr(self._value), sep)
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
162
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
163 def show(self, context, mapping):
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
164 return self._value
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
165
38289
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
166 def tobool(self, context, mapping):
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
167 return bool(self._value)
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
168
38226
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
169 def tovalue(self, context, mapping):
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
170 return self._value
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
171
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
172
38226
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
173 class wrappedvalue(wrapped):
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
174 """Generic wrapper for pure non-list/dict/bytes value"""
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
175
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
176 def __init__(self, value):
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
177 self._value = value
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
178
38267
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
179 def contains(self, context, mapping, item):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
180 raise error.ParseError(_(b"%r is not iterable") % self._value)
38267
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
181
38243
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
182 def getmember(self, context, mapping, key):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
183 raise error.ParseError(_(b'%r is not a dictionary') % self._value)
38243
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
184
38265
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
185 def getmin(self, context, mapping):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
186 raise error.ParseError(_(b"%r is not iterable") % self._value)
38265
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
187
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
188 def getmax(self, context, mapping):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
189 raise error.ParseError(_(b"%r is not iterable") % self._value)
38265
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
190
38448
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
191 def filter(self, context, mapping, select):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
192 raise error.ParseError(_(b"%r is not iterable") % self._value)
38448
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
193
38226
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
194 def itermaps(self, context):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
195 raise error.ParseError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
196 _(b'%r is not iterable of mappings') % self._value
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
197 )
38226
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
198
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
199 def join(self, context, mapping, sep):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
200 raise error.ParseError(_(b'%r is not iterable') % self._value)
38226
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
201
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
202 def show(self, context, mapping):
38272
354fad8697fd templater: fix string representation of wrapped None
Yuya Nishihara <yuya@tcha.org>
parents: 38271
diff changeset
203 if self._value is None:
354fad8697fd templater: fix string representation of wrapped None
Yuya Nishihara <yuya@tcha.org>
parents: 38271
diff changeset
204 return b''
38226
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
205 return pycompat.bytestr(self._value)
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
206
38289
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
207 def tobool(self, context, mapping):
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
208 if self._value is None:
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
209 return False
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
210 if isinstance(self._value, bool):
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
211 return self._value
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
212 # otherwise evaluate as string, which means 0 is True
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
213 return bool(pycompat.bytestr(self._value))
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
214
38226
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
215 def tovalue(self, context, mapping):
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
216 return self._value
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
217
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
218
38286
851fc9d42d6d templater: make date wrapper support dot/map operations
Yuya Nishihara <yuya@tcha.org>
parents: 38285
diff changeset
219 class date(mappable, wrapped):
38285
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
220 """Wrapper for date tuple"""
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
221
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
222 def __init__(self, value, showfmt=b'%d %d'):
38285
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
223 # value may be (float, int), but public interface shouldn't support
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
224 # floating-point timestamp
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
225 self._unixtime, self._tzoffset = map(int, value)
38299
88e7105b5cd9 templater: restore the original string format of {date}
Yuya Nishihara <yuya@tcha.org>
parents: 38289
diff changeset
226 self._showfmt = showfmt
38285
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
227
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
228 def contains(self, context, mapping, item):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
229 raise error.ParseError(_(b'date is not iterable'))
38285
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
230
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
231 def getmember(self, context, mapping, key):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
232 raise error.ParseError(_(b'date is not a dictionary'))
38285
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
233
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
234 def getmin(self, context, mapping):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
235 raise error.ParseError(_(b'date is not iterable'))
38285
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
236
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
237 def getmax(self, context, mapping):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
238 raise error.ParseError(_(b'date is not iterable'))
38285
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
239
38448
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
240 def filter(self, context, mapping, select):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
241 raise error.ParseError(_(b'date is not iterable'))
38448
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
242
38285
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
243 def join(self, context, mapping, sep):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
244 raise error.ParseError(_(b"date is not iterable"))
38285
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
245
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
246 def show(self, context, mapping):
38299
88e7105b5cd9 templater: restore the original string format of {date}
Yuya Nishihara <yuya@tcha.org>
parents: 38289
diff changeset
247 return self._showfmt % (self._unixtime, self._tzoffset)
38285
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
248
38286
851fc9d42d6d templater: make date wrapper support dot/map operations
Yuya Nishihara <yuya@tcha.org>
parents: 38285
diff changeset
249 def tomap(self, context):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
250 return {b'unixtime': self._unixtime, b'tzoffset': self._tzoffset}
38286
851fc9d42d6d templater: make date wrapper support dot/map operations
Yuya Nishihara <yuya@tcha.org>
parents: 38285
diff changeset
251
38289
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
252 def tobool(self, context, mapping):
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
253 return True
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
254
38285
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
255 def tovalue(self, context, mapping):
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
256 return (self._unixtime, self._tzoffset)
37227
9bcf096a2da2 templatefilters: declare input type as date where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37226
diff changeset
257
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
258
37273
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
259 class hybrid(wrapped):
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
260 """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: 36920
diff changeset
261
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
262 This class allows us to handle both:
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
263 - "{files}" (legacy command-line-specific list hack) and
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
264 - "{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: 36920
diff changeset
265 and to access raw values:
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
266 - "{ifcontains(file, files, ...)}", "{ifcontains(key, extras, ...)}"
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
267 - "{get(extras, key)}"
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
268 - "{files|json}"
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
269 """
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
270
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
271 def __init__(self, gen, values, makemap, joinfmt, keytype=None):
37325
41a5d815d2c1 templater: factor out generator of join()-ed items
Yuya Nishihara <yuya@tcha.org>
parents: 37324
diff changeset
272 self._gen = gen # generator or function returning generator
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
273 self._values = values
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
274 self._makemap = makemap
37329
676664592313 templater: mark .joinfmt as a private attribute
Yuya Nishihara <yuya@tcha.org>
parents: 37327
diff changeset
275 self._joinfmt = joinfmt
38268
49ef1539b84e templater: mark .keytype as a private attribute
Yuya Nishihara <yuya@tcha.org>
parents: 38267
diff changeset
276 self._keytype = keytype # hint for 'x in y' where type(x) is unresolved
37275
8c84dc8264dc templater: mark .gen as a private attribute
Yuya Nishihara <yuya@tcha.org>
parents: 37273
diff changeset
277
38267
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
278 def contains(self, context, mapping, item):
38268
49ef1539b84e templater: mark .keytype as a private attribute
Yuya Nishihara <yuya@tcha.org>
parents: 38267
diff changeset
279 item = unwrapastype(context, mapping, item, self._keytype)
38267
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
280 return item in self._values
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
281
38242
12b6ee9e88f3 templater: move getdictitem() to hybrid class
Yuya Nishihara <yuya@tcha.org>
parents: 38241
diff changeset
282 def getmember(self, context, mapping, key):
12b6ee9e88f3 templater: move getdictitem() to hybrid class
Yuya Nishihara <yuya@tcha.org>
parents: 38241
diff changeset
283 # TODO: maybe split hybrid list/dict types?
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
284 if not util.safehasattr(self._values, b'get'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
285 raise error.ParseError(_(b'not a dictionary'))
38268
49ef1539b84e templater: mark .keytype as a private attribute
Yuya Nishihara <yuya@tcha.org>
parents: 38267
diff changeset
286 key = unwrapastype(context, mapping, key, self._keytype)
38242
12b6ee9e88f3 templater: move getdictitem() to hybrid class
Yuya Nishihara <yuya@tcha.org>
parents: 38241
diff changeset
287 return self._wrapvalue(key, self._values.get(key))
12b6ee9e88f3 templater: move getdictitem() to hybrid class
Yuya Nishihara <yuya@tcha.org>
parents: 38241
diff changeset
288
38265
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
289 def getmin(self, context, mapping):
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
290 return self._getby(context, mapping, min)
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
291
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
292 def getmax(self, context, mapping):
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
293 return self._getby(context, mapping, max)
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
294
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
295 def _getby(self, context, mapping, func):
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
296 if not self._values:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
297 raise error.ParseError(_(b'empty sequence'))
38265
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
298 val = func(self._values)
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
299 return self._wrapvalue(val, val)
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
300
38242
12b6ee9e88f3 templater: move getdictitem() to hybrid class
Yuya Nishihara <yuya@tcha.org>
parents: 38241
diff changeset
301 def _wrapvalue(self, key, val):
12b6ee9e88f3 templater: move getdictitem() to hybrid class
Yuya Nishihara <yuya@tcha.org>
parents: 38241
diff changeset
302 if val is None:
12b6ee9e88f3 templater: move getdictitem() to hybrid class
Yuya Nishihara <yuya@tcha.org>
parents: 38241
diff changeset
303 return
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
304 if util.safehasattr(val, b'_makemap'):
38266
80f423a14c90 templater: inline wraphybridvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 38265
diff changeset
305 # a nested hybrid list/dict, which has its own way of map operation
80f423a14c90 templater: inline wraphybridvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 38265
diff changeset
306 return val
38283
0e0d03d09ecd templater: rename mappable to hybriditem as it is the primary use case
Yuya Nishihara <yuya@tcha.org>
parents: 38272
diff changeset
307 return hybriditem(None, key, val, self._makemap)
38242
12b6ee9e88f3 templater: move getdictitem() to hybrid class
Yuya Nishihara <yuya@tcha.org>
parents: 38241
diff changeset
308
38448
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
309 def filter(self, context, mapping, select):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
310 if util.safehasattr(self._values, b'get'):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
311 values = {
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
312 k: v
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43089
diff changeset
313 for k, v in pycompat.iteritems(self._values)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
314 if select(self._wrapvalue(k, v))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
315 }
38448
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
316 else:
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
317 values = [v for v in self._values if select(self._wrapvalue(v, v))]
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
318 return hybrid(None, values, self._makemap, self._joinfmt, self._keytype)
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
319
37324
c2f74b8f6b7f templater: pass context to itermaps() for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 37323
diff changeset
320 def itermaps(self, context):
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
321 makemap = self._makemap
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
322 for x in self._values:
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
323 yield makemap(x)
37273
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
324
37327
ebf139cbd4a1 templater: abstract away from joinfmt
Yuya Nishihara <yuya@tcha.org>
parents: 37326
diff changeset
325 def join(self, context, mapping, sep):
ebf139cbd4a1 templater: abstract away from joinfmt
Yuya Nishihara <yuya@tcha.org>
parents: 37326
diff changeset
326 # TODO: switch gen to (context, mapping) API?
37329
676664592313 templater: mark .joinfmt as a private attribute
Yuya Nishihara <yuya@tcha.org>
parents: 37327
diff changeset
327 return joinitems((self._joinfmt(x) for x in self._values), sep)
37327
ebf139cbd4a1 templater: abstract away from joinfmt
Yuya Nishihara <yuya@tcha.org>
parents: 37326
diff changeset
328
37273
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
329 def show(self, context, mapping):
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
330 # TODO: switch gen to (context, mapping) API?
37275
8c84dc8264dc templater: mark .gen as a private attribute
Yuya Nishihara <yuya@tcha.org>
parents: 37273
diff changeset
331 gen = self._gen
37325
41a5d815d2c1 templater: factor out generator of join()-ed items
Yuya Nishihara <yuya@tcha.org>
parents: 37324
diff changeset
332 if gen is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
333 return self.join(context, mapping, b' ')
37273
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
334 if callable(gen):
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
335 return gen()
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
336 return gen
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
337
38289
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
338 def tobool(self, context, mapping):
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
339 return bool(self._values)
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
340
37279
26f6fc179e62 templater: define interface for objects requiring unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 37278
diff changeset
341 def tovalue(self, context, mapping):
38269
cf8d210dfac4 templater: drop hybrid-ness on unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 38268
diff changeset
342 # TODO: make it non-recursive for trivial lists/dicts
cf8d210dfac4 templater: drop hybrid-ness on unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 38268
diff changeset
343 xs = self._values
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
344 if util.safehasattr(xs, b'get'):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
345 return {
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43089
diff changeset
346 k: unwrapvalue(context, mapping, v)
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43089
diff changeset
347 for k, v in pycompat.iteritems(xs)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
348 }
38269
cf8d210dfac4 templater: drop hybrid-ness on unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 38268
diff changeset
349 return [unwrapvalue(context, mapping, x) for x in xs]
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
350
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
351
38284
e72697893c93 templater: promote tomap() to an interface type
Yuya Nishihara <yuya@tcha.org>
parents: 38283
diff changeset
352 class hybriditem(mappable, wrapped):
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
353 """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: 36920
diff changeset
354
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
355 This class allows us to handle both:
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
356 - "{manifest}"
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
357 - "{manifest % '{rev}:{node}'}"
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
358 - "{manifest.rev}"
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
359 """
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
360
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
361 def __init__(self, gen, key, value, makemap):
37276
b4630e332a99 templater: drop unneeded generator from mappable object
Yuya Nishihara <yuya@tcha.org>
parents: 37275
diff changeset
362 self._gen = gen # generator or function returning generator
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
363 self._key = key
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
364 self._value = value # may be generator of strings
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
365 self._makemap = makemap
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
366
38284
e72697893c93 templater: promote tomap() to an interface type
Yuya Nishihara <yuya@tcha.org>
parents: 38283
diff changeset
367 def tomap(self, context):
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
368 return self._makemap(self._key)
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
369
38267
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
370 def contains(self, context, mapping, item):
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
371 w = makewrapped(context, mapping, self._value)
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
372 return w.contains(context, mapping, item)
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
373
38243
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
374 def getmember(self, context, mapping, key):
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
375 w = makewrapped(context, mapping, self._value)
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
376 return w.getmember(context, mapping, key)
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
377
38265
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
378 def getmin(self, context, mapping):
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
379 w = makewrapped(context, mapping, self._value)
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
380 return w.getmin(context, mapping)
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
381
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
382 def getmax(self, context, mapping):
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
383 w = makewrapped(context, mapping, self._value)
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
384 return w.getmax(context, mapping)
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
385
38448
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
386 def filter(self, context, mapping, select):
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
387 w = makewrapped(context, mapping, self._value)
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
388 return w.filter(context, mapping, select)
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
389
37327
ebf139cbd4a1 templater: abstract away from joinfmt
Yuya Nishihara <yuya@tcha.org>
parents: 37326
diff changeset
390 def join(self, context, mapping, sep):
38228
8bded7eae26c templater: consistently join() string-like object per character (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38226
diff changeset
391 w = makewrapped(context, mapping, self._value)
8bded7eae26c templater: consistently join() string-like object per character (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38226
diff changeset
392 return w.join(context, mapping, sep)
37327
ebf139cbd4a1 templater: abstract away from joinfmt
Yuya Nishihara <yuya@tcha.org>
parents: 37326
diff changeset
393
37273
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
394 def show(self, context, mapping):
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
395 # TODO: switch gen to (context, mapping) API?
37275
8c84dc8264dc templater: mark .gen as a private attribute
Yuya Nishihara <yuya@tcha.org>
parents: 37273
diff changeset
396 gen = self._gen
37276
b4630e332a99 templater: drop unneeded generator from mappable object
Yuya Nishihara <yuya@tcha.org>
parents: 37275
diff changeset
397 if gen is None:
b4630e332a99 templater: drop unneeded generator from mappable object
Yuya Nishihara <yuya@tcha.org>
parents: 37275
diff changeset
398 return pycompat.bytestr(self._value)
37273
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
399 if callable(gen):
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
400 return gen()
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
401 return gen
83e1bbd48991 templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
402
38289
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
403 def tobool(self, context, mapping):
38447
b6294c113794 templater: fix truth testing of integer 0 taken from a list/dict
Yuya Nishihara <yuya@tcha.org>
parents: 38299
diff changeset
404 w = makewrapped(context, mapping, self._value)
b6294c113794 templater: fix truth testing of integer 0 taken from a list/dict
Yuya Nishihara <yuya@tcha.org>
parents: 38299
diff changeset
405 return w.tobool(context, mapping)
38289
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
406
37279
26f6fc179e62 templater: define interface for objects requiring unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 37278
diff changeset
407 def tovalue(self, context, mapping):
26f6fc179e62 templater: define interface for objects requiring unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 37278
diff changeset
408 return _unthunk(context, mapping, self._value)
26f6fc179e62 templater: define interface for objects requiring unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 37278
diff changeset
409
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
410
37399
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
411 class _mappingsequence(wrapped):
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
412 """Wrapper for sequence of template mappings
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
413
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
414 This represents an inner template structure (i.e. a list of dicts),
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
415 which can also be rendered by the specified named/literal template.
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
416
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
417 Template mappings may be nested.
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
418 """
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
419
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
420 def __init__(self, name=None, tmpl=None, sep=b''):
37399
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
421 if name is not None and tmpl is not None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
422 raise error.ProgrammingError(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
423 b'name and tmpl are mutually exclusive'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
424 )
37399
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
425 self._name = name
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
426 self._tmpl = tmpl
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
427 self._defaultsep = sep
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
428
38267
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
429 def contains(self, context, mapping, item):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
430 raise error.ParseError(_(b'not comparable'))
38267
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
431
38243
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
432 def getmember(self, context, mapping, key):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
433 raise error.ParseError(_(b'not a dictionary'))
38243
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
434
38265
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
435 def getmin(self, context, mapping):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
436 raise error.ParseError(_(b'not comparable'))
38265
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
437
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
438 def getmax(self, context, mapping):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
439 raise error.ParseError(_(b'not comparable'))
38265
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
440
38448
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
441 def filter(self, context, mapping, select):
38449
bc8d925342f0 templater: extend filter() to accept template expression for emptiness test
Yuya Nishihara <yuya@tcha.org>
parents: 38448
diff changeset
442 # implement if necessary; we'll need a wrapped type for a mapping dict
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
443 raise error.ParseError(_(b'not filterable without template'))
38448
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
444
37399
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
445 def join(self, context, mapping, sep):
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
446 mapsiter = _iteroverlaymaps(context, mapping, self.itermaps(context))
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
447 if self._name:
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
448 itemiter = (context.process(self._name, m) for m in mapsiter)
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
449 elif self._tmpl:
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
450 itemiter = (context.expand(self._tmpl, m) for m in mapsiter)
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
451 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
452 raise error.ParseError(_(b'not displayable without template'))
37399
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
453 return joinitems(itemiter, sep)
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
454
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
455 def show(self, context, mapping):
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
456 return self.join(context, mapping, self._defaultsep)
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
457
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
458 def tovalue(self, context, mapping):
37502
40c7347f6848 formatter: remove template resources from nested items before generating JSON
Yuya Nishihara <yuya@tcha.org>
parents: 37499
diff changeset
459 knownres = context.knownresourcekeys()
40c7347f6848 formatter: remove template resources from nested items before generating JSON
Yuya Nishihara <yuya@tcha.org>
parents: 37499
diff changeset
460 items = []
40c7347f6848 formatter: remove template resources from nested items before generating JSON
Yuya Nishihara <yuya@tcha.org>
parents: 37499
diff changeset
461 for nm in self.itermaps(context):
40c7347f6848 formatter: remove template resources from nested items before generating JSON
Yuya Nishihara <yuya@tcha.org>
parents: 37499
diff changeset
462 # drop internal resources (recursively) which shouldn't be displayed
40c7347f6848 formatter: remove template resources from nested items before generating JSON
Yuya Nishihara <yuya@tcha.org>
parents: 37499
diff changeset
463 lm = context.overlaymap(mapping, nm)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
464 items.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
465 {
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
466 k: unwrapvalue(context, lm, v)
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43089
diff changeset
467 for k, v in pycompat.iteritems(nm)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
468 if k not in knownres
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
469 }
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
470 )
37502
40c7347f6848 formatter: remove template resources from nested items before generating JSON
Yuya Nishihara <yuya@tcha.org>
parents: 37499
diff changeset
471 return items
37399
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
472
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
473
37399
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
474 class mappinggenerator(_mappingsequence):
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
475 """Wrapper for generator of template mappings
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
476
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
477 The function ``make(context, *args)`` should return a generator of
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
478 mapping dicts.
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
479 """
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
480
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
481 def __init__(self, make, args=(), name=None, tmpl=None, sep=b''):
37399
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
482 super(mappinggenerator, self).__init__(name, tmpl, sep)
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
483 self._make = make
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
484 self._args = args
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
485
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
486 def itermaps(self, context):
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
487 return self._make(context, *self._args)
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
488
38289
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
489 def tobool(self, context, mapping):
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
490 return _nonempty(self.itermaps(context))
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
491
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
492
37399
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
493 class mappinglist(_mappingsequence):
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
494 """Wrapper for list of template mappings"""
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
495
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
496 def __init__(self, mappings, name=None, tmpl=None, sep=b''):
37399
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
497 super(mappinglist, self).__init__(name, tmpl, sep)
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
498 self._mappings = mappings
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
499
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
500 def itermaps(self, context):
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
501 return iter(self._mappings)
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
502
38289
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
503 def tobool(self, context, mapping):
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
504 return bool(self._mappings)
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
505
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
506
40475
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
507 class mappingdict(mappable, _mappingsequence):
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
508 """Wrapper for a single template mapping
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
509
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
510 This isn't a sequence in a way that the underlying dict won't be iterated
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
511 as a dict, but shares most of the _mappingsequence functions.
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
512 """
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
513
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
514 def __init__(self, mapping, name=None, tmpl=None):
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
515 super(mappingdict, self).__init__(name, tmpl)
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
516 self._mapping = mapping
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
517
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
518 def tomap(self, context):
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
519 return self._mapping
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
520
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
521 def tobool(self, context, mapping):
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
522 # no idea when a template mapping should be considered an empty, but
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
523 # a mapping dict should have at least one item in practice, so always
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
524 # mark this as non-empty.
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
525 return True
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
526
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
527 def tovalue(self, context, mapping):
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
528 return super(mappingdict, self).tovalue(context, mapping)[0]
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
529
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
530
40935
4591c9791a82 templatefuncs: specialize "no match" value of search() to allow % operation
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
531 class mappingnone(wrappedvalue):
4591c9791a82 templatefuncs: specialize "no match" value of search() to allow % operation
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
532 """Wrapper for None, but supports map operation
4591c9791a82 templatefuncs: specialize "no match" value of search() to allow % operation
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
533
4591c9791a82 templatefuncs: specialize "no match" value of search() to allow % operation
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
534 This represents None of Optional[mappable]. It's similar to
4591c9791a82 templatefuncs: specialize "no match" value of search() to allow % operation
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
535 mapplinglist([]), but the underlying value is not [], but None.
4591c9791a82 templatefuncs: specialize "no match" value of search() to allow % operation
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
536 """
4591c9791a82 templatefuncs: specialize "no match" value of search() to allow % operation
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
537
4591c9791a82 templatefuncs: specialize "no match" value of search() to allow % operation
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
538 def __init__(self):
4591c9791a82 templatefuncs: specialize "no match" value of search() to allow % operation
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
539 super(mappingnone, self).__init__(None)
4591c9791a82 templatefuncs: specialize "no match" value of search() to allow % operation
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
540
4591c9791a82 templatefuncs: specialize "no match" value of search() to allow % operation
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
541 def itermaps(self, context):
4591c9791a82 templatefuncs: specialize "no match" value of search() to allow % operation
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
542 return iter([])
4591c9791a82 templatefuncs: specialize "no match" value of search() to allow % operation
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
543
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
544
37499
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
545 class mappedgenerator(wrapped):
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
546 """Wrapper for generator of strings which acts as a list
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
547
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
548 The function ``make(context, *args)`` should return a generator of
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
549 byte strings, or a generator of (possibly nested) generators of byte
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
550 strings (i.e. a generator for a list of byte strings.)
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
551 """
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
552
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
553 def __init__(self, make, args=()):
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
554 self._make = make
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
555 self._args = args
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
556
38267
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
557 def contains(self, context, mapping, item):
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
558 item = stringify(context, mapping, item)
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
559 return item in self.tovalue(context, mapping)
fb874fc1d9b4 templater: abstract ifcontains() over wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38266
diff changeset
560
37499
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
561 def _gen(self, context):
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
562 return self._make(context, *self._args)
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
563
38243
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
564 def getmember(self, context, mapping, key):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
565 raise error.ParseError(_(b'not a dictionary'))
38243
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
566
38265
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
567 def getmin(self, context, mapping):
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
568 return self._getby(context, mapping, min)
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
569
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
570 def getmax(self, context, mapping):
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
571 return self._getby(context, mapping, max)
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
572
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
573 def _getby(self, context, mapping, func):
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
574 xs = self.tovalue(context, mapping)
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
575 if not xs:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
576 raise error.ParseError(_(b'empty sequence'))
38265
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
577 return func(xs)
41ae9b3cbfb9 templater: abstract min/max away
Yuya Nishihara <yuya@tcha.org>
parents: 38244
diff changeset
578
38448
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
579 @staticmethod
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
580 def _filteredgen(context, mapping, make, args, select):
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
581 for x in make(context, *args):
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
582 s = stringify(context, mapping, x)
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
583 if select(wrappedbytes(s)):
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
584 yield s
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
585
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
586 def filter(self, context, mapping, select):
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
587 args = (mapping, self._make, self._args, select)
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
588 return mappedgenerator(self._filteredgen, args)
dae829b4de78 templater: introduce filter() function to remove empty items from list
Yuya Nishihara <yuya@tcha.org>
parents: 38447
diff changeset
589
37499
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
590 def itermaps(self, context):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
591 raise error.ParseError(_(b'list of strings is not mappable'))
37499
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
592
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
593 def join(self, context, mapping, sep):
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
594 return joinitems(self._gen(context), sep)
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
595
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
596 def show(self, context, mapping):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
597 return self.join(context, mapping, b'')
37499
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
598
38289
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
599 def tobool(self, context, mapping):
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
600 return _nonempty(self._gen(context))
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
601
37499
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
602 def tovalue(self, context, mapping):
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
603 return [stringify(context, mapping, x) for x in self._gen(context)]
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
604
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
605
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
606 def hybriddict(data, key=b'key', value=b'value', fmt=None, gen=None):
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
607 """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: 36920
diff changeset
608 prefmt = pycompat.identity
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
609 if fmt is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
610 fmt = b'%s=%s'
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
611 prefmt = pycompat.bytestr
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
612 return hybrid(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
613 gen,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
614 data,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
615 lambda k: {key: k, value: data[k]},
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
616 lambda k: fmt % (prefmt(k), prefmt(data[k])),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
617 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
618
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
619
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
620 def hybridlist(data, name, fmt=None, gen=None):
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
621 """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: 36920
diff changeset
622 prefmt = pycompat.identity
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
623 if fmt is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
624 fmt = b'%s'
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
625 prefmt = pycompat.bytestr
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
626 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: 36920
diff changeset
627
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
628
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
629 def compatdict(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
630 context,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
631 mapping,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
632 name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
633 data,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
634 key=b'key',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
635 value=b'value',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
636 fmt=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
637 plural=None,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
638 separator=b' ',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
639 ):
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
640 """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: 36920
diff changeset
641
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
642 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: 36920
diff changeset
643 hybriddict() for new template keywords.
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
644 """
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43089
diff changeset
645 c = [{key: k, value: v} for k, v in pycompat.iteritems(data)]
37068
aa97e06a1912 templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
646 f = _showcompatlist(context, mapping, name, c, plural, separator)
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
647 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: 36920
diff changeset
648
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
649
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
650 def compatlist(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
651 context,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
652 mapping,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
653 name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
654 data,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
655 element=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
656 fmt=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
657 plural=None,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
658 separator=b' ',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
659 ):
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
660 """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: 36920
diff changeset
661
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
662 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: 36920
diff changeset
663 hybridlist() for new template keywords.
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
664 """
37068
aa97e06a1912 templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
665 f = _showcompatlist(context, mapping, name, data, plural, separator)
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
666 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: 36920
diff changeset
667
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
668
39368
5b1d406b39f1 templatekw: alias {name} of file copies dict to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 39367
diff changeset
669 def compatfilecopiesdict(context, mapping, name, copies):
5b1d406b39f1 templatekw: alias {name} of file copies dict to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 39367
diff changeset
670 """Wrap list of (dest, source) file names to support old-style list
5b1d406b39f1 templatekw: alias {name} of file copies dict to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 39367
diff changeset
671 template and field names
5b1d406b39f1 templatekw: alias {name} of file copies dict to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 39367
diff changeset
672
5b1d406b39f1 templatekw: alias {name} of file copies dict to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 39367
diff changeset
673 This exists for backward compatibility. Use hybriddict for new template
5b1d406b39f1 templatekw: alias {name} of file copies dict to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 39367
diff changeset
674 keywords.
5b1d406b39f1 templatekw: alias {name} of file copies dict to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 39367
diff changeset
675 """
5b1d406b39f1 templatekw: alias {name} of file copies dict to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 39367
diff changeset
676 # no need to provide {path} to old-style list template
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
677 c = [{b'name': k, b'source': v} for k, v in copies]
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
678 f = _showcompatlist(context, mapping, name, c, plural=b'file_copies')
39368
5b1d406b39f1 templatekw: alias {name} of file copies dict to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 39367
diff changeset
679 copies = util.sortdict(copies)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
680 return hybrid(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
681 f,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
682 copies,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
683 lambda k: {b'name': k, b'path': k, b'source': copies[k]},
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
684 lambda k: b'%s (%s)' % (k, copies[k]),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
685 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
686
39368
5b1d406b39f1 templatekw: alias {name} of file copies dict to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 39367
diff changeset
687
39367
83f8f7b9fa60 templatekw: alias {file} of files list to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 38930
diff changeset
688 def compatfileslist(context, mapping, name, files):
83f8f7b9fa60 templatekw: alias {file} of files list to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 38930
diff changeset
689 """Wrap list of file names to support old-style list template and field
83f8f7b9fa60 templatekw: alias {file} of files list to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 38930
diff changeset
690 names
83f8f7b9fa60 templatekw: alias {file} of files list to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 38930
diff changeset
691
83f8f7b9fa60 templatekw: alias {file} of files list to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 38930
diff changeset
692 This exists for backward compatibility. Use hybridlist for new template
83f8f7b9fa60 templatekw: alias {file} of files list to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 38930
diff changeset
693 keywords.
83f8f7b9fa60 templatekw: alias {file} of files list to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 38930
diff changeset
694 """
83f8f7b9fa60 templatekw: alias {file} of files list to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 38930
diff changeset
695 f = _showcompatlist(context, mapping, name, files)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
696 return hybrid(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
697 f, files, lambda x: {b'file': x, b'path': x}, pycompat.identity
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
698 )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
699
39367
83f8f7b9fa60 templatekw: alias {file} of files list to {path}
Yuya Nishihara <yuya@tcha.org>
parents: 38930
diff changeset
700
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
701 def _showcompatlist(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
702 context, mapping, name, values, plural=None, separator=b' '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
703 ):
37068
aa97e06a1912 templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
704 """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: 37019
diff changeset
705
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
706 name is name of key in template map.
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
707 values is list of strings or dicts.
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
708 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: 36920
diff changeset
709 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: 36920
diff changeset
710
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
711 expansion works like this, given name 'foo'.
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
712
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
713 if values is empty, expand 'no_foos'.
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
714
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
715 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: 36920
diff changeset
716 joined by 'separator'.
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
717
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
718 expand 'start_foos'.
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
719
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
720 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: 36920
diff changeset
721 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: 36920
diff changeset
722
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
723 expand 'end_foos'.
37068
aa97e06a1912 templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
724 """
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
725 if not plural:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
726 plural = name + b's'
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
727 if not values:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
728 noname = b'no_' + plural
37068
aa97e06a1912 templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
729 if context.preload(noname):
aa97e06a1912 templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
730 yield context.process(noname, mapping)
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
731 return
37068
aa97e06a1912 templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
732 if not context.preload(name):
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
733 if isinstance(values[0], bytes):
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
734 yield separator.join(values)
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
735 else:
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
736 for v in values:
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
737 r = dict(v)
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
738 r.update(mapping)
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
739 yield r
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
740 return
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
741 startname = b'start_' + plural
37068
aa97e06a1912 templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
742 if context.preload(startname):
aa97e06a1912 templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
743 yield context.process(startname, mapping)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
744
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
745 def one(v, tag=name):
37074
2891079fb0c0 templater: factor out function to create mapping dict for nested evaluation
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
746 vmapping = {}
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
747 try:
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
748 vmapping.update(v)
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
749 # 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: 36920
diff changeset
750 # 3 raises TypeError.
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
751 except (AttributeError, TypeError, ValueError):
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
752 try:
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
753 # 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: 36920
diff changeset
754 # bytes. Python 3 raises TypeError.
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
755 for a, b in v:
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
756 vmapping[a] = b
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
757 except (TypeError, ValueError):
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
758 vmapping[name] = v
37074
2891079fb0c0 templater: factor out function to create mapping dict for nested evaluation
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
759 vmapping = context.overlaymap(mapping, vmapping)
37068
aa97e06a1912 templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
760 return context.process(tag, vmapping)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
761
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
762 lastname = b'last_' + name
37068
aa97e06a1912 templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
763 if context.preload(lastname):
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
764 last = values.pop()
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
765 else:
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
766 last = None
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
767 for v in values:
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
768 yield one(v)
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
769 if last is not None:
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
770 yield one(last, tag=lastname)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
771 endname = b'end_' + plural
37068
aa97e06a1912 templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
772 if context.preload(endname):
aa97e06a1912 templater: use template context to render old-style list template
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
773 yield context.process(endname, mapping)
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
774
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
775
37272
7d3bc1d4e871 templater: pass (context, mapping) down to unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37231
diff changeset
776 def flatten(context, mapping, thing):
37157
888507ec655e templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents: 37104
diff changeset
777 """Yield a single stream from a possibly nested set of iterators"""
38270
630c62804383 templater: inline unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 38269
diff changeset
778 if isinstance(thing, wrapped):
630c62804383 templater: inline unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 38269
diff changeset
779 thing = thing.show(context, mapping)
37157
888507ec655e templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents: 37104
diff changeset
780 if isinstance(thing, bytes):
888507ec655e templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents: 37104
diff changeset
781 yield thing
888507ec655e templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents: 37104
diff changeset
782 elif isinstance(thing, str):
888507ec655e templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents: 37104
diff changeset
783 # 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: 37104
diff changeset
784 # against infinite recursion.
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
785 raise error.ProgrammingError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
786 b'Mercurial IO including templates is done'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
787 b' with bytes, not strings, got %r' % thing
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
788 )
37157
888507ec655e templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents: 37104
diff changeset
789 elif thing is None:
888507ec655e templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents: 37104
diff changeset
790 pass
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
791 elif not util.safehasattr(thing, b'__iter__'):
37157
888507ec655e templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents: 37104
diff changeset
792 yield pycompat.bytestr(thing)
888507ec655e templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents: 37104
diff changeset
793 else:
888507ec655e templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents: 37104
diff changeset
794 for i in thing:
38270
630c62804383 templater: inline unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 38269
diff changeset
795 if isinstance(i, wrapped):
630c62804383 templater: inline unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 38269
diff changeset
796 i = i.show(context, mapping)
37157
888507ec655e templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents: 37104
diff changeset
797 if isinstance(i, bytes):
888507ec655e templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents: 37104
diff changeset
798 yield i
888507ec655e templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents: 37104
diff changeset
799 elif i is None:
888507ec655e templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents: 37104
diff changeset
800 pass
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
801 elif not util.safehasattr(i, b'__iter__'):
37157
888507ec655e templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents: 37104
diff changeset
802 yield pycompat.bytestr(i)
888507ec655e templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents: 37104
diff changeset
803 else:
37272
7d3bc1d4e871 templater: pass (context, mapping) down to unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37231
diff changeset
804 for j in flatten(context, mapping, i):
37157
888507ec655e templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents: 37104
diff changeset
805 yield j
888507ec655e templateutil: move flatten() from templater
Yuya Nishihara <yuya@tcha.org>
parents: 37104
diff changeset
806
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
807
37272
7d3bc1d4e871 templater: pass (context, mapping) down to unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37231
diff changeset
808 def stringify(context, mapping, thing):
36920
6ff6e1d6b5b8 templater: move stringify() to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36913
diff changeset
809 """Turn values into bytes by converting into text and concatenating them"""
37158
e09d2183e226 templateutil: reimplement stringify() using flatten()
Yuya Nishihara <yuya@tcha.org>
parents: 37157
diff changeset
810 if isinstance(thing, bytes):
e09d2183e226 templateutil: reimplement stringify() using flatten()
Yuya Nishihara <yuya@tcha.org>
parents: 37157
diff changeset
811 return thing # retain localstr to be round-tripped
37272
7d3bc1d4e871 templater: pass (context, mapping) down to unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37231
diff changeset
812 return b''.join(flatten(context, mapping, thing))
36920
6ff6e1d6b5b8 templater: move stringify() to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36913
diff changeset
813
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
814
31927
2abc556dbe92 templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents: 31926
diff changeset
815 def findsymbolicname(arg):
2abc556dbe92 templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents: 31926
diff changeset
816 """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: 31926
diff changeset
817 if nothing found reliably"""
2abc556dbe92 templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents: 31926
diff changeset
818 while True:
2abc556dbe92 templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents: 31926
diff changeset
819 func, data = arg
2abc556dbe92 templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents: 31926
diff changeset
820 if func is runsymbol:
2abc556dbe92 templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents: 31926
diff changeset
821 return data
2abc556dbe92 templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents: 31926
diff changeset
822 elif func is runfilter:
2abc556dbe92 templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents: 31926
diff changeset
823 arg = data[0]
2abc556dbe92 templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents: 31926
diff changeset
824 else:
2abc556dbe92 templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents: 31926
diff changeset
825 return None
2abc556dbe92 templater: find keyword name more thoroughly on filtering error
Yuya Nishihara <yuya@tcha.org>
parents: 31926
diff changeset
826
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
827
38289
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
828 def _nonempty(xiter):
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
829 try:
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
830 next(xiter)
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
831 return True
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
832 except StopIteration:
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
833 return False
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
834
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
835
37278
671a01cd50b5 templater: extract private function to evaluate generator to byte string
Yuya Nishihara <yuya@tcha.org>
parents: 37277
diff changeset
836 def _unthunk(context, mapping, thing):
671a01cd50b5 templater: extract private function to evaluate generator to byte string
Yuya Nishihara <yuya@tcha.org>
parents: 37277
diff changeset
837 """Evaluate a lazy byte string into value"""
671a01cd50b5 templater: extract private function to evaluate generator to byte string
Yuya Nishihara <yuya@tcha.org>
parents: 37277
diff changeset
838 if not isinstance(thing, types.GeneratorType):
671a01cd50b5 templater: extract private function to evaluate generator to byte string
Yuya Nishihara <yuya@tcha.org>
parents: 37277
diff changeset
839 return thing
671a01cd50b5 templater: extract private function to evaluate generator to byte string
Yuya Nishihara <yuya@tcha.org>
parents: 37277
diff changeset
840 return stringify(context, mapping, thing)
671a01cd50b5 templater: extract private function to evaluate generator to byte string
Yuya Nishihara <yuya@tcha.org>
parents: 37277
diff changeset
841
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
842
34326
e60c601953d7 templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents: 34325
diff changeset
843 def evalrawexp(context, mapping, arg):
e60c601953d7 templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents: 34325
diff changeset
844 """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: 34325
diff changeset
845 further processing (such as folding generator of strings)"""
26124
604a7c941103 templater: extract helper that evaluates filter or function argument
Yuya Nishihara <yuya@tcha.org>
parents: 26106
diff changeset
846 func, data = arg
34326
e60c601953d7 templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents: 34325
diff changeset
847 return func(context, mapping, data)
e60c601953d7 templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents: 34325
diff changeset
848
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
849
38226
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
850 def evalwrapped(context, mapping, arg):
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
851 """Evaluate given argument to wrapped object"""
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
852 thing = evalrawexp(context, mapping, arg)
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
853 return makewrapped(context, mapping, thing)
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
854
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
855
38226
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
856 def makewrapped(context, mapping, thing):
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
857 """Lift object to a wrapped type"""
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
858 if isinstance(thing, wrapped):
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
859 return thing
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
860 thing = _unthunk(context, mapping, thing)
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
861 if isinstance(thing, bytes):
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
862 return wrappedbytes(thing)
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
863 return wrappedvalue(thing)
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
864
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
865
34326
e60c601953d7 templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents: 34325
diff changeset
866 def evalfuncarg(context, mapping, arg):
e60c601953d7 templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents: 34325
diff changeset
867 """Evaluate given argument as value type"""
38225
d48b80d58848 templater: unify unwrapvalue() with _unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 38224
diff changeset
868 return unwrapvalue(context, mapping, evalrawexp(context, mapping, arg))
37161
0023da2910c9 templater: extract type conversion from evalfuncarg()
Yuya Nishihara <yuya@tcha.org>
parents: 37160
diff changeset
869
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
870
38225
d48b80d58848 templater: unify unwrapvalue() with _unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 38224
diff changeset
871 def unwrapvalue(context, mapping, thing):
d48b80d58848 templater: unify unwrapvalue() with _unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 38224
diff changeset
872 """Move the inner value object out of the wrapper"""
38224
61cecab0cc20 templater: inline unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 37502
diff changeset
873 if isinstance(thing, wrapped):
61cecab0cc20 templater: inline unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 37502
diff changeset
874 return thing.tovalue(context, mapping)
34326
e60c601953d7 templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents: 34325
diff changeset
875 # 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: 34325
diff changeset
876 # such as date tuple, but filter does not want generator.
37278
671a01cd50b5 templater: extract private function to evaluate generator to byte string
Yuya Nishihara <yuya@tcha.org>
parents: 37277
diff changeset
877 return _unthunk(context, mapping, thing)
26124
604a7c941103 templater: extract helper that evaluates filter or function argument
Yuya Nishihara <yuya@tcha.org>
parents: 26106
diff changeset
878
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
879
29816
034412ca28c3 templater: fix if() to not evaluate False as bool('False')
Yuya Nishihara <yuya@tcha.org>
parents: 29815
diff changeset
880 def evalboolean(context, mapping, arg):
29817
cc11079644fc templater: make pad() evaluate boolean argument (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29816
diff changeset
881 """Evaluate given argument as boolean, but also takes boolean literals"""
29816
034412ca28c3 templater: fix if() to not evaluate False as bool('False')
Yuya Nishihara <yuya@tcha.org>
parents: 29815
diff changeset
882 func, data = arg
29817
cc11079644fc templater: make pad() evaluate boolean argument (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29816
diff changeset
883 if func is runsymbol:
cc11079644fc templater: make pad() evaluate boolean argument (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29816
diff changeset
884 thing = func(context, mapping, data, default=None)
cc11079644fc templater: make pad() evaluate boolean argument (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29816
diff changeset
885 if thing is None:
cc11079644fc templater: make pad() evaluate boolean argument (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29816
diff changeset
886 # not a template keyword, takes as a boolean literal
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
887 thing = stringutil.parsebool(data)
29817
cc11079644fc templater: make pad() evaluate boolean argument (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29816
diff changeset
888 else:
cc11079644fc templater: make pad() evaluate boolean argument (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29816
diff changeset
889 thing = func(context, mapping, data)
38289
f9c426385853 templater: abstract truth testing to fix {if(list_of_empty_strings)}
Yuya Nishihara <yuya@tcha.org>
parents: 38286
diff changeset
890 return makewrapped(context, mapping, thing).tobool(context, mapping)
29816
034412ca28c3 templater: fix if() to not evaluate False as bool('False')
Yuya Nishihara <yuya@tcha.org>
parents: 29815
diff changeset
891
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
892
37224
67efce231633 templater: factor out function that parses argument as date tuple
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
893 def evaldate(context, mapping, arg, err=None):
67efce231633 templater: factor out function that parses argument as date tuple
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
894 """Evaluate given argument as a date tuple or a date string; returns
67efce231633 templater: factor out function that parses argument as date tuple
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
895 a (unixtime, offset) tuple"""
37272
7d3bc1d4e871 templater: pass (context, mapping) down to unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37231
diff changeset
896 thing = evalrawexp(context, mapping, arg)
7d3bc1d4e871 templater: pass (context, mapping) down to unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37231
diff changeset
897 return unwrapdate(context, mapping, thing, err)
37224
67efce231633 templater: factor out function that parses argument as date tuple
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
898
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
899
37272
7d3bc1d4e871 templater: pass (context, mapping) down to unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37231
diff changeset
900 def unwrapdate(context, mapping, thing, err=None):
38285
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
901 if isinstance(thing, date):
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
902 return thing.tovalue(context, mapping)
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38284
diff changeset
903 # TODO: update hgweb to not return bare tuple; then just stringify 'thing'
38225
d48b80d58848 templater: unify unwrapvalue() with _unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 38224
diff changeset
904 thing = unwrapvalue(context, mapping, thing)
37224
67efce231633 templater: factor out function that parses argument as date tuple
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
905 try:
67efce231633 templater: factor out function that parses argument as date tuple
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
906 return dateutil.parsedate(thing)
67efce231633 templater: factor out function that parses argument as date tuple
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
907 except AttributeError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
908 raise error.ParseError(err or _(b'not a date tuple nor a string'))
37225
e70a90a72b80 templatefuncs: use evaldate() where seems appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37224
diff changeset
909 except error.ParseError:
e70a90a72b80 templatefuncs: use evaldate() where seems appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37224
diff changeset
910 if not err:
e70a90a72b80 templatefuncs: use evaldate() where seems appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37224
diff changeset
911 raise
e70a90a72b80 templatefuncs: use evaldate() where seems appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37224
diff changeset
912 raise error.ParseError(err)
37224
67efce231633 templater: factor out function that parses argument as date tuple
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
913
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
914
34581
ee0d74083a22 templater: store revisions as ints so min/max won't compare them as strings
Yuya Nishihara <yuya@tcha.org>
parents: 34536
diff changeset
915 def evalinteger(context, mapping, arg, err=None):
37272
7d3bc1d4e871 templater: pass (context, mapping) down to unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37231
diff changeset
916 thing = evalrawexp(context, mapping, arg)
7d3bc1d4e871 templater: pass (context, mapping) down to unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37231
diff changeset
917 return unwrapinteger(context, mapping, thing, err)
37162
9ab3491f84c2 templater: extract unwrapinteger() function from evalinteger()
Yuya Nishihara <yuya@tcha.org>
parents: 37161
diff changeset
918
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
919
37272
7d3bc1d4e871 templater: pass (context, mapping) down to unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37231
diff changeset
920 def unwrapinteger(context, mapping, thing, err=None):
38225
d48b80d58848 templater: unify unwrapvalue() with _unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 38224
diff changeset
921 thing = unwrapvalue(context, mapping, thing)
28343
a6c2310b3827 templater: factor out function that evaluates argument as integer
Yuya Nishihara <yuya@tcha.org>
parents: 28334
diff changeset
922 try:
37162
9ab3491f84c2 templater: extract unwrapinteger() function from evalinteger()
Yuya Nishihara <yuya@tcha.org>
parents: 37161
diff changeset
923 return int(thing)
28344
ac371d4c007f templater: drop redundant type conversion when evaluating integer argument
Yuya Nishihara <yuya@tcha.org>
parents: 28343
diff changeset
924 except (TypeError, ValueError):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
925 raise error.ParseError(err or _(b'not an integer'))
28343
a6c2310b3827 templater: factor out function that evaluates argument as integer
Yuya Nishihara <yuya@tcha.org>
parents: 28334
diff changeset
926
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
927
28348
ccedb17a5657 templater: factor out thin helper that evaluates argument as string
Yuya Nishihara <yuya@tcha.org>
parents: 28346
diff changeset
928 def evalstring(context, mapping, arg):
37272
7d3bc1d4e871 templater: pass (context, mapping) down to unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37231
diff changeset
929 return stringify(context, mapping, evalrawexp(context, mapping, arg))
28348
ccedb17a5657 templater: factor out thin helper that evaluates argument as string
Yuya Nishihara <yuya@tcha.org>
parents: 28346
diff changeset
930
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
931
28373
9a9dd71e882c templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents: 28349
diff changeset
932 def evalstringliteral(context, mapping, arg):
9a9dd71e882c templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents: 28349
diff changeset
933 """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: 28349
diff changeset
934 if it is unknown"""
9a9dd71e882c templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents: 28349
diff changeset
935 func, data = arg
9a9dd71e882c templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents: 28349
diff changeset
936 if func is runsymbol:
9a9dd71e882c templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents: 28349
diff changeset
937 thing = func(context, mapping, data, default=data)
9a9dd71e882c templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents: 28349
diff changeset
938 else:
9a9dd71e882c templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents: 28349
diff changeset
939 thing = func(context, mapping, data)
37272
7d3bc1d4e871 templater: pass (context, mapping) down to unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37231
diff changeset
940 return stringify(context, mapping, thing)
28373
9a9dd71e882c templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents: 28349
diff changeset
941
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
942
37163
0fb28899e81a templater: factor out unwrapastype() from evalastype()
Yuya Nishihara <yuya@tcha.org>
parents: 37162
diff changeset
943 _unwrapfuncbytype = {
38225
d48b80d58848 templater: unify unwrapvalue() with _unwrapvalue()
Yuya Nishihara <yuya@tcha.org>
parents: 38224
diff changeset
944 None: unwrapvalue,
37163
0fb28899e81a templater: factor out unwrapastype() from evalastype()
Yuya Nishihara <yuya@tcha.org>
parents: 37162
diff changeset
945 bytes: stringify,
37227
9bcf096a2da2 templatefilters: declare input type as date where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37226
diff changeset
946 date: unwrapdate,
37163
0fb28899e81a templater: factor out unwrapastype() from evalastype()
Yuya Nishihara <yuya@tcha.org>
parents: 37162
diff changeset
947 int: unwrapinteger,
34581
ee0d74083a22 templater: store revisions as ints so min/max won't compare them as strings
Yuya Nishihara <yuya@tcha.org>
parents: 34536
diff changeset
948 }
ee0d74083a22 templater: store revisions as ints so min/max won't compare them as strings
Yuya Nishihara <yuya@tcha.org>
parents: 34536
diff changeset
949
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
950
37272
7d3bc1d4e871 templater: pass (context, mapping) down to unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37231
diff changeset
951 def unwrapastype(context, mapping, thing, typ):
37163
0fb28899e81a templater: factor out unwrapastype() from evalastype()
Yuya Nishihara <yuya@tcha.org>
parents: 37162
diff changeset
952 """Move the inner value object out of the wrapper and coerce its type"""
34581
ee0d74083a22 templater: store revisions as ints so min/max won't compare them as strings
Yuya Nishihara <yuya@tcha.org>
parents: 34536
diff changeset
953 try:
37163
0fb28899e81a templater: factor out unwrapastype() from evalastype()
Yuya Nishihara <yuya@tcha.org>
parents: 37162
diff changeset
954 f = _unwrapfuncbytype[typ]
34581
ee0d74083a22 templater: store revisions as ints so min/max won't compare them as strings
Yuya Nishihara <yuya@tcha.org>
parents: 34536
diff changeset
955 except KeyError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
956 raise error.ProgrammingError(b'invalid type specified: %r' % typ)
37272
7d3bc1d4e871 templater: pass (context, mapping) down to unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37231
diff changeset
957 return f(context, mapping, thing)
34581
ee0d74083a22 templater: store revisions as ints so min/max won't compare them as strings
Yuya Nishihara <yuya@tcha.org>
parents: 34536
diff changeset
958
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
959
25002
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
960 def runinteger(context, mapping, data):
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
961 return int(data)
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
962
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
963
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
964 def runstring(context, mapping, data):
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
965 return data
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
966
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
967
27939
7ed3a3c0cef1 templater: abort if infinite recursion detected while evaluation (issue4758)
Yuya Nishihara <yuya@tcha.org>
parents: 27892
diff changeset
968 def _recursivesymbolblocker(key):
38930
382b055cc358 templatekw: deprecate old-style template keyword function (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38449
diff changeset
969 def showrecursion(context, mapping):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
970 raise error.Abort(_(b"recursive reference '%s' in template") % key)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
971
27939
7ed3a3c0cef1 templater: abort if infinite recursion detected while evaluation (issue4758)
Yuya Nishihara <yuya@tcha.org>
parents: 27892
diff changeset
972 return showrecursion
7ed3a3c0cef1 templater: abort if infinite recursion detected while evaluation (issue4758)
Yuya Nishihara <yuya@tcha.org>
parents: 27892
diff changeset
973
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
974
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
975 def runsymbol(context, mapping, key, default=b''):
35467
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35414
diff changeset
976 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
977 if v is None:
27939
7ed3a3c0cef1 templater: abort if infinite recursion detected while evaluation (issue4758)
Yuya Nishihara <yuya@tcha.org>
parents: 27892
diff changeset
978 # 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: 27892
diff changeset
979 # 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: 27892
diff changeset
980 safemapping = mapping.copy()
7ed3a3c0cef1 templater: abort if infinite recursion detected while evaluation (issue4758)
Yuya Nishihara <yuya@tcha.org>
parents: 27892
diff changeset
981 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
982 try:
27939
7ed3a3c0cef1 templater: abort if infinite recursion detected while evaluation (issue4758)
Yuya Nishihara <yuya@tcha.org>
parents: 27892
diff changeset
983 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
984 except TemplateNotFound:
28373
9a9dd71e882c templater: make label() take unknown symbol as color literal
Yuya Nishihara <yuya@tcha.org>
parents: 28349
diff changeset
985 v = default
36445
e8d37838f5df templatekw: add 'requires' flag to switch to exception-safe interface
Yuya Nishihara <yuya@tcha.org>
parents: 36444
diff changeset
986 if callable(v):
e8d37838f5df templatekw: add 'requires' flag to switch to exception-safe interface
Yuya Nishihara <yuya@tcha.org>
parents: 36444
diff changeset
987 # new templatekw
e8d37838f5df templatekw: add 'requires' flag to switch to exception-safe interface
Yuya Nishihara <yuya@tcha.org>
parents: 36444
diff changeset
988 try:
e8d37838f5df templatekw: add 'requires' flag to switch to exception-safe interface
Yuya Nishihara <yuya@tcha.org>
parents: 36444
diff changeset
989 return v(context, mapping)
e8d37838f5df templatekw: add 'requires' flag to switch to exception-safe interface
Yuya Nishihara <yuya@tcha.org>
parents: 36444
diff changeset
990 except ResourceUnavailable:
e8d37838f5df templatekw: add 'requires' flag to switch to exception-safe interface
Yuya Nishihara <yuya@tcha.org>
parents: 36444
diff changeset
991 # 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: 36444
diff changeset
992 return None
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
993 return v
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
994
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
995
25595
a7dd6692e5cb templater: move runtemplate function out of buildmap/runmap pair
Yuya Nishihara <yuya@tcha.org>
parents: 25580
diff changeset
996 def runtemplate(context, mapping, template):
34326
e60c601953d7 templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents: 34325
diff changeset
997 for arg in template:
e60c601953d7 templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents: 34325
diff changeset
998 yield evalrawexp(context, mapping, arg)
25595
a7dd6692e5cb templater: move runtemplate function out of buildmap/runmap pair
Yuya Nishihara <yuya@tcha.org>
parents: 25580
diff changeset
999
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
1000
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
1001 def runfilter(context, mapping, data):
26125
c990afab2243 templater: drop unneeded destructuring of argument tuple at buildfilter
Yuya Nishihara <yuya@tcha.org>
parents: 26124
diff changeset
1002 arg, filt = data
37222
54355c243042 templatefilters: allow declaration of input data type
Yuya Nishihara <yuya@tcha.org>
parents: 37163
diff changeset
1003 thing = evalrawexp(context, mapping, arg)
37272
7d3bc1d4e871 templater: pass (context, mapping) down to unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37231
diff changeset
1004 intype = getattr(filt, '_intype', None)
17383
099c778ceb33 templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents: 17334
diff changeset
1005 try:
37272
7d3bc1d4e871 templater: pass (context, mapping) down to unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37231
diff changeset
1006 thing = unwrapastype(context, mapping, thing, intype)
24280
6c55e37ba5f2 templater: allow piping generator-type function output to filters
Yuya Nishihara <yuya@tcha.org>
parents: 24240
diff changeset
1007 return filt(thing)
37226
920589f52be9 templater: attach hint to input-type error of runfilter()
Yuya Nishihara <yuya@tcha.org>
parents: 37225
diff changeset
1008 except error.ParseError as e:
920589f52be9 templater: attach hint to input-type error of runfilter()
Yuya Nishihara <yuya@tcha.org>
parents: 37225
diff changeset
1009 raise error.ParseError(bytes(e), hint=_formatfiltererror(arg, filt))
920589f52be9 templater: attach hint to input-type error of runfilter()
Yuya Nishihara <yuya@tcha.org>
parents: 37225
diff changeset
1010
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
1011
37226
920589f52be9 templater: attach hint to input-type error of runfilter()
Yuya Nishihara <yuya@tcha.org>
parents: 37225
diff changeset
1012 def _formatfiltererror(arg, filt):
920589f52be9 templater: attach hint to input-type error of runfilter()
Yuya Nishihara <yuya@tcha.org>
parents: 37225
diff changeset
1013 fn = pycompat.sysbytes(filt.__name__)
920589f52be9 templater: attach hint to input-type error of runfilter()
Yuya Nishihara <yuya@tcha.org>
parents: 37225
diff changeset
1014 sym = findsymbolicname(arg)
920589f52be9 templater: attach hint to input-type error of runfilter()
Yuya Nishihara <yuya@tcha.org>
parents: 37225
diff changeset
1015 if not sym:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1016 return _(b"incompatible use of template filter '%s'") % fn
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1017 return _(b"template filter '%s' is not compatible with keyword '%s'") % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
1018 fn,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
1019 sym,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
1020 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
1021
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
1022
37399
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
1023 def _iteroverlaymaps(context, origmapping, newmappings):
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
1024 """Generate combined mappings from the original mapping and an iterable
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
1025 of partial mappings to override the original"""
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
1026 for i, nm in enumerate(newmappings):
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
1027 lm = context.overlaymap(origmapping, nm)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1028 lm[b'index'] = i
37399
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
1029 yield lm
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37329
diff changeset
1030
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
1031
38271
4b0f39e7406e templater: show slightly better hint on map operation error
Yuya Nishihara <yuya@tcha.org>
parents: 38270
diff changeset
1032 def _applymap(context, mapping, d, darg, targ):
4b0f39e7406e templater: show slightly better hint on map operation error
Yuya Nishihara <yuya@tcha.org>
parents: 38270
diff changeset
1033 try:
4b0f39e7406e templater: show slightly better hint on map operation error
Yuya Nishihara <yuya@tcha.org>
parents: 38270
diff changeset
1034 diter = d.itermaps(context)
4b0f39e7406e templater: show slightly better hint on map operation error
Yuya Nishihara <yuya@tcha.org>
parents: 38270
diff changeset
1035 except error.ParseError as err:
4b0f39e7406e templater: show slightly better hint on map operation error
Yuya Nishihara <yuya@tcha.org>
parents: 38270
diff changeset
1036 sym = findsymbolicname(darg)
4b0f39e7406e templater: show slightly better hint on map operation error
Yuya Nishihara <yuya@tcha.org>
parents: 38270
diff changeset
1037 if not sym:
4b0f39e7406e templater: show slightly better hint on map operation error
Yuya Nishihara <yuya@tcha.org>
parents: 38270
diff changeset
1038 raise
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1039 hint = _(b"keyword '%s' does not support map operation") % sym
38271
4b0f39e7406e templater: show slightly better hint on map operation error
Yuya Nishihara <yuya@tcha.org>
parents: 38270
diff changeset
1040 raise error.ParseError(bytes(err), hint=hint)
4b0f39e7406e templater: show slightly better hint on map operation error
Yuya Nishihara <yuya@tcha.org>
parents: 38270
diff changeset
1041 for lm in _iteroverlaymaps(context, mapping, diter):
37499
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
1042 yield evalrawexp(context, lm, targ)
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37405
diff changeset
1043
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
1044
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
1045 def runmap(context, mapping, data):
34326
e60c601953d7 templater: extract helper to just evaluate template expression
Yuya Nishihara <yuya@tcha.org>
parents: 34325
diff changeset
1046 darg, targ = data
38229
7701c2d4a438 templater: always map over a wrapped object
Yuya Nishihara <yuya@tcha.org>
parents: 38228
diff changeset
1047 d = evalwrapped(context, mapping, darg)
38271
4b0f39e7406e templater: show slightly better hint on map operation error
Yuya Nishihara <yuya@tcha.org>
parents: 38270
diff changeset
1048 return mappedgenerator(_applymap, args=(mapping, d, darg, targ))
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
1049
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
1050
34535
78590585c0db templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents: 34534
diff changeset
1051 def runmember(context, mapping, data):
78590585c0db templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents: 34534
diff changeset
1052 darg, memb = data
38240
c2456a7726c1 templater: do dict lookup over a wrapped object
Yuya Nishihara <yuya@tcha.org>
parents: 38229
diff changeset
1053 d = evalwrapped(context, mapping, darg)
38284
e72697893c93 templater: promote tomap() to an interface type
Yuya Nishihara <yuya@tcha.org>
parents: 38283
diff changeset
1054 if isinstance(d, mappable):
e72697893c93 templater: promote tomap() to an interface type
Yuya Nishihara <yuya@tcha.org>
parents: 38283
diff changeset
1055 lm = context.overlaymap(mapping, d.tomap(context))
34535
78590585c0db templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents: 34534
diff changeset
1056 return runsymbol(context, lm, memb)
38241
ad06a4264daf templater: add try-except stub to runmember()
Yuya Nishihara <yuya@tcha.org>
parents: 38240
diff changeset
1057 try:
38243
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
1058 return d.getmember(context, mapping, memb)
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
1059 except error.ParseError as err:
38241
ad06a4264daf templater: add try-except stub to runmember()
Yuya Nishihara <yuya@tcha.org>
parents: 38240
diff changeset
1060 sym = findsymbolicname(darg)
38243
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
1061 if not sym:
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
1062 raise
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1063 hint = _(b"keyword '%s' does not support member operation") % sym
38243
06d11cd90516 templater: promote getmember() to an interface of wrapped types
Yuya Nishihara <yuya@tcha.org>
parents: 38242
diff changeset
1064 raise error.ParseError(bytes(err), hint=hint)
34535
78590585c0db templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents: 34534
diff changeset
1065
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
1066
30115
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
1067 def runnegate(context, mapping, data):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
1068 data = evalinteger(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1069 context, mapping, data, _(b'negation needs an integer argument')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
1070 )
30115
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
1071 return -data
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
1072
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
1073
30115
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
1074 def runarithmetic(context, mapping, data):
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
1075 func, left, right = data
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
1076 left = evalinteger(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1077 context, mapping, left, _(b'arithmetic only defined on integers')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
1078 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
1079 right = evalinteger(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1080 context, mapping, right, _(b'arithmetic only defined on integers')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
1081 )
30116
1c01fa29630f templater: handle division by zero in arithmetic
Simon Farnsworth <simonfar@fb.com>
parents: 30115
diff changeset
1082 try:
1c01fa29630f templater: handle division by zero in arithmetic
Simon Farnsworth <simonfar@fb.com>
parents: 30115
diff changeset
1083 return func(left, right)
1c01fa29630f templater: handle division by zero in arithmetic
Simon Farnsworth <simonfar@fb.com>
parents: 30115
diff changeset
1084 except ZeroDivisionError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1085 raise error.Abort(_(b'division by zero is not defined'))
30115
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
1086
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42337
diff changeset
1087
37325
41a5d815d2c1 templater: factor out generator of join()-ed items
Yuya Nishihara <yuya@tcha.org>
parents: 37324
diff changeset
1088 def joinitems(itemiter, sep):
41a5d815d2c1 templater: factor out generator of join()-ed items
Yuya Nishihara <yuya@tcha.org>
parents: 37324
diff changeset
1089 """Join items with the separator; Returns generator of bytes"""
41a5d815d2c1 templater: factor out generator of join()-ed items
Yuya Nishihara <yuya@tcha.org>
parents: 37324
diff changeset
1090 first = True
41a5d815d2c1 templater: factor out generator of join()-ed items
Yuya Nishihara <yuya@tcha.org>
parents: 37324
diff changeset
1091 for x in itemiter:
41a5d815d2c1 templater: factor out generator of join()-ed items
Yuya Nishihara <yuya@tcha.org>
parents: 37324
diff changeset
1092 if first:
41a5d815d2c1 templater: factor out generator of join()-ed items
Yuya Nishihara <yuya@tcha.org>
parents: 37324
diff changeset
1093 first = False
37326
9cd88dd3bf64 templater: micro-optimize join() with empty separator
Yuya Nishihara <yuya@tcha.org>
parents: 37325
diff changeset
1094 elif sep:
37325
41a5d815d2c1 templater: factor out generator of join()-ed items
Yuya Nishihara <yuya@tcha.org>
parents: 37324
diff changeset
1095 yield sep
41a5d815d2c1 templater: factor out generator of join()-ed items
Yuya Nishihara <yuya@tcha.org>
parents: 37324
diff changeset
1096 yield x