From: Fredrik Tolf Date: Fri, 23 Dec 2011 00:53:15 +0000 (+0100) Subject: Merge branch 'master' into python3 X-Git-Tag: 0.1~2 X-Git-Url: http://dolda2000.com/gitweb/?p=pdm.git;a=commitdiff_plain;h=144c745cd600fc7c050f5426fe438430885ef5b8 Merge branch 'master' into python3 Conflicts: pdm/cli.py pdm/srv.py --- 144c745cd600fc7c050f5426fe438430885ef5b8 diff --cc pdm/cli.py index 6af06f1,81246b7..9924d40 --- a/pdm/cli.py +++ b/pdm/cli.py @@@ -35,11 -36,30 +36,30 @@@ def resolve(spec) return rv class client(object): + """PDM client + + This class provides general facilities to speak to PDM servers, + and is mainly intended to be subclassed to provide for the + specific protocols, such as replclient and perfclient do. + + `client' instances can be passed as arguments to select.select(), + and can be used in `with' statements. + """ def __init__(self, sk, proto = None): + """Create a client object connected to the specified + server. `sk' can either be a socket object, which is used as + it is, or a string specification very similar to the + specification for pdm.srv.listen, so see its documentation for + details. The differences are only that this function does not + take arguments specific to socket creation, like the mode and + group arguments for Unix sockets. If `proto' is given, that + subprotocol will negotiated with the server (by calling the + select() method). + """ self.sk = resolve(sk) - self.buf = "" + self.buf = b"" line = self.readline() - if line != "+PDM1": + if line != b"+PDM1": raise protoerr("Illegal protocol signature") if proto is not None: self.select(proto) @@@ -51,8 -73,9 +73,9 @@@ return self.sk.fileno() def readline(self): + """Read a single NL-terminated line and return it.""" while True: - p = self.buf.find("\n") + p = self.buf.find(b"\n") if p >= 0: ret = self.buf[:p] self.buf = self.buf[p + 1:] @@@ -63,13 -86,12 +86,14 @@@ self.buf += ret def select(self, proto): + """Negotiate the given subprotocol with the server""" - if "\n" in proto: + if isinstance(proto, str): + proto = proto.encode("ascii") + if b"\n" in proto: raise Exception("Illegal protocol specified: %r" % proto) - self.sk.send(proto + "\n") + self.sk.send(proto + b"\n") rep = self.readline() - if len(rep) < 1 or rep[0] != "+": + if len(rep) < 1 or rep[0] != b"+"[0]: raise protoerr("Error reply when selecting protocol %s: %s" % (proto, rep[1:])) def __enter__(self): @@@ -80,10 -102,20 +104,20 @@@ return False class replclient(client): + """REPL protocol client + + Implements the client side of the REPL protocol; see pdm.srv.repl + for details on the protocol and its functionality. + """ def __init__(self, sk): + """Create a connected client as documented in the `client' class.""" - super(replclient, self).__init__(sk, "repl") + super().__init__(sk, "repl") def run(self, code): + """Run a single block of Python code on the server. Returns + the output of the command (as documented in pdm.srv.repl) as a + string. + """ while True: ncode = code.replace("\n\n", "\n") if ncode == code: break @@@ -166,8 -203,25 +205,25 @@@ class perfproxy(object) return False class perfclient(client): + """PERF protocol client + + Implements the client side of the PERF protocol; see pdm.srv.perf + for details on the protocol and its functionality. + + This client class implements functions for finding PERF objects on + the server, and returns, for each server-side object looked up, a + proxy object that mimics exactly the PERF interfaces that the + object implements. As the proxy objects reference live objects on + the server, they should be released when they are no longer used; + they implement a close() method for that purpose, and can also be + used in `with' statements. + + See pdm.srv.perf for details on the various PERF interfaces that + the proxy objects might implement. + """ def __init__(self, sk): + """Create a connected client as documented in the `client' class.""" - super(perfclient, self).__init__(sk, "perf") + super().__init__(sk, "perf") self.nextid = 0 self.lock = threading.Lock() self.proxies = {} diff --cc pdm/srv.py index e2aef4e,128c6d9..3ddc682 --- a/pdm/srv.py +++ b/pdm/srv.py @@@ -297,8 -405,15 +410,15 @@@ class client(threading.Thread) class listener(threading.Thread): + """PDM listener + + This subclass of a thread listens to PDM connections and handles + client connections properly. It is intended to be subclassed by + providers of specific domains, such as unixlistener and + tcplistener. + """ def __init__(self): - super(listener, self).__init__(name = "Management listener") + super().__init__(name = "Management listener") self.setDaemon(True) def listen(self, sk): @@@ -319,8 -440,15 +445,15 @@@ cl.start() class unixlistener(listener): + """Unix socket listener""" - def __init__(self, name, mode = 0600, group = None): + def __init__(self, name, mode = 0o600, group = None): + """Create a listener that will bind to the Unix socket named + by `name'. The socket will not actually be bound until the + listener is started. The socket will be chmodded to `mode', + and if `group' is given, the named group will be set as the + owner of the socket. + """ - super(unixlistener, self).__init__() + super().__init__() self.name = name self.mode = mode self.group = group @@@ -344,8 -472,13 +477,13 @@@ os.unlink(self.name) class tcplistener(listener): + """TCP socket listener""" def __init__(self, port, bindaddr = "127.0.0.1"): + """Create a listener that will bind to the given TCP port, and + the given local interface. The socket will not actually be + bound until the listener is started. + """ - super(tcplistener, self).__init__() + super().__init__() self.port = port self.bindaddr = bindaddr