# HG changeset patch # User Matt Harbison # Date 2024-12-16 07:41:24 # Node ID 1554bd50a1afc4dbb7ec80691119780c480e9aea # Parent 5cf81d8d7de1a79300f80131f11438638a25da2d interfaces: move peer `capabilities()` to the `ipeercapabilities` interface I'm not sure why this was on the `ipeercommands` interface. It appears to be because these interfaces started out as `_basewirecommands` to hold wire commands, back in 558f5b2ee10e. The capabilities interface wasn't split out until 98861a2298b5, when it pulled the capability related methods off of the `ipeerbase` interface. Perhaps it was an oversight to not look at the commands interface because, while this is a wire command, both `sshpeer` and `httppeer` now perform a handshake while instantiating the peer object, and cache a fixed list of capabilities in that object. Likewise, `localpeer` is given a fixed set of capabilities when instantiated. Back in 558f5b2ee10e, `httppeer` looks like it issued a wire command when this method was called, but `sshpeer` obtained and cached the capabilities when instantiated, and this method always returned a fixed value. There's a perfectly good interface with other capability related methods, and having it here makes it easier to implement the base `peer` mixin class. diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py --- a/mercurial/httppeer.py +++ b/mercurial/httppeer.py @@ -437,11 +437,13 @@ class httppeer(wireprotov1peer.wirepeer) # End of ipeerconnection interface. - # Begin of ipeercommands interface. + # Begin of ipeercapabilities interface. def capabilities(self): return self._caps + # End of ipeercapabilities interface. + def _finish_inline_clone_bundle(self, stream): # HTTP streams must hit the end to process the last empty # chunk of Chunked-Encoding so the connection can be reused. @@ -449,8 +451,6 @@ class httppeer(wireprotov1peer.wirepeer) if chunk: self._abort(error.ResponseError(_(b"unexpected response:"), chunk)) - # End of ipeercommands interface. - def _callstream(self, cmd, _compressible=False, **args): args = pycompat.byteskwargs(args) diff --git a/mercurial/interfaces/repository.py b/mercurial/interfaces/repository.py --- a/mercurial/interfaces/repository.py +++ b/mercurial/interfaces/repository.py @@ -205,6 +205,13 @@ class ipeercapabilities(Protocol): """ @abc.abstractmethod + def capabilities(self): + """Obtain capabilities of the peer. + + Returns a set of string capabilities. + """ + + @abc.abstractmethod def requirecap(self, name: bytes, purpose: bytes) -> None: """Require a capability to be present. @@ -228,13 +235,6 @@ class ipeercommands(Protocol): """ @abc.abstractmethod - def capabilities(self): - """Obtain capabilities of the peer. - - Returns a set of string capabilities. - """ - - @abc.abstractmethod def get_cached_bundle_inline(self, path): """Retrieve a clonebundle across the wire. @@ -470,9 +470,7 @@ class peer(_ipeerconnection, ipeercapabi self.path = path def capable(self, name: bytes) -> bool | bytes: - # TODO: this class should maybe subclass ipeercommands too, otherwise it - # is assuming whatever uses this as a mixin also has this interface. - caps = self.capabilities() # pytype: disable=attribute-error + caps = self.capabilities() if name in caps: return True diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -339,14 +339,18 @@ class localpeer(repository.peer): # (re # End of _basepeer interface. + # Begin of ipeercapabilities interface. + + def capabilities(self): + return self._caps + + # End of ipeercapabilities interface. + # Begin of _basewirecommands interface. def branchmap(self): return self._repo.branchmap() - def capabilities(self): - return self._caps - def get_cached_bundle_inline(self, path): # not needed with local peer raise NotImplementedError diff --git a/mercurial/sshpeer.py b/mercurial/sshpeer.py --- a/mercurial/sshpeer.py +++ b/mercurial/sshpeer.py @@ -439,12 +439,12 @@ class sshv1peer(wireprotov1peer.wirepeer # End of ipeerconnection interface. - # Begin of ipeercommands interface. + # Begin of ipeercapabilities interface. def capabilities(self): return self._caps - # End of ipeercommands interface. + # End of ipeercapabilities interface. def _readerr(self): _forwardoutput(self.ui, self._pipee)