Merge branch 'master' into python3
authorFredrik Tolf <fredrik@dolda2000.com>
Fri, 23 Dec 2011 00:53:15 +0000 (01:53 +0100)
committerFredrik Tolf <fredrik@dolda2000.com>
Fri, 23 Dec 2011 00:53:15 +0000 (01:53 +0100)
Conflicts:
pdm/cli.py
pdm/srv.py

1  2 
pdm/cli.py
pdm/srv.py

diff --cc 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:]
              self.buf += ret
  
      def select(self, proto):
 -        if "\n" in proto:
+         """Negotiate the given subprotocol with the server"""
 +        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):
          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):
 -        super(replclient, self).__init__(sk, "repl")
+         """Create a connected client as documented in the `client' class."""
 +        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):
 -        super(perfclient, self).__init__(sk, "perf")
+         """Create a connected client as documented in the `client' class."""
 +        super().__init__(sk, "perf")
          self.nextid = 0
          self.lock = threading.Lock()
          self.proxies = {}
diff --cc 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):
          cl.start()
  
  class unixlistener(listener):
 -    def __init__(self, name, mode = 0600, group = None):
+     """Unix socket listener"""
 -        super(unixlistener, self).__init__()
 +    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().__init__()
          self.name = name
          self.mode = mode
          self.group = group
                  os.unlink(self.name)
  
  class tcplistener(listener):
+     """TCP socket listener"""
      def __init__(self, port, bindaddr = "127.0.0.1"):
 -        super(tcplistener, self).__init__()
+         """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().__init__()
          self.port = port
          self.bindaddr = bindaddr