changeset 37781:352932a11905

wireproto: move command registration types to wireprototypes These are shared across wire protocol implementations. wireprototypes is our module for common code. Differential Revision: https://phab.mercurial-scm.org/D3396
author Gregory Szorc <gregory.szorc@gmail.com>
date Mon, 16 Apr 2018 21:52:33 -0700
parents 8acd3a9ac4fd
children 99accae4cc59
files mercurial/wireproto.py mercurial/wireprototypes.py mercurial/wireprotov2server.py
diffstat 3 files changed, 83 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/wireproto.py	Mon Apr 16 21:49:59 2018 -0700
+++ b/mercurial/wireproto.py	Mon Apr 16 21:52:33 2018 -0700
@@ -173,89 +173,11 @@
 
     return compengines
 
-class commandentry(object):
-    """Represents a declared wire protocol command."""
-    def __init__(self, func, args='', transports=None,
-                 permission='push'):
-        self.func = func
-        self.args = args
-        self.transports = transports or set()
-        self.permission = permission
-
-    def _merge(self, func, args):
-        """Merge this instance with an incoming 2-tuple.
-
-        This is called when a caller using the old 2-tuple API attempts
-        to replace an instance. The incoming values are merged with
-        data not captured by the 2-tuple and a new instance containing
-        the union of the two objects is returned.
-        """
-        return commandentry(func, args=args, transports=set(self.transports),
-                            permission=self.permission)
-
-    # Old code treats instances as 2-tuples. So expose that interface.
-    def __iter__(self):
-        yield self.func
-        yield self.args
-
-    def __getitem__(self, i):
-        if i == 0:
-            return self.func
-        elif i == 1:
-            return self.args
-        else:
-            raise IndexError('can only access elements 0 and 1')
-
-class commanddict(dict):
-    """Container for registered wire protocol commands.
-
-    It behaves like a dict. But __setitem__ is overwritten to allow silent
-    coercion of values from 2-tuples for API compatibility.
-    """
-    def __setitem__(self, k, v):
-        if isinstance(v, commandentry):
-            pass
-        # Cast 2-tuples to commandentry instances.
-        elif isinstance(v, tuple):
-            if len(v) != 2:
-                raise ValueError('command tuples must have exactly 2 elements')
-
-            # It is common for extensions to wrap wire protocol commands via
-            # e.g. ``wireproto.commands[x] = (newfn, args)``. Because callers
-            # doing this aren't aware of the new API that uses objects to store
-            # command entries, we automatically merge old state with new.
-            if k in self:
-                v = self[k]._merge(v[0], v[1])
-            else:
-                # Use default values from @wireprotocommand.
-                v = commandentry(v[0], args=v[1],
-                                 transports=set(wireprototypes.TRANSPORTS),
-                                 permission='push')
-        else:
-            raise ValueError('command entries must be commandentry instances '
-                             'or 2-tuples')
-
-        return super(commanddict, self).__setitem__(k, v)
-
-    def commandavailable(self, command, proto):
-        """Determine if a command is available for the requested protocol."""
-        assert proto.name in wireprototypes.TRANSPORTS
-
-        entry = self.get(command)
-
-        if not entry:
-            return False
-
-        if proto.name not in entry.transports:
-            return False
-
-        return True
-
 # For version 1 transports.
-commands = commanddict()
+commands = wireprototypes.commanddict()
 
 # For version 2 transports.
-commandsv2 = commanddict()
+commandsv2 = wireprototypes.commanddict()
 
 def wireprotocommand(name, args=None, permission='push'):
     """Decorator to declare a wire protocol command.
@@ -297,9 +219,8 @@
         if name in commands:
             raise error.ProgrammingError('%s command already registered '
                                          'for version 1' % name)
-        commands[name] = commandentry(func, args=args,
-                                      transports=transports,
-                                      permission=permission)
+        commands[name] = wireprototypes.commandentry(
+            func, args=args, transports=transports, permission=permission)
 
         return func
     return register
--- a/mercurial/wireprototypes.py	Mon Apr 16 21:49:59 2018 -0700
+++ b/mercurial/wireprototypes.py	Mon Apr 16 21:52:33 2018 -0700
@@ -241,3 +241,81 @@
         doesn't have that permission, the exception should raise or abort
         in a protocol specific manner.
         """
+
+class commandentry(object):
+    """Represents a declared wire protocol command."""
+    def __init__(self, func, args='', transports=None,
+                 permission='push'):
+        self.func = func
+        self.args = args
+        self.transports = transports or set()
+        self.permission = permission
+
+    def _merge(self, func, args):
+        """Merge this instance with an incoming 2-tuple.
+
+        This is called when a caller using the old 2-tuple API attempts
+        to replace an instance. The incoming values are merged with
+        data not captured by the 2-tuple and a new instance containing
+        the union of the two objects is returned.
+        """
+        return commandentry(func, args=args, transports=set(self.transports),
+                            permission=self.permission)
+
+    # Old code treats instances as 2-tuples. So expose that interface.
+    def __iter__(self):
+        yield self.func
+        yield self.args
+
+    def __getitem__(self, i):
+        if i == 0:
+            return self.func
+        elif i == 1:
+            return self.args
+        else:
+            raise IndexError('can only access elements 0 and 1')
+
+class commanddict(dict):
+    """Container for registered wire protocol commands.
+
+    It behaves like a dict. But __setitem__ is overwritten to allow silent
+    coercion of values from 2-tuples for API compatibility.
+    """
+    def __setitem__(self, k, v):
+        if isinstance(v, commandentry):
+            pass
+        # Cast 2-tuples to commandentry instances.
+        elif isinstance(v, tuple):
+            if len(v) != 2:
+                raise ValueError('command tuples must have exactly 2 elements')
+
+            # It is common for extensions to wrap wire protocol commands via
+            # e.g. ``wireproto.commands[x] = (newfn, args)``. Because callers
+            # doing this aren't aware of the new API that uses objects to store
+            # command entries, we automatically merge old state with new.
+            if k in self:
+                v = self[k]._merge(v[0], v[1])
+            else:
+                # Use default values from @wireprotocommand.
+                v = commandentry(v[0], args=v[1],
+                                 transports=set(TRANSPORTS),
+                                 permission='push')
+        else:
+            raise ValueError('command entries must be commandentry instances '
+                             'or 2-tuples')
+
+        return super(commanddict, self).__setitem__(k, v)
+
+    def commandavailable(self, command, proto):
+        """Determine if a command is available for the requested protocol."""
+        assert proto.name in TRANSPORTS
+
+        entry = self.get(command)
+
+        if not entry:
+            return False
+
+        if proto.name not in entry.transports:
+            return False
+
+        return True
--- a/mercurial/wireprotov2server.py	Mon Apr 16 21:49:59 2018 -0700
+++ b/mercurial/wireprotov2server.py	Mon Apr 16 21:52:33 2018 -0700
@@ -438,7 +438,7 @@
             raise error.ProgrammingError('%s command already registered '
                                          'for version 2' % name)
 
-        wireproto.commandsv2[name] = wireproto.commandentry(
+        wireproto.commandsv2[name] = wireprototypes.commandentry(
             func, args=args, transports=transports, permission=permission)
 
         return func