view tests/test-wireproto.py @ 51833:6388fd855f66 stable

setup: handle removal of old MSVC compiler from setuptools 65.0 (issue6910) It was removed a few years ago[1]. When trying to reproduce locally using a clean py3.12 as called out in the bug report, `setuptools` wasn't installed at all, and needed a `pip install` to fix a `ModuleNotFoundError` when building locally. Maybe that needs to be in the requirements clause now. It looks like this "private" module was added in setuptools 48.0.[2] I can't find a changelog of what version was included in which version of python, and the changelog for pip has a huge gap between when it called out 67.6.1 in `pip` 23.1 (2023-04-15), and 41.4.0 in `pip` 19.3 (2019-10-14).[3] So, we'll just add to the existing code instead of replacing it, for safety. [1] https://github.com/pypa/setuptools/commit/cc017c77948737d131f683e0c25cd37bc639b8fc [2] https://github.com/pypa/setuptools/commit/d034a5ec7f707499139f90eb846b9e720923124c [3] https://pip.pypa.io/en/stable/news/
author Matt Harbison <mharbison@atto.com>
date Thu, 05 Sep 2024 15:37:14 -0400
parents 642e31cb55f0
children
line wrap: on
line source

import sys

from mercurial import (
    error,
    pycompat,
    ui as uimod,
    util,
    wireprototypes,
    wireprotov1peer,
    wireprotov1server,
)
from mercurial.utils import stringutil

stringio = util.stringio


class proto:
    def __init__(self, args):
        self.args = args
        self.name = 'dummyproto'

    def getargs(self, spec):
        args = self.args
        args.setdefault(b'*', {})
        names = spec.split()
        return [args[n] for n in names]

    def checkperm(self, perm):
        pass


wireprototypes.TRANSPORTS['dummyproto'] = {
    'transport': 'dummy',
    'version': 1,
}


class clientpeer(wireprotov1peer.wirepeer):
    def __init__(self, serverrepo, ui):
        self.serverrepo = serverrepo
        self.ui = ui

    def url(self):
        return b'test'

    def local(self):
        return None

    def peer(self):
        return self

    def canpush(self):
        return True

    def close(self):
        pass

    def capabilities(self):
        return [b'batch']

    def _call(self, cmd, **args):
        args = pycompat.byteskwargs(args)
        res = wireprotov1server.dispatch(self.serverrepo, proto(args), cmd)
        if isinstance(res, wireprototypes.bytesresponse):
            return res.data
        elif isinstance(res, bytes):
            return res
        else:
            raise error.Abort('dummy client does not support response type')

    def _callstream(self, cmd, **args):
        return stringio(self._call(cmd, **args))

    @wireprotov1peer.batchable
    def greet(self, name):
        return {b'name': mangle(name)}, unmangle


class serverrepo:
    def __init__(self, ui):
        self.ui = ui

    def greet(self, name):
        return b"Hello, " + name

    def filtered(self, name):
        return self


def mangle(s):
    return b''.join(pycompat.bytechr(ord(c) + 1) for c in pycompat.bytestr(s))


def unmangle(s):
    return b''.join(pycompat.bytechr(ord(c) - 1) for c in pycompat.bytestr(s))


def greet(repo, proto, name):
    return mangle(repo.greet(unmangle(name)))


wireprotov1server.commands[b'greet'] = (greet, b'name')

srv = serverrepo(uimod.ui())
clt = clientpeer(srv, uimod.ui())


def printb(data, end=b'\n'):
    out = getattr(sys.stdout, 'buffer', sys.stdout)
    out.write(data + end)
    out.flush()


printb(clt.greet(b"Foobar"))

with clt.commandexecutor() as e:
    fgreet1 = e.callcommand(b'greet', {b'name': b'Fo, =;:<o'})
    fgreet2 = e.callcommand(b'greet', {b'name': b'Bar'})

printb(
    stringutil.pprint([f.result() for f in (fgreet1, fgreet2)], bprefix=True)
)