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