D335: localrepo: use peer interfaces

indygreg (Gregory Szorc) phabricator at mercurial-scm.org
Fri Aug 11 04:20:54 UTC 2017


indygreg created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  We now have a formal abstract base class for peers. Let's
  transition the peer classes in localrepo to it.
  
  As part of the transition, we reorder methods so they are grouped
  by interface and match the order they are defined in the interface.
  We also had to change self.ui from an instance attribute to a
  property to satisfy the @abstractproperty requirement.
  
  As part of this change, we uncover the first "bug" as part of
  enforcing interfaces: stream_out() wasn't implemented on localpeer!
  This isn't technically a bug since the repo isn't advertising the
  stream capability, so clients shouldn't be attempting to call it.
  But I don't think there's a good reason why this is the case.
  We implement a dummy method to satisfy the interface requriements.
  We can make localpeer instances streamable as a future enhancement.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D335

AFFECTED FILES
  mercurial/localrepo.py

CHANGE DETAILS

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -49,6 +49,7 @@
     phases,
     pushkey,
     pycompat,
+    repository,
     repoview,
     revset,
     revsetlang,
@@ -144,43 +145,52 @@
               'unbundle'}
 legacycaps = moderncaps.union({'changegroupsubset'})
 
-class localpeer(peer.peerrepository):
+class localpeer(repository.peer):
     '''peer for a local repo; reflects only the most recent API'''
 
     def __init__(self, repo, caps=None):
+        super(localpeer, self).__init__()
+
         if caps is None:
             caps = moderncaps.copy()
-        peer.peerrepository.__init__(self)
         self._repo = repo.filtered('served')
-        self.ui = repo.ui
+        self._ui = repo.ui
         self._caps = repo._restrictcapabilities(caps)
 
+    # Begin of _basepeer interface.
+
+    @util.propertycache
+    def ui(self):
+        return self._ui
+
+    def url(self):
+        return self._repo.url()
+
+    def local(self):
+        return self._repo
+
+    def peer(self):
+        return self
+
+    def canpush(self):
+        return True
+
     def close(self):
         self._repo.close()
 
-    def _capabilities(self):
-        return self._caps
-
-    def local(self):
-        return self._repo
+    # End of _basepeer interface.
 
-    def canpush(self):
-        return True
-
-    def url(self):
-        return self._repo.url()
-
-    def lookup(self, key):
-        return self._repo.lookup(key)
+    # Begin of _basewirecommands interface.
 
     def branchmap(self):
         return self._repo.branchmap()
 
-    def heads(self):
-        return self._repo.heads()
+    def capabilities(self):
+        return self._caps
 
-    def known(self, nodes):
-        return self._repo.known(nodes)
+    def debugwireargs(self, one, two, three=None, four=None, five=None):
+        """Used to test argument passing over the wire"""
+        return "%s %s %s %s %s" % (one, two, three, four, five)
 
     def getbundle(self, source, heads=None, common=None, bundlecaps=None,
                   **kwargs):
@@ -197,8 +207,24 @@
         else:
             return changegroup.getunbundler('01', cb, None)
 
-    # TODO We might want to move the next two calls into legacypeer and add
-    # unbundle instead.
+    def heads(self):
+        return self._repo.heads()
+
+    def known(self, nodes):
+        return self._repo.known(nodes)
+
+    def listkeys(self, namespace):
+        return self._repo.listkeys(namespace)
+
+    def lookup(self, key):
+        return self._repo.lookup(key)
+
+    def pushkey(self, namespace, key, old, new):
+        return self._repo.pushkey(namespace, key, old, new)
+
+    def stream_out(self):
+        raise error.Abort(_('cannot perform stream clone against local '
+                            'peer'))
 
     def unbundle(self, cg, heads, url):
         """apply a bundle on a repo
@@ -235,35 +261,38 @@
         except error.PushRaced as exc:
             raise error.ResponseError(_('push failed:'), str(exc))
 
-    def pushkey(self, namespace, key, old, new):
-        return self._repo.pushkey(namespace, key, old, new)
+    # End of _basewirecommands interface.
 
-    def listkeys(self, namespace):
-        return self._repo.listkeys(namespace)
+    # Begin of peer interface.
 
-    def debugwireargs(self, one, two, three=None, four=None, five=None):
-        '''used to test argument passing over the wire'''
-        return "%s %s %s %s %s" % (one, two, three, four, five)
+    def iterbatch(self):
+        return peer.localiterbatcher(self)
 
-class locallegacypeer(localpeer):
+    # End of peer interface.
+
+class locallegacypeer(repository.legacypeer, localpeer):
     '''peer extension which implements legacy methods too; used for tests with
     restricted capabilities'''
 
     def __init__(self, repo):
-        localpeer.__init__(self, repo, caps=legacycaps)
+        super(locallegacypeer, self).__init__(repo, caps=legacycaps)
+
+    # Begin of baselegacywirecommands interface.
+
+    def between(self, pairs):
+        return self._repo.between(pairs)
 
     def branches(self, nodes):
         return self._repo.branches(nodes)
 
-    def between(self, pairs):
-        return self._repo.between(pairs)
-
     def changegroup(self, basenodes, source):
         return changegroup.changegroup(self._repo, basenodes, source)
 
     def changegroupsubset(self, bases, heads, source):
         return changegroup.changegroupsubset(self._repo, bases, heads, source)
 
+    # End of baselegacywirecommands interface.
+
 # Increment the sub-version when the revlog v2 format changes to lock out old
 # clients.
 REVLOGV2_REQUIREMENT = 'exp-revlogv2.0'



To: indygreg, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list