##// END OF EJS Templates
wireproto: define and use types for wire protocol commands...
Gregory Szorc -
r35999:ef683a0f default
parent child Browse files
Show More
@@ -634,8 +634,64 b' def supportedcompengines(ui, proto, role'
634
634
635 return compengines
635 return compengines
636
636
637 # list of commands
637 class commandentry(object):
638 commands = {}
638 """Represents a declared wire protocol command."""
639 def __init__(self, func, args=''):
640 self.func = func
641 self.args = args
642
643 def _merge(self, func, args):
644 """Merge this instance with an incoming 2-tuple.
645
646 This is called when a caller using the old 2-tuple API attempts
647 to replace an instance. The incoming values are merged with
648 data not captured by the 2-tuple and a new instance containing
649 the union of the two objects is returned.
650 """
651 return commandentry(func, args)
652
653 # Old code treats instances as 2-tuples. So expose that interface.
654 def __iter__(self):
655 yield self.func
656 yield self.args
657
658 def __getitem__(self, i):
659 if i == 0:
660 return self.func
661 elif i == 1:
662 return self.args
663 else:
664 raise IndexError('can only access elements 0 and 1')
665
666 class commanddict(dict):
667 """Container for registered wire protocol commands.
668
669 It behaves like a dict. But __setitem__ is overwritten to allow silent
670 coercion of values from 2-tuples for API compatibility.
671 """
672 def __setitem__(self, k, v):
673 if isinstance(v, commandentry):
674 pass
675 # Cast 2-tuples to commandentry instances.
676 elif isinstance(v, tuple):
677 if len(v) != 2:
678 raise ValueError('command tuples must have exactly 2 elements')
679
680 # It is common for extensions to wrap wire protocol commands via
681 # e.g. ``wireproto.commands[x] = (newfn, args)``. Because callers
682 # doing this aren't aware of the new API that uses objects to store
683 # command entries, we automatically merge old state with new.
684 if k in self:
685 v = self[k]._merge(v[0], v[1])
686 else:
687 v = commandentry(v[0], v[1])
688 else:
689 raise ValueError('command entries must be commandentry instances '
690 'or 2-tuples')
691
692 return super(commanddict, self).__setitem__(k, v)
693
694 commands = commanddict()
639
695
640 def wireprotocommand(name, args=''):
696 def wireprotocommand(name, args=''):
641 """Decorator to declare a wire protocol command.
697 """Decorator to declare a wire protocol command.
@@ -646,7 +702,7 b" def wireprotocommand(name, args=''):"
646 accepts. ``*`` is a special value that says to accept all arguments.
702 accepts. ``*`` is a special value that says to accept all arguments.
647 """
703 """
648 def register(func):
704 def register(func):
649 commands[name] = (func, args)
705 commands[name] = commandentry(func, args)
650 return func
706 return func
651 return register
707 return register
652
708
General Comments 0
You need to be logged in to leave comments. Login now