Show More
@@ -173,89 +173,11 b' def supportedcompengines(ui, role):' | |||
|
173 | 173 | |
|
174 | 174 | return compengines |
|
175 | 175 | |
|
176 | class commandentry(object): | |
|
177 | """Represents a declared wire protocol command.""" | |
|
178 | def __init__(self, func, args='', transports=None, | |
|
179 | permission='push'): | |
|
180 | self.func = func | |
|
181 | self.args = args | |
|
182 | self.transports = transports or set() | |
|
183 | self.permission = permission | |
|
184 | ||
|
185 | def _merge(self, func, args): | |
|
186 | """Merge this instance with an incoming 2-tuple. | |
|
187 | ||
|
188 | This is called when a caller using the old 2-tuple API attempts | |
|
189 | to replace an instance. The incoming values are merged with | |
|
190 | data not captured by the 2-tuple and a new instance containing | |
|
191 | the union of the two objects is returned. | |
|
192 | """ | |
|
193 | return commandentry(func, args=args, transports=set(self.transports), | |
|
194 | permission=self.permission) | |
|
195 | ||
|
196 | # Old code treats instances as 2-tuples. So expose that interface. | |
|
197 | def __iter__(self): | |
|
198 | yield self.func | |
|
199 | yield self.args | |
|
200 | ||
|
201 | def __getitem__(self, i): | |
|
202 | if i == 0: | |
|
203 | return self.func | |
|
204 | elif i == 1: | |
|
205 | return self.args | |
|
206 | else: | |
|
207 | raise IndexError('can only access elements 0 and 1') | |
|
208 | ||
|
209 | class commanddict(dict): | |
|
210 | """Container for registered wire protocol commands. | |
|
211 | ||
|
212 | It behaves like a dict. But __setitem__ is overwritten to allow silent | |
|
213 | coercion of values from 2-tuples for API compatibility. | |
|
214 | """ | |
|
215 | def __setitem__(self, k, v): | |
|
216 | if isinstance(v, commandentry): | |
|
217 | pass | |
|
218 | # Cast 2-tuples to commandentry instances. | |
|
219 | elif isinstance(v, tuple): | |
|
220 | if len(v) != 2: | |
|
221 | raise ValueError('command tuples must have exactly 2 elements') | |
|
222 | ||
|
223 | # It is common for extensions to wrap wire protocol commands via | |
|
224 | # e.g. ``wireproto.commands[x] = (newfn, args)``. Because callers | |
|
225 | # doing this aren't aware of the new API that uses objects to store | |
|
226 | # command entries, we automatically merge old state with new. | |
|
227 | if k in self: | |
|
228 | v = self[k]._merge(v[0], v[1]) | |
|
229 | else: | |
|
230 | # Use default values from @wireprotocommand. | |
|
231 | v = commandentry(v[0], args=v[1], | |
|
232 | transports=set(wireprototypes.TRANSPORTS), | |
|
233 | permission='push') | |
|
234 | else: | |
|
235 | raise ValueError('command entries must be commandentry instances ' | |
|
236 | 'or 2-tuples') | |
|
237 | ||
|
238 | return super(commanddict, self).__setitem__(k, v) | |
|
239 | ||
|
240 | def commandavailable(self, command, proto): | |
|
241 | """Determine if a command is available for the requested protocol.""" | |
|
242 | assert proto.name in wireprototypes.TRANSPORTS | |
|
243 | ||
|
244 | entry = self.get(command) | |
|
245 | ||
|
246 | if not entry: | |
|
247 | return False | |
|
248 | ||
|
249 | if proto.name not in entry.transports: | |
|
250 | return False | |
|
251 | ||
|
252 | return True | |
|
253 | ||
|
254 | 176 | # For version 1 transports. |
|
255 | commands = commanddict() | |
|
177 | commands = wireprototypes.commanddict() | |
|
256 | 178 | |
|
257 | 179 | # For version 2 transports. |
|
258 | commandsv2 = commanddict() | |
|
180 | commandsv2 = wireprototypes.commanddict() | |
|
259 | 181 | |
|
260 | 182 | def wireprotocommand(name, args=None, permission='push'): |
|
261 | 183 | """Decorator to declare a wire protocol command. |
@@ -297,9 +219,8 b' def wireprotocommand(name, args=None, pe' | |||
|
297 | 219 | if name in commands: |
|
298 | 220 | raise error.ProgrammingError('%s command already registered ' |
|
299 | 221 | 'for version 1' % name) |
|
300 |
commands[name] = commandentry( |
|
|
301 | transports=transports, | |
|
302 | permission=permission) | |
|
222 | commands[name] = wireprototypes.commandentry( | |
|
223 | func, args=args, transports=transports, permission=permission) | |
|
303 | 224 | |
|
304 | 225 | return func |
|
305 | 226 | return register |
@@ -241,3 +241,81 b' class baseprotocolhandler(zi.Interface):' | |||
|
241 | 241 | doesn't have that permission, the exception should raise or abort |
|
242 | 242 | in a protocol specific manner. |
|
243 | 243 | """ |
|
244 | ||
|
245 | class commandentry(object): | |
|
246 | """Represents a declared wire protocol command.""" | |
|
247 | def __init__(self, func, args='', transports=None, | |
|
248 | permission='push'): | |
|
249 | self.func = func | |
|
250 | self.args = args | |
|
251 | self.transports = transports or set() | |
|
252 | self.permission = permission | |
|
253 | ||
|
254 | def _merge(self, func, args): | |
|
255 | """Merge this instance with an incoming 2-tuple. | |
|
256 | ||
|
257 | This is called when a caller using the old 2-tuple API attempts | |
|
258 | to replace an instance. The incoming values are merged with | |
|
259 | data not captured by the 2-tuple and a new instance containing | |
|
260 | the union of the two objects is returned. | |
|
261 | """ | |
|
262 | return commandentry(func, args=args, transports=set(self.transports), | |
|
263 | permission=self.permission) | |
|
264 | ||
|
265 | # Old code treats instances as 2-tuples. So expose that interface. | |
|
266 | def __iter__(self): | |
|
267 | yield self.func | |
|
268 | yield self.args | |
|
269 | ||
|
270 | def __getitem__(self, i): | |
|
271 | if i == 0: | |
|
272 | return self.func | |
|
273 | elif i == 1: | |
|
274 | return self.args | |
|
275 | else: | |
|
276 | raise IndexError('can only access elements 0 and 1') | |
|
277 | ||
|
278 | class commanddict(dict): | |
|
279 | """Container for registered wire protocol commands. | |
|
280 | ||
|
281 | It behaves like a dict. But __setitem__ is overwritten to allow silent | |
|
282 | coercion of values from 2-tuples for API compatibility. | |
|
283 | """ | |
|
284 | def __setitem__(self, k, v): | |
|
285 | if isinstance(v, commandentry): | |
|
286 | pass | |
|
287 | # Cast 2-tuples to commandentry instances. | |
|
288 | elif isinstance(v, tuple): | |
|
289 | if len(v) != 2: | |
|
290 | raise ValueError('command tuples must have exactly 2 elements') | |
|
291 | ||
|
292 | # It is common for extensions to wrap wire protocol commands via | |
|
293 | # e.g. ``wireproto.commands[x] = (newfn, args)``. Because callers | |
|
294 | # doing this aren't aware of the new API that uses objects to store | |
|
295 | # command entries, we automatically merge old state with new. | |
|
296 | if k in self: | |
|
297 | v = self[k]._merge(v[0], v[1]) | |
|
298 | else: | |
|
299 | # Use default values from @wireprotocommand. | |
|
300 | v = commandentry(v[0], args=v[1], | |
|
301 | transports=set(TRANSPORTS), | |
|
302 | permission='push') | |
|
303 | else: | |
|
304 | raise ValueError('command entries must be commandentry instances ' | |
|
305 | 'or 2-tuples') | |
|
306 | ||
|
307 | return super(commanddict, self).__setitem__(k, v) | |
|
308 | ||
|
309 | def commandavailable(self, command, proto): | |
|
310 | """Determine if a command is available for the requested protocol.""" | |
|
311 | assert proto.name in TRANSPORTS | |
|
312 | ||
|
313 | entry = self.get(command) | |
|
314 | ||
|
315 | if not entry: | |
|
316 | return False | |
|
317 | ||
|
318 | if proto.name not in entry.transports: | |
|
319 | return False | |
|
320 | ||
|
321 | return True |
@@ -438,7 +438,7 b' def wireprotocommand(name, args=None, pe' | |||
|
438 | 438 | raise error.ProgrammingError('%s command already registered ' |
|
439 | 439 | 'for version 2' % name) |
|
440 | 440 | |
|
441 | wireproto.commandsv2[name] = wireproto.commandentry( | |
|
441 | wireproto.commandsv2[name] = wireprototypes.commandentry( | |
|
442 | 442 | func, args=args, transports=transports, permission=permission) |
|
443 | 443 | |
|
444 | 444 | return func |
General Comments 0
You need to be logged in to leave comments.
Login now