##// END OF EJS Templates
registrar: unindent superfluous "if True" block
Yuya Nishihara -
r32339:92de09a0 default
parent child Browse files
Show More
@@ -1,303 +1,302 b''
1 # registrar.py - utilities to register function for specific purpose
1 # registrar.py - utilities to register function for specific purpose
2 #
2 #
3 # Copyright FUJIWARA Katsunori <foozy@lares.dti.ne.jp> and others
3 # Copyright FUJIWARA Katsunori <foozy@lares.dti.ne.jp> and others
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 from . import (
10 from . import (
11 error,
11 error,
12 pycompat,
12 pycompat,
13 util,
13 util,
14 )
14 )
15
15
16 class _funcregistrarbase(object):
16 class _funcregistrarbase(object):
17 """Base of decorator to register a function for specific purpose
17 """Base of decorator to register a function for specific purpose
18
18
19 This decorator stores decorated functions into own dict 'table'.
19 This decorator stores decorated functions into own dict 'table'.
20
20
21 The least derived class can be defined by overriding 'formatdoc',
21 The least derived class can be defined by overriding 'formatdoc',
22 for example::
22 for example::
23
23
24 class keyword(_funcregistrarbase):
24 class keyword(_funcregistrarbase):
25 _docformat = ":%s: %s"
25 _docformat = ":%s: %s"
26
26
27 This should be used as below:
27 This should be used as below:
28
28
29 keyword = registrar.keyword()
29 keyword = registrar.keyword()
30
30
31 @keyword('bar')
31 @keyword('bar')
32 def barfunc(*args, **kwargs):
32 def barfunc(*args, **kwargs):
33 '''Explanation of bar keyword ....
33 '''Explanation of bar keyword ....
34 '''
34 '''
35 pass
35 pass
36
36
37 In this case:
37 In this case:
38
38
39 - 'barfunc' is stored as 'bar' in '_table' of an instance 'keyword' above
39 - 'barfunc' is stored as 'bar' in '_table' of an instance 'keyword' above
40 - 'barfunc.__doc__' becomes ":bar: Explanation of bar keyword"
40 - 'barfunc.__doc__' becomes ":bar: Explanation of bar keyword"
41 """
41 """
42 def __init__(self, table=None):
42 def __init__(self, table=None):
43 if table is None:
43 if table is None:
44 self._table = {}
44 self._table = {}
45 else:
45 else:
46 self._table = table
46 self._table = table
47
47
48 def __call__(self, decl, *args, **kwargs):
48 def __call__(self, decl, *args, **kwargs):
49 return lambda func: self._doregister(func, decl, *args, **kwargs)
49 return lambda func: self._doregister(func, decl, *args, **kwargs)
50
50
51 def _doregister(self, func, decl, *args, **kwargs):
51 def _doregister(self, func, decl, *args, **kwargs):
52 name = self._getname(decl)
52 name = self._getname(decl)
53
53
54 if name in self._table:
54 if name in self._table:
55 msg = 'duplicate registration for name: "%s"' % name
55 msg = 'duplicate registration for name: "%s"' % name
56 raise error.ProgrammingError(msg)
56 raise error.ProgrammingError(msg)
57
57
58 if func.__doc__ and not util.safehasattr(func, '_origdoc'):
58 if func.__doc__ and not util.safehasattr(func, '_origdoc'):
59 doc = pycompat.sysbytes(func.__doc__).strip()
59 doc = pycompat.sysbytes(func.__doc__).strip()
60 func._origdoc = doc
60 func._origdoc = doc
61 func.__doc__ = pycompat.sysstr(self._formatdoc(decl, doc))
61 func.__doc__ = pycompat.sysstr(self._formatdoc(decl, doc))
62
62
63 self._table[name] = func
63 self._table[name] = func
64 self._extrasetup(name, func, *args, **kwargs)
64 self._extrasetup(name, func, *args, **kwargs)
65
65
66 return func
66 return func
67
67
68 def _parsefuncdecl(self, decl):
68 def _parsefuncdecl(self, decl):
69 """Parse function declaration and return the name of function in it
69 """Parse function declaration and return the name of function in it
70 """
70 """
71 i = decl.find('(')
71 i = decl.find('(')
72 if i >= 0:
72 if i >= 0:
73 return decl[:i]
73 return decl[:i]
74 else:
74 else:
75 return decl
75 return decl
76
76
77 def _getname(self, decl):
77 def _getname(self, decl):
78 """Return the name of the registered function from decl
78 """Return the name of the registered function from decl
79
79
80 Derived class should override this, if it allows more
80 Derived class should override this, if it allows more
81 descriptive 'decl' string than just a name.
81 descriptive 'decl' string than just a name.
82 """
82 """
83 return decl
83 return decl
84
84
85 _docformat = None
85 _docformat = None
86
86
87 def _formatdoc(self, decl, doc):
87 def _formatdoc(self, decl, doc):
88 """Return formatted document of the registered function for help
88 """Return formatted document of the registered function for help
89
89
90 'doc' is '__doc__.strip()' of the registered function.
90 'doc' is '__doc__.strip()' of the registered function.
91 """
91 """
92 return self._docformat % (decl, doc)
92 return self._docformat % (decl, doc)
93
93
94 def _extrasetup(self, name, func):
94 def _extrasetup(self, name, func):
95 """Execute exra setup for registered function, if needed
95 """Execute exra setup for registered function, if needed
96 """
96 """
97 pass
97 pass
98
98
99 class command(_funcregistrarbase):
99 class command(_funcregistrarbase):
100 """Decorator to register a command function to table
100 """Decorator to register a command function to table
101
101
102 This class receives a command table as its argument. The table should
102 This class receives a command table as its argument. The table should
103 be a dict.
103 be a dict.
104
104
105 The created object can be used as a decorator for adding commands to
105 The created object can be used as a decorator for adding commands to
106 that command table. This accepts multiple arguments to define a command.
106 that command table. This accepts multiple arguments to define a command.
107
107
108 The first argument is the command name.
108 The first argument is the command name.
109
109
110 The options argument is an iterable of tuples defining command arguments.
110 The options argument is an iterable of tuples defining command arguments.
111 See ``mercurial.fancyopts.fancyopts()`` for the format of each tuple.
111 See ``mercurial.fancyopts.fancyopts()`` for the format of each tuple.
112
112
113 The synopsis argument defines a short, one line summary of how to use the
113 The synopsis argument defines a short, one line summary of how to use the
114 command. This shows up in the help output.
114 command. This shows up in the help output.
115
115
116 The norepo argument defines whether the command does not require a
116 The norepo argument defines whether the command does not require a
117 local repository. Most commands operate against a repository, thus the
117 local repository. Most commands operate against a repository, thus the
118 default is False.
118 default is False.
119
119
120 The optionalrepo argument defines whether the command optionally requires
120 The optionalrepo argument defines whether the command optionally requires
121 a local repository.
121 a local repository.
122
122
123 The inferrepo argument defines whether to try to find a repository from the
123 The inferrepo argument defines whether to try to find a repository from the
124 command line arguments. If True, arguments will be examined for potential
124 command line arguments. If True, arguments will be examined for potential
125 repository locations. See ``findrepo()``. If a repository is found, it
125 repository locations. See ``findrepo()``. If a repository is found, it
126 will be used.
126 will be used.
127 """
127 """
128
128
129 def _doregister(self, func, name, options=(), synopsis=None,
129 def _doregister(self, func, name, options=(), synopsis=None,
130 norepo=False, optionalrepo=False, inferrepo=False):
130 norepo=False, optionalrepo=False, inferrepo=False):
131 if True:
131 func.norepo = norepo
132 func.norepo = norepo
132 func.optionalrepo = optionalrepo
133 func.optionalrepo = optionalrepo
133 func.inferrepo = inferrepo
134 func.inferrepo = inferrepo
134 if synopsis:
135 if synopsis:
135 self._table[name] = func, list(options), synopsis
136 self._table[name] = func, list(options), synopsis
136 else:
137 else:
137 self._table[name] = func, list(options)
138 self._table[name] = func, list(options)
138 return func
139 return func
140
139
141 class revsetpredicate(_funcregistrarbase):
140 class revsetpredicate(_funcregistrarbase):
142 """Decorator to register revset predicate
141 """Decorator to register revset predicate
143
142
144 Usage::
143 Usage::
145
144
146 revsetpredicate = registrar.revsetpredicate()
145 revsetpredicate = registrar.revsetpredicate()
147
146
148 @revsetpredicate('mypredicate(arg1, arg2[, arg3])')
147 @revsetpredicate('mypredicate(arg1, arg2[, arg3])')
149 def mypredicatefunc(repo, subset, x):
148 def mypredicatefunc(repo, subset, x):
150 '''Explanation of this revset predicate ....
149 '''Explanation of this revset predicate ....
151 '''
150 '''
152 pass
151 pass
153
152
154 The first string argument is used also in online help.
153 The first string argument is used also in online help.
155
154
156 Optional argument 'safe' indicates whether a predicate is safe for
155 Optional argument 'safe' indicates whether a predicate is safe for
157 DoS attack (False by default).
156 DoS attack (False by default).
158
157
159 Optional argument 'takeorder' indicates whether a predicate function
158 Optional argument 'takeorder' indicates whether a predicate function
160 takes ordering policy as the last argument.
159 takes ordering policy as the last argument.
161
160
162 'revsetpredicate' instance in example above can be used to
161 'revsetpredicate' instance in example above can be used to
163 decorate multiple functions.
162 decorate multiple functions.
164
163
165 Decorated functions are registered automatically at loading
164 Decorated functions are registered automatically at loading
166 extension, if an instance named as 'revsetpredicate' is used for
165 extension, if an instance named as 'revsetpredicate' is used for
167 decorating in extension.
166 decorating in extension.
168
167
169 Otherwise, explicit 'revset.loadpredicate()' is needed.
168 Otherwise, explicit 'revset.loadpredicate()' is needed.
170 """
169 """
171 _getname = _funcregistrarbase._parsefuncdecl
170 _getname = _funcregistrarbase._parsefuncdecl
172 _docformat = "``%s``\n %s"
171 _docformat = "``%s``\n %s"
173
172
174 def _extrasetup(self, name, func, safe=False, takeorder=False):
173 def _extrasetup(self, name, func, safe=False, takeorder=False):
175 func._safe = safe
174 func._safe = safe
176 func._takeorder = takeorder
175 func._takeorder = takeorder
177
176
178 class filesetpredicate(_funcregistrarbase):
177 class filesetpredicate(_funcregistrarbase):
179 """Decorator to register fileset predicate
178 """Decorator to register fileset predicate
180
179
181 Usage::
180 Usage::
182
181
183 filesetpredicate = registrar.filesetpredicate()
182 filesetpredicate = registrar.filesetpredicate()
184
183
185 @filesetpredicate('mypredicate()')
184 @filesetpredicate('mypredicate()')
186 def mypredicatefunc(mctx, x):
185 def mypredicatefunc(mctx, x):
187 '''Explanation of this fileset predicate ....
186 '''Explanation of this fileset predicate ....
188 '''
187 '''
189 pass
188 pass
190
189
191 The first string argument is used also in online help.
190 The first string argument is used also in online help.
192
191
193 Optional argument 'callstatus' indicates whether a predicate
192 Optional argument 'callstatus' indicates whether a predicate
194 implies 'matchctx.status()' at runtime or not (False, by
193 implies 'matchctx.status()' at runtime or not (False, by
195 default).
194 default).
196
195
197 Optional argument 'callexisting' indicates whether a predicate
196 Optional argument 'callexisting' indicates whether a predicate
198 implies 'matchctx.existing()' at runtime or not (False, by
197 implies 'matchctx.existing()' at runtime or not (False, by
199 default).
198 default).
200
199
201 'filesetpredicate' instance in example above can be used to
200 'filesetpredicate' instance in example above can be used to
202 decorate multiple functions.
201 decorate multiple functions.
203
202
204 Decorated functions are registered automatically at loading
203 Decorated functions are registered automatically at loading
205 extension, if an instance named as 'filesetpredicate' is used for
204 extension, if an instance named as 'filesetpredicate' is used for
206 decorating in extension.
205 decorating in extension.
207
206
208 Otherwise, explicit 'fileset.loadpredicate()' is needed.
207 Otherwise, explicit 'fileset.loadpredicate()' is needed.
209 """
208 """
210 _getname = _funcregistrarbase._parsefuncdecl
209 _getname = _funcregistrarbase._parsefuncdecl
211 _docformat = "``%s``\n %s"
210 _docformat = "``%s``\n %s"
212
211
213 def _extrasetup(self, name, func, callstatus=False, callexisting=False):
212 def _extrasetup(self, name, func, callstatus=False, callexisting=False):
214 func._callstatus = callstatus
213 func._callstatus = callstatus
215 func._callexisting = callexisting
214 func._callexisting = callexisting
216
215
217 class _templateregistrarbase(_funcregistrarbase):
216 class _templateregistrarbase(_funcregistrarbase):
218 """Base of decorator to register functions as template specific one
217 """Base of decorator to register functions as template specific one
219 """
218 """
220 _docformat = ":%s: %s"
219 _docformat = ":%s: %s"
221
220
222 class templatekeyword(_templateregistrarbase):
221 class templatekeyword(_templateregistrarbase):
223 """Decorator to register template keyword
222 """Decorator to register template keyword
224
223
225 Usage::
224 Usage::
226
225
227 templatekeyword = registrar.templatekeyword()
226 templatekeyword = registrar.templatekeyword()
228
227
229 @templatekeyword('mykeyword')
228 @templatekeyword('mykeyword')
230 def mykeywordfunc(repo, ctx, templ, cache, revcache, **args):
229 def mykeywordfunc(repo, ctx, templ, cache, revcache, **args):
231 '''Explanation of this template keyword ....
230 '''Explanation of this template keyword ....
232 '''
231 '''
233 pass
232 pass
234
233
235 The first string argument is used also in online help.
234 The first string argument is used also in online help.
236
235
237 'templatekeyword' instance in example above can be used to
236 'templatekeyword' instance in example above can be used to
238 decorate multiple functions.
237 decorate multiple functions.
239
238
240 Decorated functions are registered automatically at loading
239 Decorated functions are registered automatically at loading
241 extension, if an instance named as 'templatekeyword' is used for
240 extension, if an instance named as 'templatekeyword' is used for
242 decorating in extension.
241 decorating in extension.
243
242
244 Otherwise, explicit 'templatekw.loadkeyword()' is needed.
243 Otherwise, explicit 'templatekw.loadkeyword()' is needed.
245 """
244 """
246
245
247 class templatefilter(_templateregistrarbase):
246 class templatefilter(_templateregistrarbase):
248 """Decorator to register template filer
247 """Decorator to register template filer
249
248
250 Usage::
249 Usage::
251
250
252 templatefilter = registrar.templatefilter()
251 templatefilter = registrar.templatefilter()
253
252
254 @templatefilter('myfilter')
253 @templatefilter('myfilter')
255 def myfilterfunc(text):
254 def myfilterfunc(text):
256 '''Explanation of this template filter ....
255 '''Explanation of this template filter ....
257 '''
256 '''
258 pass
257 pass
259
258
260 The first string argument is used also in online help.
259 The first string argument is used also in online help.
261
260
262 'templatefilter' instance in example above can be used to
261 'templatefilter' instance in example above can be used to
263 decorate multiple functions.
262 decorate multiple functions.
264
263
265 Decorated functions are registered automatically at loading
264 Decorated functions are registered automatically at loading
266 extension, if an instance named as 'templatefilter' is used for
265 extension, if an instance named as 'templatefilter' is used for
267 decorating in extension.
266 decorating in extension.
268
267
269 Otherwise, explicit 'templatefilters.loadkeyword()' is needed.
268 Otherwise, explicit 'templatefilters.loadkeyword()' is needed.
270 """
269 """
271
270
272 class templatefunc(_templateregistrarbase):
271 class templatefunc(_templateregistrarbase):
273 """Decorator to register template function
272 """Decorator to register template function
274
273
275 Usage::
274 Usage::
276
275
277 templatefunc = registrar.templatefunc()
276 templatefunc = registrar.templatefunc()
278
277
279 @templatefunc('myfunc(arg1, arg2[, arg3])', argspec='arg1 arg2 arg3')
278 @templatefunc('myfunc(arg1, arg2[, arg3])', argspec='arg1 arg2 arg3')
280 def myfuncfunc(context, mapping, args):
279 def myfuncfunc(context, mapping, args):
281 '''Explanation of this template function ....
280 '''Explanation of this template function ....
282 '''
281 '''
283 pass
282 pass
284
283
285 The first string argument is used also in online help.
284 The first string argument is used also in online help.
286
285
287 If optional 'argspec' is defined, the function will receive 'args' as
286 If optional 'argspec' is defined, the function will receive 'args' as
288 a dict of named arguments. Otherwise 'args' is a list of positional
287 a dict of named arguments. Otherwise 'args' is a list of positional
289 arguments.
288 arguments.
290
289
291 'templatefunc' instance in example above can be used to
290 'templatefunc' instance in example above can be used to
292 decorate multiple functions.
291 decorate multiple functions.
293
292
294 Decorated functions are registered automatically at loading
293 Decorated functions are registered automatically at loading
295 extension, if an instance named as 'templatefunc' is used for
294 extension, if an instance named as 'templatefunc' is used for
296 decorating in extension.
295 decorating in extension.
297
296
298 Otherwise, explicit 'templater.loadfunction()' is needed.
297 Otherwise, explicit 'templater.loadfunction()' is needed.
299 """
298 """
300 _getname = _funcregistrarbase._parsefuncdecl
299 _getname = _funcregistrarbase._parsefuncdecl
301
300
302 def _extrasetup(self, name, func, argspec=None):
301 def _extrasetup(self, name, func, argspec=None):
303 func._argspec = argspec
302 func._argspec = argspec
General Comments 0
You need to be logged in to leave comments. Login now