[tor-commits] [chutney/master] Add initial support for Python 3 alongside 2

nickm at torproject.org nickm at torproject.org
Tue Dec 23 19:52:38 UTC 2014


commit 07f0979a4e4d807deced3f69226cb978e0e7e03b
Author: Daniel Martí <mvdan at mvdan.cc>
Date:   Thu Sep 11 21:21:36 2014 +0200

    Add initial support for Python 3 alongside 2
---
 lib/chutney/Templating.py |    5 +--
 lib/chutney/TorNet.py     |   80 +++++++++++++++++++++++++--------------------
 lib/chutney/Traffic.py    |    6 ++--
 3 files changed, 51 insertions(+), 40 deletions(-)

diff --git a/lib/chutney/Templating.py b/lib/chutney/Templating.py
index 301b049..a8f638f 100644
--- a/lib/chutney/Templating.py
+++ b/lib/chutney/Templating.py
@@ -76,6 +76,7 @@
 
 """
 
+from __future__ import print_function
 from __future__ import with_statement
 
 import string
@@ -369,9 +370,9 @@ if __name__ == '__main__':
     if len(sys.argv) == 1:
         import doctest
         doctest.testmod()
-        print "done"
+        print("done")
     else:
         for fn in sys.argv[1:]:
             with open(fn, 'r') as f:
                 t = Template(f.read())
-                print fn, t.freevars()
+                print(fn, t.freevars())
diff --git a/lib/chutney/TorNet.py b/lib/chutney/TorNet.py
index 1d9326d..ecd181c 100644
--- a/lib/chutney/TorNet.py
+++ b/lib/chutney/TorNet.py
@@ -7,6 +7,7 @@
 #  restrict, so long as you retain the above notice(s) and this license
 #  in all redistributed copies and derived works.  There is no warranty.
 
+from __future__ import print_function
 from __future__ import with_statement
 
 # Get verbose tracebacks, so we can diagnose better.
@@ -29,13 +30,17 @@ _TORRC_OPTIONS = None
 _THE_NETWORK = None
 
 
-def mkdir_p(d, mode=0777):
+def mkdir_p(d, mode=511):
     """Create directory 'd' and all of its parents as needed.  Unlike
        os.makedirs, does not give an error if d already exists.
+
+       511 is the decimal representation of the octal number 0777. Since
+       python2 only supports 0777 and python3 only supports 0o777, we can use
+       neither.
     """
     try:
         os.makedirs(d, mode=mode)
-    except OSError, e:
+    except OSError as e:
         if e.errno == errno.EEXIST:
             return
         raise
@@ -66,7 +71,7 @@ class Node(object):
         self._controller = None
 
     def getN(self, N):
-        return [Node(self) for _ in xrange(N)]
+        return [Node(self) for _ in range(N)]
 
     def specialize(self, **kwargs):
         return Node(parent=self, **kwargs)
@@ -352,14 +357,14 @@ class LocalNodeBuilder(NodeBuilder):
             '-c', certfile,
             '-m', str(lifetime),
             '-a', addr]
-        print "Creating identity key %s for %s with %s" % (
-            idfile, self._env['nick'], " ".join(cmdline))
+        print("Creating identity key %s for %s with %s" % (
+            idfile, self._env['nick'], " ".join(cmdline)))
         try:
             p = subprocess.Popen(cmdline, stdin=subprocess.PIPE)
         except OSError as e:
             # only catch file not found error
             if e.errno == errno.ENOENT:
-                print ("Cannot find tor-gencert binary %r. Use "
+                print("Cannot find tor-gencert binary %r. Use "
                        "CHUTNEY_TOR_GENCERT environment variable to set the "
                        "path, or put the binary into $PATH.") % tor_gencert
                 sys.exit(0)
@@ -387,7 +392,7 @@ class LocalNodeBuilder(NodeBuilder):
         except OSError as e:
             # only catch file not found error
             if e.errno == errno.ENOENT:
-                print ("Cannot find tor binary %r. Use "
+                print("Cannot find tor binary %r. Use "
                        "CHUTNEY_TOR environment variable to set the "
                        "path, or put the binary into $PATH.") % tor
                 sys.exit(0)
@@ -488,7 +493,7 @@ class LocalNodeController(NodeController):
 
         try:
             os.kill(pid, 0)  # "kill 0" == "are you there?"
-        except OSError, e:
+        except OSError as e:
             if e.errno == errno.ESRCH:
                 return False
             raise
@@ -510,16 +515,16 @@ class LocalNodeController(NodeController):
         datadir = self._env['dir']
         if self.isRunning(pid):
             if listRunning:
-                print "%s is running with PID %s" % (nick, pid)
+                print("%s is running with PID %s" % (nick, pid))
             return True
         elif os.path.exists(os.path.join(datadir, "core.%s" % pid)):
             if listNonRunning:
-                print "%s seems to have crashed, and left core file core.%s" % (
-                    nick, pid)
+                print("%s seems to have crashed, and left core file core.%s" % (
+                    nick, pid))
             return False
         else:
             if listNonRunning:
-                print "%s is stopped" % nick
+                print("%s is stopped" % nick)
             return False
 
     def hup(self):
@@ -527,11 +532,11 @@ class LocalNodeController(NodeController):
         pid = self.getPid()
         nick = self._env['nick']
         if self.isRunning(pid):
-            print "Sending sighup to %s" % nick
+            print("Sending sighup to %s" % nick)
             os.kill(pid, signal.SIGHUP)
             return True
         else:
-            print "%s is not running" % nick
+            print("%s is not running" % nick)
             return False
 
     def start(self):
@@ -539,7 +544,7 @@ class LocalNodeController(NodeController):
            already running, False if we failed."""
 
         if self.isRunning():
-            print "%s is already running" % self._env['nick']
+            print("%s is already running" % self._env['nick'])
             return True
         tor_path = self._env['tor']
         torrc = self._getTorrcFname()
@@ -553,7 +558,7 @@ class LocalNodeController(NodeController):
         except OSError as e:
             # only catch file not found error
             if e.errno == errno.ENOENT:
-                print ("Cannot find tor binary %r. Use CHUTNEY_TOR "
+                print("Cannot find tor binary %r. Use CHUTNEY_TOR "
                        "environment variable to set the path, or put the binary "
                        "into $PATH.") % tor_path
                 sys.exit(0)
@@ -578,16 +583,16 @@ class LocalNodeController(NodeController):
             p.poll()
         if p.returncode != None and p.returncode != 0:
             if self._env['poll_launch_time'] is None:
-                print "Couldn't launch %s (%s): %s" % (self._env['nick'],
+                print("Couldn't launch %s (%s): %s" % (self._env['nick'],
                                                        " ".join(cmdline),
-                                                       p.returncode)
+                                                       p.returncode))
             else:
-                print ("Couldn't poll %s (%s) "
+                print("Couldn't poll %s (%s) "
                        "after waiting %s seconds for launch"
-                       ": %s") % (self._env['nick'],
+                       ": %s" % (self._env['nick'],
                                   " ".join(cmdline),
                                   self._env['poll_launch_time'],
-                                  p.returncode)
+                                  p.returncode))
             return False
         return True
 
@@ -595,15 +600,15 @@ class LocalNodeController(NodeController):
         """Try to stop this node by sending it the signal 'sig'."""
         pid = self.getPid()
         if not self.isRunning(pid):
-            print "%s is not running" % self._env['nick']
+            print("%s is not running" % self._env['nick'])
             return
         os.kill(pid, sig)
 
     def cleanup_lockfile(self):
         lf = self._env['lockfile']
         if not self.isRunning() and os.path.exists(lf):
-            print 'Removing stale lock file for {0} ...'.format(
-                self._env['nick'])
+            print('Removing stale lock file for {0} ...'.format(
+                self._env['nick']))
             os.remove(lf)
 
     def waitOnLaunch(self):
@@ -774,7 +779,7 @@ class Network(object):
     def status(self):
         statuses = [n.getController().check() for n in self._nodes]
         n_ok = len([x for x in statuses if x])
-        print "%d/%d nodes are running" % (n_ok, len(self._nodes))
+        print("%d/%d nodes are running" % (n_ok, len(self._nodes)))
         return n_ok == len(self._nodes)
 
     def restart(self):
@@ -787,17 +792,17 @@ class Network(object):
             sys.stdout.write("Starting nodes")
             sys.stdout.flush()
         else:
-            print "Starting nodes"
+            print("Starting nodes")
         rv = all([n.getController().start() for n in self._nodes])
         # now print a newline unconditionally - this stops poll()ing
         # output from being squashed together, at the cost of a blank
         # line in wait()ing output
-        print ""
+        print("")
         return rv
     
 
     def hup(self):
-        print "Sending SIGHUP to nodes"
+        print("Sending SIGHUP to nodes")
         return all([n.getController().hup() for n in self._nodes])
 
     def stop(self):
@@ -805,12 +810,12 @@ class Network(object):
         for sig, desc in [(signal.SIGINT, "SIGINT"),
                           (signal.SIGINT, "another SIGINT"),
                           (signal.SIGKILL, "SIGKILL")]:
-            print "Sending %s to nodes" % desc
+            print("Sending %s to nodes" % desc)
             for c in controllers:
                 if c.isRunning():
                     c.stop(sig=sig)
-            print "Waiting for nodes to finish."
-            for n in xrange(15):
+            print("Waiting for nodes to finish.")
+            for n in range(15):
                 time.sleep(1)
                 if all(not c.isRunning() for c in controllers):
                     # check for stale lock file when Tor crashes
@@ -826,7 +831,7 @@ class Network(object):
         sys.stdout.write("Verifying data transmission: ")
         sys.stdout.flush()
         status = self._verify_traffic()
-        print "Success" if status else "Failure"
+        print("Success" if status else "Failure")
         return status
 
     def _verify_traffic(self):
@@ -865,18 +870,21 @@ def exit_on_error(err_msg):
     print usage(_THE_NETWORK)
     sys.exit(1)
 
-def runConfigFile(verb, f):
+def runConfigFile(verb, path):
     _GLOBALS = dict(_BASE_ENVIRON=_BASE_ENVIRON,
                     Node=Node,
                     ConfigureNodes=ConfigureNodes,
                     _THE_NETWORK=_THE_NETWORK)
 
-    exec f in _GLOBALS
+    with open(path) as f:
+        data = f.read()
+
+    exec(data, _GLOBALS)
     network = _GLOBALS['_THE_NETWORK']
 
     if not hasattr(network, verb):
-        print usage(network)
-        print "Error: I don't know how to %s." % verb
+        print(usage(network))
+        print("Error: I don't know how to %s." % verb)
         return
 
     return getattr(network, verb)()
diff --git a/lib/chutney/Traffic.py b/lib/chutney/Traffic.py
index 56a0006..d98a670 100644
--- a/lib/chutney/Traffic.py
+++ b/lib/chutney/Traffic.py
@@ -20,6 +20,8 @@
 #
 # For example code, see main() below.
 
+from __future__ import print_function
+
 import sys
 import socket
 import select
@@ -181,7 +183,7 @@ class Source(Peer):
         dest = self.proxy or self.dest
         try:
             self.s.connect(dest)
-        except socket.error, e:
+        except socket.error as e:
             if e[0] != errno.EINPROGRESS:
                 raise
 
@@ -228,7 +230,7 @@ class Source(Peer):
                 self.outbuf = socks_cmd(self.dest)
         try:
             n = self.s.send(self.outbuf)
-        except socket.error, e:
+        except socket.error as e:
             if e[0] == errno.ECONNREFUSED:
                 debug("connection refused (fd=%d)" % self.fd())
                 return -1





More information about the tor-commits mailing list