# HG changeset patch # User Matt Harbison # Date 1728098501 14400 # Node ID fa7059f031a97d0a1b15e57945e23f2f55e717ef # Parent 936f85b243a88f7981a26ae516617b0d5a488618 interfaces: introduce and use a protocol class for the `base85` module See f2832de2a46c for details when this was done for the `bdiff` module. It looks like PEP-688 removed the special casing of `bytes` being a standin for any type of `ByteString`, and defines a `typing.Buffer` class (with a backport in `typing_extensions` for Python prior to 3.12). There's been a lot of churn in this area with pytype, but recent versions of pytype and PyCharm recognize this, and e.g. have `mercurial.node.hex()` defined as: from typing_extensions import Buffer def hex(data: Buffer, sep: str | bytes = ..., bytes_per_sep: int = ...) -> bytes This covers `bytes`, `bytearray`, and `memoryview` by default. Both of the C functions here use `y#` to parse the arguments, which means the arg is a byte-like object[2], so the args would appear to be better typed as `Buffer`. However, pytype has a bug that prevents using this from `typing_extensions`[3], and mypy complained `Unsupported left operand type for + ("memoryview")` in the pure module on line 37 (meaning it's only a subset of `Buffer`). So hold off on changing any of that for now. [1] https://peps.python.org/pep-0688/#no-special-meaning-for-bytes [2] https://docs.python.org/3/glossary.html#term-bytes-like-object [3] https://github.com/google/pytype/issues/1772 diff -r 936f85b243a8 -r fa7059f031a9 mercurial/interfaces/modules.py --- a/mercurial/interfaces/modules.py Fri Oct 04 23:09:56 2024 -0400 +++ b/mercurial/interfaces/modules.py Fri Oct 04 23:21:41 2024 -0400 @@ -23,6 +23,16 @@ """The signature of `bdiff.blocks()` and `bdiff.xdiffblocks()`.""" +class Base85(Protocol): + """A Protocol class for the various base85 module implementations.""" + + def b85encode(self, text: bytes, pad: bool = False) -> bytes: + """encode text in base85 format""" + + def b85decode(self, text: bytes) -> bytes: + """decode base85-encoded text""" + + class BDiff(Protocol): """A Protocol class for the various bdiff module implementations.""" diff -r 936f85b243a8 -r fa7059f031a9 mercurial/util.py --- a/mercurial/util.py Fri Oct 04 23:09:56 2024 -0400 +++ b/mercurial/util.py Fri Oct 04 23:21:41 2024 -0400 @@ -70,6 +70,9 @@ typelib, urllibcompat, ) +from .interfaces import ( + modules as intmod, +) from .utils import ( compression, hashutil, @@ -87,7 +90,7 @@ ] -base85 = policy.importmod('base85') +base85: intmod.Base85 = policy.importmod('base85') osutil = policy.importmod('osutil') b85decode = base85.b85decode