From: Fredrik Tolf Date: Fri, 23 Dec 2011 06:14:45 +0000 (+0100) Subject: Merge branch 'master' into python3 X-Git-Url: http://www.dolda2000.com/gitweb/?a=commitdiff_plain;h=c58b1ad8cc6658ea46ed049f6909b4ce05906b57;hp=-c;p=pdm.git Merge branch 'master' into python3 --- c58b1ad8cc6658ea46ed049f6909b4ce05906b57 diff --combined pdm/cli.py index 32580bb,effe3c9..0b31682 --- a/pdm/cli.py +++ b/pdm/cli.py @@@ -51,17 -51,17 +51,17 @@@ class client(object) """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). + specification for L{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) @@@ -77,25 -77,23 +77,25 @@@ 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:] return ret ret = self.sk.recv(1024) - if ret == "": + if ret == b"": return None 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): @@@ -108,17 -106,17 +108,17 @@@ 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. + Implements the client side of the REPL protocol; see + L{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. + the output of the command (as documented in L{pdm.srv.repl}) + as a string. """ while True: ncode = code.replace("\n\n", "\n") @@@ -126,16 -124,16 +126,16 @@@ code = ncode while len(code) > 0 and code[-1] == "\n": code = code[:-1] - self.sk.send(code + "\n\n") - buf = "" + self.sk.send((code + "\n\n").encode("utf-8")) + buf = b"" while True: ln = self.readline() - if ln[0] == " ": - buf += ln[1:] + "\n" - elif ln[0] == "+": - return buf - elif ln[0] == "-": - raise protoerr("Error reply: %s" % ln[1:]) + if ln[0] == b" "[0]: + buf += ln[1:] + b"\n" + elif ln[0] == b"+"[0]: + return buf.decode("utf-8") + elif ln[0] == b"-"[0]: + raise protoerr("Error reply: %s" % ln[1:].decode("utf-8")) else: raise protoerr("Illegal reply: %s" % ln) @@@ -209,8 -207,8 +209,8 @@@ class perfproxy(object) 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. + Implements the client side of the PERF protocol; see + L{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 @@@ -220,12 -218,12 +220,12 @@@ 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. + See L{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 = {} @@@ -237,10 -235,10 +237,10 @@@ self.sk.send(buf) def recvb(self, num): - buf = "" + buf = b"" while len(buf) < num: data = self.sk.recv(num - len(buf)) - if data == "": + if data == b"": raise EOFError() buf += data return buf diff --combined pdm/perf.py index feb8b4a,f3a3e70..6a68676 --- a/pdm/perf.py +++ b/pdm/perf.py @@@ -5,35 -5,44 +5,44 @@@ for implementing PERF interfaces in com classes to implement some standard PERF objects that can be used by PERF clients connecting to any PERF server. - See the documentation for pdm.srv.perf for a description of the + See the documentation for L{pdm.srv.perf} for a description of the various PERF interfaces. It contains two named PERF objects: - * sysres -- A directory containing the following objects pertaining - to the resource usage of the server process: - * realtime -- An attribute returning the amount of real time - since the PDM module was imported (which likely - coincides with the amount of time the server process - has been running). - * cputime -- An attribute returning the amount of CPU time - consumed by the server process (in both user and - kernel mode). - * utime -- An attribute returning the amount of CPU time the - server process has spent in user mode. - * stime -- An attribute returning the amount of CPU time the - server process has spent in kernel mode. - * maxrss -- An attribute returning the largest resident set size - the server process has used during its lifetime. - * rusage -- An attribute returning the current rusage of the - server process. - * sysinfo -- A directory containing the following objects pertaining - to the environment of the server process: - * pid -- An attribute returning the PID of the server process. - * uname -- An attribute returning the uname information of the - system. - * hostname -- An attribute returning the hostname of the system. - * platform -- An attribute returning the Python build platform. + - sysres -- A directory containing the following objects pertaining + to the resource usage of the server process: + + - realtime -- An attribute returning the amount of real time since + the PDM module was imported (which likely coincides with the + amount of time the server process has been running). + + - cputime -- An attribute returning the amount of CPU time + consumed by the server process (in both user and kernel mode). + + - utime -- An attribute returning the amount of CPU time the + server process has spent in user mode. + + - stime -- An attribute returning the amount of CPU time the + server process has spent in kernel mode. + + - maxrss -- An attribute returning the largest resident set size + the server process has used during its lifetime. + + - rusage -- An attribute returning the current rusage of the + server process. + + - sysinfo -- A directory containing the following objects pertaining + to the environment of the server process: + + - pid -- An attribute returning the PID of the server process. + + - uname -- An attribute returning the uname information of the + system. + + - hostname -- An attribute returning the hostname of the system. + + - platform -- An attribute returning the Python build platform. """ import os, sys, resource, time, socket, threading @@@ -44,7 -53,7 +53,7 @@@ __all__ = ["attrinfo", "simpleattr", "v class attrinfo(object): """The return value of the `attrinfo' method on `attr' objects as - described in pdm.srv.perf. + described in L{pdm.srv.perf}. Currently contains a single data field, `desc', which should have a human-readable description of the purpose of the attribute. @@@ -54,7 -63,7 +63,7 @@@ class perfobj(object): def __init__(self, *args, **kwargs): - super(perfobj, self).__init__() + super().__init__() def pdm_protocols(self): return [] @@@ -65,7 -74,7 +74,7 @@@ class simpleattr(perfobj) read. """ def __init__(self, func, info = None, *args, **kwargs): - super(simpleattr, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.func = func if info is None: info = attrinfo() @@@ -78,7 -87,7 +87,7 @@@ return self.info def pdm_protocols(self): - return super(simpleattr, self).pdm_protocols() + ["attr"] + return super().pdm_protocols() + ["attr"] class valueattr(perfobj): """An implementation of the `attr' interface, which is initialized @@@ -86,7 -95,7 +95,7 @@@ updates to the value are reflected in subsequent reads. """ def __init__(self, init, info = None, *args, **kwargs): - super(valueattr, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.value = init if info is None: info = attrinfo() @@@ -99,7 -108,7 +108,7 @@@ return self.info def pdm_protocols(self): - return super(valueattr, self).pdm_protocols() + ["attr"] + return super().pdm_protocols() + ["attr"] class eventobj(perfobj): """An implementation of the `event' interface. It keeps track of @@@ -107,7 -116,7 +116,7 @@@ subscribers when submitted with the `notify' method. """ def __init__(self, *args, **kwargs): - super(eventobj, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.subscribers = set() def subscribe(self, cb): @@@ -126,7 -135,7 +135,7 @@@ except: pass def pdm_protocols(self): - return super(eventobj, self).pdm_protocols() + ["event"] + return super().pdm_protocols() + ["event"] class staticdir(perfobj): """An implementation of the `dir' interface. Put other PERF @@@ -134,7 -143,7 +143,7 @@@ return them to requesting clients. """ def __init__(self, *args, **kwargs): - super(staticdir, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.map = {} def __setitem__(self, name, ob): @@@ -150,13 -159,13 +159,13 @@@ return self.map.get(name, default) def listdir(self): - return self.map.keys() + return list(self.map.keys()) def lookup(self, name): return self.map[name] def pdm_protocols(self): - return super(staticdir, self).pdm_protocols() + ["dir"] + return super().pdm_protocols() + ["dir"] class event(object): """This class should be subclassed by all event objects sent via @@@ -200,7 -209,7 +209,7 @@@ class procevent(event) `finishevent' emitted when the connection is closed. """ def __init__(self, id): - super(procevent, self).__init__() + super().__init__() if isinstance(id, procevent): self.id = id.id else: @@@ -209,7 -218,7 +218,7 @@@ class startevent(procevent): """A subclass of `procevent'. See its documentation for details.""" def __init__(self): - super(startevent, self).__init__(getprocid()) + super().__init__(getprocid()) class finishevent(procevent): """A subclass of `procevent'. Intended to be emitted when a @@@ -218,7 -227,7 +227,7 @@@ distinction is meaningful. The `start' parameter should be the `startevent' instance used when the process was initiated.""" def __init__(self, start, aborted = False): - super(finishevent, self).__init__(start) + super().__init__(start) self.aborted = aborted sysres = staticdir() diff --combined pdm/srv.py index 3ddc682,8eb11f5..abf7d89 --- a/pdm/srv.py +++ b/pdm/srv.py @@@ -19,9 -19,9 +19,9 @@@ class repl(object) """REPL protocol handler Provides a read-eval-print loop. The primary client-side interface - is the pdm.cli.replclient class. Clients can send arbitrary code, - which is compiled and run on its own thread in the server process, - and output responses that are echoed back to the client. + is the L{pdm.cli.replclient} class. Clients can send arbitrary + code, which is compiled and run on its own thread in the server + process, and output responses that are echoed back to the client. Each client is provided with its own module, in which the code runs. The module is prepared with a function named `echo', which @@@ -40,34 -40,33 +40,34 @@@ self.mod = types.ModuleType("repl") self.mod.echo = self.echo self.printer = pprint.PrettyPrinter(indent = 4, depth = 6) - cl.send("+REPL\n") + cl.send(b"+REPL\n") def sendlines(self, text): for line in text.split("\n"): - self.cl.send(" " + line + "\n") + self.cl.send(b" " + line.encode("utf-8") + b"\n") def echo(self, ob): self.sendlines(self.printer.pformat(ob)) def command(self, cmd): + cmd = cmd.decode("utf-8") try: try: ccode = compile(cmd, "PDM Input", "eval") except SyntaxError: ccode = compile(cmd, "PDM Input", "exec") - exec ccode in self.mod.__dict__ - self.cl.send("+OK\n") + exec(ccode, self.mod.__dict__) + self.cl.send(b"+OK\n") else: self.echo(eval(ccode, self.mod.__dict__)) - self.cl.send("+OK\n") + self.cl.send(b"+OK\n") except: for line in traceback.format_exception(*sys.exc_info()): - self.cl.send(" " + line) - self.cl.send("+EXC\n") + self.cl.send(b" " + line.encode("utf-8")) + self.cl.send(b"+EXC\n") def handle(self, buf): - p = buf.find("\n\n") + p = buf.find(b"\n\n") if p < 0: return buf cmd = buf[:p + 1] @@@ -98,12 -97,12 +98,12 @@@ class perf(object) already be imported. PDM will not import new modules for clients; rather, the daemon process needs to import all modules that clients should be able to interact with. PDM itself always imports - the pdm.perf module, which contains a few basic PERF objects. See - its documentation for details. + the L{pdm.perf} module, which contains a few basic PERF + objects. See its documentation for details. The following interfaces are currently known to PERF. - * attr: + - attr: An object that implements the `attr' interface models an attribute that can be read by clients. The attribute can be anything, as long as its representation can be @@@ -117,9 -116,9 +117,9 @@@ description of the attribute. Both should be idempotent. `readattr' can return any pickleable object, and `attrinfo' should return either None to indicate that it has no - description, or an instance of the pdm.perf.attrinfo class. + description, or an instance of the L{pdm.perf.attrinfo} class. - * dir: + - dir: The `dir' interface models a directory of other PERF objects. An object implementing it must implement methods called `lookup' and `listdir'. `lookup' is called with a single @@@ -130,7 -129,7 +130,7 @@@ used as argument to `lookup', but the list is not required to be exhaustive and may also be empty. - * invoke: + - invoke: The `invoke' interface allows a more arbitrary form of method calls to objects implementing it. Such objects must implement a method called `invoke', which is called with one positional @@@ -141,7 -140,7 +141,7 @@@ the client. In case the method name is not recognized, `invoke' should raise an AttributeError. - * event: + - event: The `event' interface allows PERF objects to notify clients of events asynchronously. Objects implementing it must implement methods called `subscribe' and `unsubscribe'. `subscribe' will @@@ -151,7 -150,7 +151,7 @@@ `event' object should then call all such registered callables with a single argument describing the event. The argument could be any object that can be pickled, but should be an instance of - a subclass of the pdm.perf.event class. If `subscribe' is + a subclass of the L{pdm.perf.event} class. If `subscribe' is called with a callback object that it has already registered, it should raise a ValueError. `unsubscribe' is called with a single argument, which is a previously registered callback @@@ -160,23 -159,23 +160,23 @@@ object is not, in fact, registered, a ValueError should be raised. - The pdm.perf module contains a few convenience classes which + The L{pdm.perf} module contains a few convenience classes which implements the interfaces, but PERF objects are not required to be instances of them. Any object can implement a PERF interface, as long as it does so as described above. - The pdm.cli.perfclient class is the client-side implementation. + The L{pdm.cli.perfclient} class is the client-side implementation. """ def __init__(self, cl): self.cl = cl self.odtab = {} - cl.send("+PERF1\n") + cl.send(b"+PERF1\n") self.buf = "" self.lock = threading.Lock() self.subscribed = {} def closed(self): - for id, recv in self.subscribed.iteritems(): + for id, recv in self.subscribed.items(): ob = self.odtab[id] if ob is None: continue ob, protos = ob @@@ -198,7 -197,7 +198,7 @@@ raise ValueError("Object does not support PDM introspection") try: proto = ob.pdm_protocols() - except Exception, exc: + except Exception as exc: raise ValueError("PDM introspection failed", exc) self.odtab[id] = ob, proto return proto @@@ -215,7 -214,7 +215,7 @@@ return try: proto = self.bindob(id, ob) - except Exception, exc: + except Exception as exc: self.send("-", exc) return self.send("+", proto) @@@ -237,12 -236,12 +237,12 @@@ return try: ob = src.lookup(obnm) - except KeyError, exc: + except KeyError as exc: self.send("-", exc) return try: proto = self.bindob(tgtid, ob) - except Exception, exc: + except Exception as exc: self.send("-", exc) return self.send("+", proto) @@@ -272,7 -271,7 +272,7 @@@ return try: ret = ob.readattr() - except Exception, exc: + except Exception as exc: self.send("-", Exception("Could not read attribute")) return self.send("+", ret) @@@ -289,7 -288,7 +289,7 @@@ return try: self.send("+", ob.invoke(method, *args, **kwargs)) - except Exception, exc: + except Exception as exc: self.send("-", exc) def event(self, id, ob, ev): @@@ -355,7 -354,7 +355,7 @@@ protocols["perf"] = per class client(threading.Thread): def __init__(self, sk): - super(client, self).__init__(name = "Management client") + super().__init__(name = "Management client") self.setDaemon(True) self.sk = sk self.handler = self @@@ -364,10 -363,6 +364,10 @@@ return self.sk.send(data) def choose(self, proto): + try: + proto = proto.decode("ascii") + except UnicodeError: + proto = None if proto in protocols: self.handler = protocols[proto](self) else: @@@ -375,7 -370,7 +375,7 @@@ raise Exception() def handle(self, buf): - p = buf.find("\n") + p = buf.find(b"\n") if p >= 0: proto = buf[:p] buf = buf[p + 1:] @@@ -384,24 -379,24 +384,24 @@@ def run(self): try: - buf = "" - self.send("+PDM1\n") + buf = b"" + self.send(b"+PDM1\n") while True: ret = self.sk.recv(1024) - if ret == "": + if ret == b"": return buf += ret while True: try: nbuf = self.handler.handle(buf) except: + #for line in traceback.format_exception(*sys.exc_info()): + # print(line) return if nbuf == buf: break buf = nbuf finally: - #for line in traceback.format_exception(*sys.exc_info()): - # print line try: self.sk.close() finally: @@@ -418,7 -413,7 +418,7 @@@ class listener(threading.Thread) tcplistener. """ def __init__(self): - super(listener, self).__init__(name = "Management listener") + super().__init__(name = "Management listener") self.setDaemon(True) def listen(self, sk): @@@ -446,14 -441,14 +446,14 @@@ 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 @@@ -483,7 -478,7 +483,7 @@@ class tcplistener(listener) 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 @@@ -521,7 -516,7 +521,7 @@@ def listen(spec) last = spec if "/" in first: parts = spec.split(":") - mode = 0600 + mode = 0o600 group = None if len(parts) > 1: mode = int(parts[1], 8)