[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [stem/master] Standardizing single vs double quotes



commit 3650c6089186fd941bd2e71613f5c37022313c0e
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date:   Sat May 10 12:53:31 2014 -0700

    Standardizing single vs double quotes
    
    PEP8 doesn't have any advice on when to opt for one quote type or the other, so
    I'm settling on the following:
    
      Single quotes unless it's either block quotes (""") or has single quotes in
      the content ("he said 'hello'").
---
 stem/__init__.py                                   |  404 +++++++-------
 stem/connection.py                                 |  164 +++---
 stem/control.py                                    |  421 +++++++-------
 stem/descriptor/__init__.py                        |   92 ++--
 stem/descriptor/export.py                          |    6 +-
 stem/descriptor/extrainfo_descriptor.py            |  300 +++++-----
 stem/descriptor/microdescriptor.py                 |   58 +-
 stem/descriptor/networkstatus.py                   |  284 +++++-----
 stem/descriptor/reader.py                          |   36 +-
 stem/descriptor/remote.py                          |   32 +-
 stem/descriptor/router_status_entry.py             |   68 +--
 stem/descriptor/server_descriptor.py               |  252 ++++-----
 stem/descriptor/tordnsel.py                        |   32 +-
 stem/exit_policy.py                                |  112 ++--
 stem/interpretor/__init__.py                       |    2 +-
 stem/interpretor/commands.py                       |    2 +-
 stem/interpretor/help.py                           |    4 +-
 stem/prereq.py                                     |    4 +-
 stem/process.py                                    |   42 +-
 stem/response/__init__.py                          |   79 +--
 stem/response/authchallenge.py                     |   18 +-
 stem/response/events.py                            |  286 +++++-----
 stem/response/getconf.py                           |   12 +-
 stem/response/getinfo.py                           |   18 +-
 stem/response/mapaddress.py                        |   10 +-
 stem/response/protocolinfo.py                      |   34 +-
 stem/socket.py                                     |  104 ++--
 stem/util/__init__.py                              |   22 +-
 stem/util/conf.py                                  |   98 ++--
 stem/util/connection.py                            |   84 +--
 stem/util/enum.py                                  |   14 +-
 stem/util/log.py                                   |   10 +-
 stem/util/proc.py                                  |   98 ++--
 stem/util/str_tools.py                             |   72 +--
 stem/util/system.py                                |  158 +++---
 stem/util/term.py                                  |   20 +-
 stem/util/test_tools.py                            |   34 +-
 stem/util/tor_tools.py                             |   12 +-
 test/__init__.py                                   |   12 +-
 test/integ/__init__.py                             |   16 +-
 test/integ/connection/__init__.py                  |    2 +-
 test/integ/connection/authentication.py            |   30 +-
 test/integ/control/__init__.py                     |    2 +-
 test/integ/control/base_controller.py              |   30 +-
 test/integ/control/controller.py                   |  262 ++++-----
 test/integ/descriptor/__init__.py                  |   14 +-
 test/integ/descriptor/extrainfo_descriptor.py      |   40 +-
 test/integ/descriptor/microdescriptor.py           |   36 +-
 test/integ/descriptor/networkstatus.py             |  230 ++++----
 test/integ/descriptor/reader.py                    |  101 ++--
 test/integ/descriptor/remote.py                    |   16 +-
 test/integ/descriptor/server_descriptor.py         |  174 +++---
 test/integ/process.py                              |   16 +-
 test/integ/response/__init__.py                    |    2 +-
 test/integ/response/protocolinfo.py                |   20 +-
 test/integ/socket/__init__.py                      |    2 +-
 test/integ/socket/control_message.py               |   66 +--
 test/integ/socket/control_socket.py                |   22 +-
 test/integ/util/__init__.py                        |    2 +-
 test/integ/util/conf.py                            |   56 +-
 test/integ/util/connection.py                      |    6 +-
 test/integ/util/proc.py                            |   18 +-
 test/integ/util/system.py                          |  194 +++----
 test/integ/version.py                              |    8 +-
 test/mocking.py                                    |  204 +++----
 test/network.py                                    |   58 +-
 test/output.py                                     |   42 +-
 test/runner.py                                     |  143 ++---
 test/unit/__init__.py                              |   14 +-
 test/unit/connection/__init__.py                   |    2 +-
 test/unit/connection/authentication.py             |    6 +-
 test/unit/connection/connect.py                    |    2 +-
 test/unit/control/__init__.py                      |    2 +-
 test/unit/control/controller.py                    |   78 +--
 test/unit/descriptor/__init__.py                   |   14 +-
 test/unit/descriptor/export.py                     |   14 +-
 test/unit/descriptor/extrainfo_descriptor.py       |  274 ++++-----
 test/unit/descriptor/microdescriptor.py            |   32 +-
 test/unit/descriptor/networkstatus/__init__.py     |    2 +-
 .../descriptor/networkstatus/bridge_document.py    |    4 +-
 .../networkstatus/directory_authority.py           |  114 ++--
 test/unit/descriptor/networkstatus/document_v2.py  |   10 +-
 test/unit/descriptor/networkstatus/document_v3.py  |  328 +++++------
 .../descriptor/networkstatus/key_certificate.py    |   72 +--
 test/unit/descriptor/reader.py                     |   48 +-
 test/unit/descriptor/router_status_entry.py        |  246 ++++-----
 test/unit/descriptor/server_descriptor.py          |  186 +++----
 test/unit/descriptor/tordnsel.py                   |   10 +-
 test/unit/doctest.py                               |    2 +-
 test/unit/exit_policy/__init__.py                  |    2 +-
 test/unit/exit_policy/policy.py                    |   56 +-
 test/unit/exit_policy/rule.py                      |  308 +++++------
 test/unit/interpretor/__init__.py                  |    8 +-
 test/unit/response/__init__.py                     |   16 +-
 test/unit/response/authchallenge.py                |   14 +-
 test/unit/response/control_line.py                 |   20 +-
 test/unit/response/control_message.py              |   52 +-
 test/unit/response/events.py                       |  580 ++++++++++----------
 test/unit/response/getconf.py                      |   32 +-
 test/unit/response/getinfo.py                      |   32 +-
 test/unit/response/mapaddress.py                   |   30 +-
 test/unit/response/protocolinfo.py                 |   48 +-
 test/unit/response/singleline.py                   |   18 +-
 test/unit/tutorial.py                              |   36 +-
 test/unit/util/__init__.py                         |   14 +-
 test/unit/util/conf.py                             |  162 +++---
 test/unit/util/connection.py                       |  102 ++--
 test/unit/util/enum.py                             |   20 +-
 test/unit/util/proc.py                             |    4 +-
 test/unit/util/str_tools.py                        |   14 +-
 test/unit/util/system.py                           |  220 ++++----
 test/unit/util/tor_tools.py                        |   38 +-
 test/unit/version.py                               |  154 +++---
 test/util.py                                       |  104 ++--
 114 files changed, 4449 insertions(+), 4417 deletions(-)

diff --git a/stem/__init__.py b/stem/__init__.py
index 8a607a6..f32a3bd 100644
--- a/stem/__init__.py
+++ b/stem/__init__.py
@@ -428,48 +428,48 @@ __url__ = 'https://stem.torproject.org/'
 __license__ = 'LGPLv3'
 
 __all__ = [
-  "descriptor",
-  "response",
-  "util",
-  "connection",
-  "control",
-  "exit_policy",
-  "prereq",
-  "process",
-  "socket",
-  "version",
-  "ControllerError",
-  "ProtocolError",
-  "OperationFailed",
-  "UnsatisfiableRequest",
-  "CircuitExtensionFailed",
-  "InvalidRequest",
-  "InvalidArguments",
-  "SocketError",
-  "SocketClosed",
-  "Runlevel",
-  "Signal",
-  "Flag",
-  "CircStatus",
-  "CircBuildFlag",
-  "CircPurpose",
-  "CircClosureReason",
-  "CircEvent",
-  "HiddenServiceState",
-  "HSAuth",
-  "HSDescAction",
-  "RelayEndReason",
-  "StreamStatus",
-  "StreamClosureReason",
-  "StreamSource",
-  "StreamPurpose",
-  "ORStatus",
-  "ORClosureReason",
-  "AuthDescriptorAction",
-  "StatusType",
-  "GuardType",
-  "GuardStatus",
-  "TimeoutSetType",
+  'descriptor',
+  'response',
+  'util',
+  'connection',
+  'control',
+  'exit_policy',
+  'prereq',
+  'process',
+  'socket',
+  'version',
+  'ControllerError',
+  'ProtocolError',
+  'OperationFailed',
+  'UnsatisfiableRequest',
+  'CircuitExtensionFailed',
+  'InvalidRequest',
+  'InvalidArguments',
+  'SocketError',
+  'SocketClosed',
+  'Runlevel',
+  'Signal',
+  'Flag',
+  'CircStatus',
+  'CircBuildFlag',
+  'CircPurpose',
+  'CircClosureReason',
+  'CircEvent',
+  'HiddenServiceState',
+  'HSAuth',
+  'HSDescAction',
+  'RelayEndReason',
+  'StreamStatus',
+  'StreamClosureReason',
+  'StreamSource',
+  'StreamPurpose',
+  'ORStatus',
+  'ORClosureReason',
+  'AuthDescriptorAction',
+  'StatusType',
+  'GuardType',
+  'GuardStatus',
+  'TimeoutSetType',
 ]
 
 import stem.util.enum
@@ -478,15 +478,15 @@ import stem.util.enum
 # this, but users will commonly provide None as the argument so need something
 # else fairly unique...
 
-UNDEFINED = "<Undefined_ >"
+UNDEFINED = '<Undefined_ >'
 
 
 class ControllerError(Exception):
-  "Base error for controller communication issues."
+  'Base error for controller communication issues.'
 
 
 class ProtocolError(ControllerError):
-  "Malformed content from the control socket."
+  'Malformed content from the control socket.'
 
 
 class OperationFailed(ControllerError):
@@ -544,239 +544,239 @@ class InvalidArguments(InvalidRequest):
 
 
 class SocketError(ControllerError):
-  "Error arose while communicating with the control socket."
+  'Error arose while communicating with the control socket.'
 
 
 class SocketClosed(SocketError):
-  "Control socket was closed before completing the message."
+  'Control socket was closed before completing the message.'
 
 Runlevel = stem.util.enum.UppercaseEnum(
-  "DEBUG",
-  "INFO",
-  "NOTICE",
-  "WARN",
-  "ERR",
+  'DEBUG',
+  'INFO',
+  'NOTICE',
+  'WARN',
+  'ERR',
 )
 
 Flag = stem.util.enum.Enum(
-  ("AUTHORITY", "Authority"),
-  ("BADEXIT", "BadExit"),
-  ("BADDIRECTORY", "BadDirectory"),
-  ("EXIT", "Exit"),
-  ("FAST", "Fast"),
-  ("GUARD", "Guard"),
-  ("HSDIR", "HSDir"),
-  ("NAMED", "Named"),
-  ("RUNNING", "Running"),
-  ("STABLE", "Stable"),
-  ("UNNAMED", "Unnamed"),
-  ("V2DIR", "V2Dir"),
-  ("V3DIR", "V3Dir"),
-  ("VALID", "Valid"),
+  ('AUTHORITY', 'Authority'),
+  ('BADEXIT', 'BadExit'),
+  ('BADDIRECTORY', 'BadDirectory'),
+  ('EXIT', 'Exit'),
+  ('FAST', 'Fast'),
+  ('GUARD', 'Guard'),
+  ('HSDIR', 'HSDir'),
+  ('NAMED', 'Named'),
+  ('RUNNING', 'Running'),
+  ('STABLE', 'Stable'),
+  ('UNNAMED', 'Unnamed'),
+  ('V2DIR', 'V2Dir'),
+  ('V3DIR', 'V3Dir'),
+  ('VALID', 'Valid'),
 )
 
 Signal = stem.util.enum.UppercaseEnum(
-  "RELOAD",
-  "HUP",
-  "SHUTDOWN",
-  "INT",
-  "DUMP",
-  "USR1",
-  "DEBUG",
-  "USR2",
-  "HALT",
-  "TERM",
-  "NEWNYM",
-  "CLEARDNSCACHE",
+  'RELOAD',
+  'HUP',
+  'SHUTDOWN',
+  'INT',
+  'DUMP',
+  'USR1',
+  'DEBUG',
+  'USR2',
+  'HALT',
+  'TERM',
+  'NEWNYM',
+  'CLEARDNSCACHE',
 )
 
 CircStatus = stem.util.enum.UppercaseEnum(
-  "LAUNCHED",
-  "BUILT",
-  "EXTENDED",
-  "FAILED",
-  "CLOSED",
+  'LAUNCHED',
+  'BUILT',
+  'EXTENDED',
+  'FAILED',
+  'CLOSED',
 )
 
 CircBuildFlag = stem.util.enum.UppercaseEnum(
-  "ONEHOP_TUNNEL",
-  "IS_INTERNAL",
-  "NEED_CAPACITY",
-  "NEED_UPTIME",
+  'ONEHOP_TUNNEL',
+  'IS_INTERNAL',
+  'NEED_CAPACITY',
+  'NEED_UPTIME',
 )
 
 CircPurpose = stem.util.enum.UppercaseEnum(
-  "GENERAL",
-  "HS_CLIENT_INTRO",
-  "HS_CLIENT_REND",
-  "HS_SERVICE_INTRO",
-  "HS_SERVICE_REND",
-  "TESTING",
-  "CONTROLLER",
-  "MEASURE_TIMEOUT",
+  'GENERAL',
+  'HS_CLIENT_INTRO',
+  'HS_CLIENT_REND',
+  'HS_SERVICE_INTRO',
+  'HS_SERVICE_REND',
+  'TESTING',
+  'CONTROLLER',
+  'MEASURE_TIMEOUT',
 )
 
 CircClosureReason = stem.util.enum.UppercaseEnum(
-  "NONE",
-  "TORPROTOCOL",
-  "INTERNAL",
-  "REQUESTED",
-  "HIBERNATING",
-  "RESOURCELIMIT",
-  "CONNECTFAILED",
-  "OR_IDENTITY",
-  "OR_CONN_CLOSED",
-  "FINISHED",
-  "TIMEOUT",
-  "DESTROYED",
-  "NOPATH",
-  "NOSUCHSERVICE",
-  "MEASUREMENT_EXPIRED",
+  'NONE',
+  'TORPROTOCOL',
+  'INTERNAL',
+  'REQUESTED',
+  'HIBERNATING',
+  'RESOURCELIMIT',
+  'CONNECTFAILED',
+  'OR_IDENTITY',
+  'OR_CONN_CLOSED',
+  'FINISHED',
+  'TIMEOUT',
+  'DESTROYED',
+  'NOPATH',
+  'NOSUCHSERVICE',
+  'MEASUREMENT_EXPIRED',
 )
 
 CircEvent = stem.util.enum.UppercaseEnum(
-  "PURPOSE_CHANGED",
-  "CANNIBALIZED",
+  'PURPOSE_CHANGED',
+  'CANNIBALIZED',
 )
 
 HiddenServiceState = stem.util.enum.UppercaseEnum(
-  "HSCI_CONNECTING",
-  "HSCI_INTRO_SENT",
-  "HSCI_DONE",
-  "HSCR_CONNECTING",
-  "HSCR_ESTABLISHED_IDLE",
-  "HSCR_ESTABLISHED_WAITING",
-  "HSCR_JOINED",
-  "HSSI_CONNECTING",
-  "HSSI_ESTABLISHED",
-  "HSSR_CONNECTING",
-  "HSSR_JOINED",
+  'HSCI_CONNECTING',
+  'HSCI_INTRO_SENT',
+  'HSCI_DONE',
+  'HSCR_CONNECTING',
+  'HSCR_ESTABLISHED_IDLE',
+  'HSCR_ESTABLISHED_WAITING',
+  'HSCR_JOINED',
+  'HSSI_CONNECTING',
+  'HSSI_ESTABLISHED',
+  'HSSR_CONNECTING',
+  'HSSR_JOINED',
 )
 
 RelayEndReason = stem.util.enum.UppercaseEnum(
-  "MISC",
-  "RESOLVEFAILED",
-  "CONNECTREFUSED",
-  "EXITPOLICY",
-  "DESTROY",
-  "DONE",
-  "TIMEOUT",
-  "NOROUTE",
-  "HIBERNATING",
-  "INTERNAL",
-  "RESOURCELIMIT",
-  "CONNRESET",
-  "TORPROTOCOL",
-  "NOTDIRECTORY",
+  'MISC',
+  'RESOLVEFAILED',
+  'CONNECTREFUSED',
+  'EXITPOLICY',
+  'DESTROY',
+  'DONE',
+  'TIMEOUT',
+  'NOROUTE',
+  'HIBERNATING',
+  'INTERNAL',
+  'RESOURCELIMIT',
+  'CONNRESET',
+  'TORPROTOCOL',
+  'NOTDIRECTORY',
 )
 
 StreamStatus = stem.util.enum.UppercaseEnum(
-  "NEW",
-  "NEWRESOLVE",
-  "REMAP",
-  "SENTCONNECT",
-  "SENTRESOLVE",
-  "SUCCEEDED",
-  "FAILED",
-  "DETACHED",
-  "CLOSED",
+  'NEW',
+  'NEWRESOLVE',
+  'REMAP',
+  'SENTCONNECT',
+  'SENTRESOLVE',
+  'SUCCEEDED',
+  'FAILED',
+  'DETACHED',
+  'CLOSED',
 )
 
 # StreamClosureReason is a superset of RelayEndReason
 StreamClosureReason = stem.util.enum.UppercaseEnum(*(RelayEndReason.keys() + [
-  "END",
-  "PRIVATE_ADDR",
+  'END',
+  'PRIVATE_ADDR',
 ]))
 
 StreamSource = stem.util.enum.UppercaseEnum(
-  "CACHE",
-  "EXIT",
+  'CACHE',
+  'EXIT',
 )
 
 StreamPurpose = stem.util.enum.UppercaseEnum(
-  "DIR_FETCH",
-  "DIR_UPLOAD",
-  "DNS_REQUEST",
-  "DIRPORT_TEST",
-  "USER",
+  'DIR_FETCH',
+  'DIR_UPLOAD',
+  'DNS_REQUEST',
+  'DIRPORT_TEST',
+  'USER',
 )
 
 ORStatus = stem.util.enum.UppercaseEnum(
-  "NEW",
-  "LAUNCHED",
-  "CONNECTED",
-  "FAILED",
-  "CLOSED",
+  'NEW',
+  'LAUNCHED',
+  'CONNECTED',
+  'FAILED',
+  'CLOSED',
 )
 
 ORClosureReason = stem.util.enum.UppercaseEnum(
-  "DONE",
-  "CONNECTREFUSED",
-  "IDENTITY",
-  "CONNECTRESET",
-  "TIMEOUT",
-  "NOROUTE",
-  "IOERROR",
-  "RESOURCELIMIT",
-  "MISC",
-  "PT_MISSING",
+  'DONE',
+  'CONNECTREFUSED',
+  'IDENTITY',
+  'CONNECTRESET',
+  'TIMEOUT',
+  'NOROUTE',
+  'IOERROR',
+  'RESOURCELIMIT',
+  'MISC',
+  'PT_MISSING',
 )
 
 AuthDescriptorAction = stem.util.enum.UppercaseEnum(
-  "ACCEPTED",
-  "DROPPED",
-  "REJECTED",
+  'ACCEPTED',
+  'DROPPED',
+  'REJECTED',
 )
 
 StatusType = stem.util.enum.UppercaseEnum(
-  "GENERAL",
-  "CLIENT",
-  "SERVER",
+  'GENERAL',
+  'CLIENT',
+  'SERVER',
 )
 
 GuardType = stem.util.enum.UppercaseEnum(
-  "ENTRY",
+  'ENTRY',
 )
 
 GuardStatus = stem.util.enum.UppercaseEnum(
-  "NEW",
-  "UP",
-  "DOWN",
-  "BAD",
-  "GOOD",
-  "DROPPED",
+  'NEW',
+  'UP',
+  'DOWN',
+  'BAD',
+  'GOOD',
+  'DROPPED',
 )
 
 TimeoutSetType = stem.util.enum.UppercaseEnum(
-  "COMPUTED",
-  "RESET",
-  "SUSPENDED",
-  "DISCARD",
-  "RESUME",
+  'COMPUTED',
+  'RESET',
+  'SUSPENDED',
+  'DISCARD',
+  'RESUME',
 )
 
 ConnectionType = stem.util.enum.UppercaseEnum(
-  "OR",
-  "DIR",
-  "EXIT",
+  'OR',
+  'DIR',
+  'EXIT',
 )
 
 TokenBucket = stem.util.enum.UppercaseEnum(
-  "GLOBAL",
-  "RELAY",
-  "ORCONN",
+  'GLOBAL',
+  'RELAY',
+  'ORCONN',
 )
 
 HSDescAction = stem.util.enum.UppercaseEnum(
-  "REQUESTED",
-  "RECEIVED",
-  "IGNORE",
-  "FAILED",
+  'REQUESTED',
+  'RECEIVED',
+  'IGNORE',
+  'FAILED',
 )
 
 HSAuth = stem.util.enum.UppercaseEnum(
-  "NO_AUTH",
-  "BASIC_AUTH",
-  "STEALTH_AUTH",
-  "UNKNOWN",
+  'NO_AUTH',
+  'BASIC_AUTH',
+  'STEALTH_AUTH',
+  'UNKNOWN',
 )
diff --git a/stem/connection.py b/stem/connection.py
index ad04aa7..d807bcf 100644
--- a/stem/connection.py
+++ b/stem/connection.py
@@ -22,7 +22,7 @@ exceptions, etc).
     if not controller:
       sys.exit(1)  # unable to get a connection
 
-    print "Tor is running version %s" % controller.get_version()
+    print 'Tor is running version %s' % controller.get_version()
     controller.close()
 
 ::
@@ -50,25 +50,25 @@ fine-grained control over the authentication process. For instance...
   try:
     control_socket = stem.socket.ControlPort(port = 9051)
   except stem.SocketError as exc:
-    print "Unable to connect to port 9051 (%s)" % exc
+    print 'Unable to connect to port 9051 (%s)' % exc
     sys.exit(1)
 
   try:
     stem.connection.authenticate(control_socket)
   except stem.connection.IncorrectSocketType:
-    print "Please check in your torrc that 9051 is the ControlPort."
-    print "Maybe you configured it to be the ORPort or SocksPort instead?"
+    print 'Please check in your torrc that 9051 is the ControlPort.'
+    print 'Maybe you configured it to be the ORPort or SocksPort instead?'
     sys.exit(1)
   except stem.connection.MissingPassword:
-    controller_password = getpass.getpass("Controller password: ")
+    controller_password = getpass.getpass('Controller password: ')
 
     try:
       stem.connection.authenticate_password(control_socket, controller_password)
     except stem.connection.PasswordAuthFailed:
-      print "Unable to authenticate, password is incorrect"
+      print 'Unable to authenticate, password is incorrect'
       sys.exit(1)
   except stem.connection.AuthenticationFailure as exc:
-    print "Unable to authenticate: %s" % exc
+    print 'Unable to authenticate: %s' % exc
     sys.exit(1)
 
 **Module Overview:**
@@ -142,10 +142,10 @@ import stem.version
 
 from stem.util import log
 
-AuthMethod = stem.util.enum.Enum("NONE", "PASSWORD", "COOKIE", "SAFECOOKIE", "UNKNOWN")
+AuthMethod = stem.util.enum.Enum('NONE', 'PASSWORD', 'COOKIE', 'SAFECOOKIE', 'UNKNOWN')
 
-CLIENT_HASH_CONSTANT = b"Tor safe cookie authentication controller-to-server hash"
-SERVER_HASH_CONSTANT = b"Tor safe cookie authentication server-to-controller hash"
+CLIENT_HASH_CONSTANT = b'Tor safe cookie authentication controller-to-server hash'
+SERVER_HASH_CONSTANT = b'Tor safe cookie authentication server-to-controller hash'
 
 MISSING_PASSWORD_BUG_MSG = """
 BUG: You provided a password but despite this stem reported that it was
@@ -182,14 +182,14 @@ tor?
 """
 
 CONNECT_MESSAGES = {
-  'general_auth_failure': "Unable to authenticate: {error}",
-  'incorrect_password': "Incorrect password",
+  'general_auth_failure': 'Unable to authenticate: {error}',
+  'incorrect_password': 'Incorrect password',
   'no_control_port': "Unable to connect to tor. Maybe it's running without a ControlPort?",
-  'password_prompt': "Tor controller password:",
-  'needs_password': "Tor requires a password to authenticate",
+  'password_prompt': 'Tor controller password:',
+  'needs_password': 'Tor requires a password to authenticate',
   'socket_doesnt_exist': "The socket file you specified ({path}) doesn't exist",
   'tor_isnt_running': "Unable to connect to tor. Are you sure it's running?",
-  'unable_to_use_port': "Unable to connect to {address}:{port}: {error}",
+  'unable_to_use_port': 'Unable to connect to {address}:{port}: {error}',
   'unable_to_use_socket': "Unable to connect to '{path}': {error}",
   'missing_password_bug': MISSING_PASSWORD_BUG_MSG.strip(),
   'uncrcognized_auth_type': UNRECOGNIZED_AUTH_TYPE_MSG.strip(),
@@ -230,10 +230,10 @@ def connect(control_port = ('127.0.0.1', 9051), control_socket = '/var/run/tor/c
   """
 
   if control_port is None and control_socket is None:
-    raise ValueError("Neither a control port nor control socket were provided. Nothing to connect to.")
+    raise ValueError('Neither a control port nor control socket were provided. Nothing to connect to.')
   elif control_port:
     if len(control_port) != 2:
-      raise ValueError("The control_port argument for connect() should be an (address, port) tuple.")
+      raise ValueError('The control_port argument for connect() should be an (address, port) tuple.')
     elif not stem.util.connection.is_valid_ipv4_address(control_port[0]):
       raise ValueError("'%s' isn't a vaid IPv4 address" % control_port[0])
     elif not stem.util.connection.is_valid_port(control_port[1]):
@@ -275,7 +275,7 @@ def connect(control_port = ('127.0.0.1', 9051), control_socket = '/var/run/tor/c
   return _connect_auth(control_connection, password, password_prompt, chroot_path, controller)
 
 
-def connect_port(address = "127.0.0.1", port = 9051, password = None, chroot_path = None, controller = stem.control.Controller):
+def connect_port(address = '127.0.0.1', port = 9051, password = None, chroot_path = None, controller = stem.control.Controller):
   """
   Convenience function for quickly getting a control connection. This is very
   handy for debugging or CLI setup, handling setup and prompting for a password
@@ -304,7 +304,7 @@ def connect_port(address = "127.0.0.1", port = 9051, password = None, chroot_pat
   return _connect_auth(control_port, password, True, chroot_path, controller)
 
 
-def connect_socket_file(path = "/var/run/tor/control", password = None, chroot_path = None, controller = stem.control.Controller):
+def connect_socket_file(path = '/var/run/tor/control', password = None, chroot_path = None, controller = stem.control.Controller):
   """
   Convenience function for quickly getting a control connection. For more
   information see the :func:`~stem.connection.connect_port` function.
@@ -513,15 +513,15 @@ def authenticate(controller, password = None, chroot_path = None, protocolinfo_r
     try:
       protocolinfo_response = get_protocolinfo(controller)
     except stem.ProtocolError:
-      raise IncorrectSocketType("unable to use the control socket")
+      raise IncorrectSocketType('unable to use the control socket')
     except stem.SocketError as exc:
-      raise AuthenticationFailure("socket connection failed (%s)" % exc)
+      raise AuthenticationFailure('socket connection failed (%s)' % exc)
 
   auth_methods = list(protocolinfo_response.auth_methods)
   auth_exceptions = []
 
   if len(auth_methods) == 0:
-    raise NoAuthMethods("our PROTOCOLINFO response did not have any methods for authenticating")
+    raise NoAuthMethods('our PROTOCOLINFO response did not have any methods for authenticating')
 
   # remove authentication methods that are either unknown or for which we don't
   # have an input
@@ -529,27 +529,27 @@ def authenticate(controller, password = None, chroot_path = None, protocolinfo_r
     auth_methods.remove(AuthMethod.UNKNOWN)
 
     unknown_methods = protocolinfo_response.unknown_auth_methods
-    plural_label = "s" if len(unknown_methods) > 1 else ""
-    methods_label = ", ".join(unknown_methods)
+    plural_label = 's' if len(unknown_methods) > 1 else ''
+    methods_label = ', '.join(unknown_methods)
 
     # we... er, can't do anything with only unrecognized auth types
     if not auth_methods:
-      exc_msg = "unrecognized authentication method%s (%s)" % (plural_label, methods_label)
+      exc_msg = 'unrecognized authentication method%s (%s)' % (plural_label, methods_label)
       auth_exceptions.append(UnrecognizedAuthMethods(exc_msg, unknown_methods))
     else:
-      log.debug("Authenticating to a socket with unrecognized auth method%s, ignoring them: %s" % (plural_label, methods_label))
+      log.debug('Authenticating to a socket with unrecognized auth method%s, ignoring them: %s' % (plural_label, methods_label))
 
   if protocolinfo_response.cookie_path is None:
     for cookie_auth_method in (AuthMethod.COOKIE, AuthMethod.SAFECOOKIE):
       if cookie_auth_method in auth_methods:
         auth_methods.remove(cookie_auth_method)
 
-        exc_msg = "our PROTOCOLINFO response did not have the location of our authentication cookie"
+        exc_msg = 'our PROTOCOLINFO response did not have the location of our authentication cookie'
         auth_exceptions.append(NoAuthCookie(exc_msg, cookie_auth_method == AuthMethod.SAFECOOKIE))
 
   if AuthMethod.PASSWORD in auth_methods and password is None:
     auth_methods.remove(AuthMethod.PASSWORD)
-    auth_exceptions.append(MissingPassword("no passphrase provided"))
+    auth_exceptions.append(MissingPassword('no passphrase provided'))
 
   # iterating over AuthMethods so we can try them in this order
   for auth_type in (AuthMethod.NONE, AuthMethod.PASSWORD, AuthMethod.SAFECOOKIE, AuthMethod.COOKIE):
@@ -580,19 +580,19 @@ def authenticate(controller, password = None, chroot_path = None, protocolinfo_r
     except PasswordAuthRejected as exc:
       # Since the PROTOCOLINFO says password auth is available we can assume
       # that if PasswordAuthRejected is raised it's being raised in error.
-      log.debug("The authenticate_password method raised a PasswordAuthRejected when password auth should be available. Stem may need to be corrected to recognize this response: %s" % exc)
+      log.debug('The authenticate_password method raised a PasswordAuthRejected when password auth should be available. Stem may need to be corrected to recognize this response: %s' % exc)
       auth_exceptions.append(IncorrectPassword(str(exc)))
     except AuthSecurityFailure as exc:
-      log.info("Tor failed to provide the nonce expected for safecookie authentication. (%s)" % exc)
+      log.info('Tor failed to provide the nonce expected for safecookie authentication. (%s)' % exc)
       auth_exceptions.append(exc)
     except (InvalidClientNonce, UnrecognizedAuthChallengeMethod, AuthChallengeFailed) as exc:
       auth_exceptions.append(exc)
     except (IncorrectCookieSize, UnreadableCookieFile, IncorrectCookieValue) as exc:
       auth_exceptions.append(exc)
     except CookieAuthRejected as exc:
-      auth_func = "authenticate_safecookie" if exc.is_safecookie else "authenticate_cookie"
+      auth_func = 'authenticate_safecookie' if exc.is_safecookie else 'authenticate_cookie'
 
-      log.debug("The %s method raised a CookieAuthRejected when cookie auth should be available. Stem may need to be corrected to recognize this response: %s" % (auth_func, exc))
+      log.debug('The %s method raised a CookieAuthRejected when cookie auth should be available. Stem may need to be corrected to recognize this response: %s' % (auth_func, exc))
       auth_exceptions.append(IncorrectCookieValue(str(exc), exc.cookie_path, exc.is_safecookie))
     except stem.ControllerError as exc:
       auth_exceptions.append(AuthenticationFailure(str(exc)))
@@ -608,7 +608,7 @@ def authenticate(controller, password = None, chroot_path = None, protocolinfo_r
   # We really, really shouldn't get here. It means that auth_exceptions is
   # either empty or contains something that isn't an AuthenticationFailure.
 
-  raise AssertionError("BUG: Authentication failed without providing a recognized exception: %s" % str(auth_exceptions))
+  raise AssertionError('BUG: Authentication failed without providing a recognized exception: %s' % str(auth_exceptions))
 
 
 def authenticate_none(controller, suppress_ctl_errors = True):
@@ -636,10 +636,10 @@ def authenticate_none(controller, suppress_ctl_errors = True):
   """
 
   try:
-    auth_response = _msg(controller, "AUTHENTICATE")
+    auth_response = _msg(controller, 'AUTHENTICATE')
 
     # if we got anything but an OK response then error
-    if str(auth_response) != "OK":
+    if str(auth_response) != 'OK':
       try:
         controller.connect()
       except:
@@ -655,7 +655,7 @@ def authenticate_none(controller, suppress_ctl_errors = True):
     if not suppress_ctl_errors:
       raise exc
     else:
-      raise OpenAuthRejected("Socket failed (%s)" % exc)
+      raise OpenAuthRejected('Socket failed (%s)' % exc)
 
 
 def authenticate_password(controller, password, suppress_ctl_errors = True):
@@ -699,10 +699,10 @@ def authenticate_password(controller, password, suppress_ctl_errors = True):
   password = password.replace('"', '\\"')
 
   try:
-    auth_response = _msg(controller, "AUTHENTICATE \"%s\"" % password)
+    auth_response = _msg(controller, 'AUTHENTICATE "%s"' % password)
 
     # if we got anything but an OK response then error
-    if str(auth_response) != "OK":
+    if str(auth_response) != 'OK':
       try:
         controller.connect()
       except:
@@ -712,7 +712,7 @@ def authenticate_password(controller, password, suppress_ctl_errors = True):
       # Password did not match HashedControlPassword value value from configuration...
       # Password did not match HashedControlPassword *or*...
 
-      if "Password did not match HashedControlPassword" in str(auth_response):
+      if 'Password did not match HashedControlPassword' in str(auth_response):
         raise IncorrectPassword(str(auth_response), auth_response)
       else:
         raise PasswordAuthRejected(str(auth_response), auth_response)
@@ -725,7 +725,7 @@ def authenticate_password(controller, password, suppress_ctl_errors = True):
     if not suppress_ctl_errors:
       raise exc
     else:
-      raise PasswordAuthRejected("Socket failed (%s)" % exc)
+      raise PasswordAuthRejected('Socket failed (%s)' % exc)
 
 
 def authenticate_cookie(controller, cookie_path, suppress_ctl_errors = True):
@@ -787,11 +787,11 @@ def authenticate_cookie(controller, cookie_path, suppress_ctl_errors = True):
     # misbehave.
 
     auth_token_hex = binascii.b2a_hex(stem.util.str_tools._to_bytes(cookie_data))
-    msg = "AUTHENTICATE %s" % stem.util.str_tools._to_unicode(auth_token_hex)
+    msg = 'AUTHENTICATE %s' % stem.util.str_tools._to_unicode(auth_token_hex)
     auth_response = _msg(controller, msg)
 
     # if we got anything but an OK response then error
-    if str(auth_response) != "OK":
+    if str(auth_response) != 'OK':
       try:
         controller.connect()
       except:
@@ -801,8 +801,8 @@ def authenticate_cookie(controller, cookie_path, suppress_ctl_errors = True):
       # ... Authentication cookie did not match expected value.
       # ... *or* authentication cookie.
 
-      if "*or* authentication cookie." in str(auth_response) or \
-         "Authentication cookie did not match expected value." in str(auth_response):
+      if '*or* authentication cookie.' in str(auth_response) or \
+         'Authentication cookie did not match expected value.' in str(auth_response):
         raise IncorrectCookieValue(str(auth_response), cookie_path, False, auth_response)
       else:
         raise CookieAuthRejected(str(auth_response), cookie_path, False, auth_response)
@@ -815,7 +815,7 @@ def authenticate_cookie(controller, cookie_path, suppress_ctl_errors = True):
     if not suppress_ctl_errors:
       raise exc
     else:
-      raise CookieAuthRejected("Socket failed (%s)" % exc, cookie_path, False)
+      raise CookieAuthRejected('Socket failed (%s)' % exc, cookie_path, False)
 
 
 def authenticate_safecookie(controller, cookie_path, suppress_ctl_errors = True):
@@ -883,7 +883,7 @@ def authenticate_safecookie(controller, cookie_path, suppress_ctl_errors = True)
 
   try:
     client_nonce_hex = stem.util.str_tools._to_unicode(binascii.b2a_hex(client_nonce))
-    authchallenge_response = _msg(controller, "AUTHCHALLENGE SAFECOOKIE %s" % client_nonce_hex)
+    authchallenge_response = _msg(controller, 'AUTHCHALLENGE SAFECOOKIE %s' % client_nonce_hex)
 
     if not authchallenge_response.is_ok():
       try:
@@ -893,11 +893,11 @@ def authenticate_safecookie(controller, cookie_path, suppress_ctl_errors = True)
 
       authchallenge_response_str = str(authchallenge_response)
 
-      if "Authentication required." in authchallenge_response_str:
+      if 'Authentication required.' in authchallenge_response_str:
         raise AuthChallengeUnsupported("SAFECOOKIE authentication isn't supported", cookie_path)
-      elif "AUTHCHALLENGE only supports" in authchallenge_response_str:
+      elif 'AUTHCHALLENGE only supports' in authchallenge_response_str:
         raise UnrecognizedAuthChallengeMethod(authchallenge_response_str, cookie_path)
-      elif "Invalid base16 client nonce" in authchallenge_response_str:
+      elif 'Invalid base16 client nonce' in authchallenge_response_str:
         raise InvalidClientNonce(authchallenge_response_str, cookie_path)
       elif "Cookie authentication is disabled" in authchallenge_response_str:
         raise CookieAuthRejected(authchallenge_response_str, cookie_path, True)
@@ -912,29 +912,29 @@ def authenticate_safecookie(controller, cookie_path, suppress_ctl_errors = True)
     if not suppress_ctl_errors:
       raise exc
     else:
-      raise AuthChallengeFailed("Socket failed (%s)" % exc, cookie_path, True)
+      raise AuthChallengeFailed('Socket failed (%s)' % exc, cookie_path, True)
 
   try:
-    stem.response.convert("AUTHCHALLENGE", authchallenge_response)
+    stem.response.convert('AUTHCHALLENGE', authchallenge_response)
   except stem.ProtocolError as exc:
     if not suppress_ctl_errors:
       raise exc
     else:
-      raise AuthChallengeFailed("Unable to parse AUTHCHALLENGE response: %s" % exc, cookie_path)
+      raise AuthChallengeFailed('Unable to parse AUTHCHALLENGE response: %s' % exc, cookie_path)
 
   expected_server_hash = stem.util.connection._hmac_sha256(
     SERVER_HASH_CONSTANT,
     cookie_data + client_nonce + authchallenge_response.server_nonce)
 
   if not stem.util.connection._cryptovariables_equal(authchallenge_response.server_hash, expected_server_hash):
-    raise AuthSecurityFailure("Tor provided the wrong server nonce", cookie_path)
+    raise AuthSecurityFailure('Tor provided the wrong server nonce', cookie_path)
 
   try:
     client_hash = stem.util.connection._hmac_sha256(
       CLIENT_HASH_CONSTANT,
       cookie_data + client_nonce + authchallenge_response.server_nonce)
 
-    auth_response = _msg(controller, "AUTHENTICATE %s" % stem.util.str_tools._to_unicode(binascii.b2a_hex(client_hash)))
+    auth_response = _msg(controller, 'AUTHENTICATE %s' % stem.util.str_tools._to_unicode(binascii.b2a_hex(client_hash)))
   except stem.ControllerError as exc:
     try:
       controller.connect()
@@ -944,7 +944,7 @@ def authenticate_safecookie(controller, cookie_path, suppress_ctl_errors = True)
     if not suppress_ctl_errors:
       raise exc
     else:
-      raise CookieAuthRejected("Socket failed (%s)" % exc, cookie_path, True, auth_response)
+      raise CookieAuthRejected('Socket failed (%s)' % exc, cookie_path, True, auth_response)
 
   # if we got anything but an OK response then err
   if not auth_response.is_ok():
@@ -957,8 +957,8 @@ def authenticate_safecookie(controller, cookie_path, suppress_ctl_errors = True)
     # ... Safe cookie response did not match expected value
     # ... *or* authentication cookie.
 
-    if "*or* authentication cookie." in str(auth_response) or \
-       "Safe cookie response did not match expected value" in str(auth_response):
+    if '*or* authentication cookie.' in str(auth_response) or \
+       'Safe cookie response did not match expected value' in str(auth_response):
       raise IncorrectCookieValue(str(auth_response), cookie_path, True, auth_response)
     else:
       raise CookieAuthRejected(str(auth_response), cookie_path, True, auth_response)
@@ -990,27 +990,27 @@ def get_protocolinfo(controller):
   """
 
   try:
-    protocolinfo_response = _msg(controller, "PROTOCOLINFO 1")
+    protocolinfo_response = _msg(controller, 'PROTOCOLINFO 1')
   except:
     protocolinfo_response = None
 
   # Tor hangs up on sockets after receiving a PROTOCOLINFO query if it isn't
   # next followed by authentication. Transparently reconnect if that happens.
 
-  if not protocolinfo_response or str(protocolinfo_response) == "Authentication required.":
+  if not protocolinfo_response or str(protocolinfo_response) == 'Authentication required.':
     controller.connect()
 
     try:
-      protocolinfo_response = _msg(controller, "PROTOCOLINFO 1")
+      protocolinfo_response = _msg(controller, 'PROTOCOLINFO 1')
     except stem.SocketClosed as exc:
       raise stem.SocketError(exc)
 
-  stem.response.convert("PROTOCOLINFO", protocolinfo_response)
+  stem.response.convert('PROTOCOLINFO', protocolinfo_response)
 
   # attempt to expand relative cookie paths
 
   if protocolinfo_response.cookie_path:
-    _expand_cookie_path(protocolinfo_response, stem.util.system.get_pid_by_name, "tor")
+    _expand_cookie_path(protocolinfo_response, stem.util.system.get_pid_by_name, 'tor')
 
   # attempt to expand relative cookie paths via the control port or socket file
 
@@ -1020,7 +1020,7 @@ def get_protocolinfo(controller):
     control_socket = controller.get_socket()
 
   if isinstance(control_socket, stem.socket.ControlPort):
-    if control_socket.get_address() == "127.0.0.1":
+    if control_socket.get_address() == '127.0.0.1':
       pid_method = stem.util.system.get_pid_by_port
       _expand_cookie_path(protocolinfo_response, pid_method, control_socket.get_port())
   elif isinstance(control_socket, stem.socket.ControlSocketFile):
@@ -1098,23 +1098,23 @@ def _expand_cookie_path(protocolinfo_response, pid_resolver, pid_resolution_arg)
       tor_pid = pid_resolver(pid_resolution_arg)
 
       if not tor_pid:
-        raise IOError("pid lookup failed")
+        raise IOError('pid lookup failed')
 
       tor_cwd = stem.util.system.get_cwd(tor_pid)
 
       if not tor_cwd:
-        raise IOError("cwd lookup failed")
+        raise IOError('cwd lookup failed')
 
       cookie_path = stem.util.system.expand_path(cookie_path, tor_cwd)
     except IOError as exc:
       resolver_labels = {
-        stem.util.system.get_pid_by_name: " by name",
-        stem.util.system.get_pid_by_port: " by port",
-        stem.util.system.get_pid_by_open_file: " by socket file",
+        stem.util.system.get_pid_by_name: ' by name',
+        stem.util.system.get_pid_by_port: ' by port',
+        stem.util.system.get_pid_by_open_file: ' by socket file',
       }
 
-      pid_resolver_label = resolver_labels.get(pid_resolver, "")
-      log.debug("unable to expand relative tor cookie path%s: %s" % (pid_resolver_label, exc))
+      pid_resolver_label = resolver_labels.get(pid_resolver, '')
+      log.debug('unable to expand relative tor cookie path%s: %s' % (pid_resolver_label, exc))
 
   protocolinfo_response.cookie_path = cookie_path
 
@@ -1145,27 +1145,27 @@ class UnrecognizedAuthMethods(AuthenticationFailure):
 
 
 class IncorrectSocketType(AuthenticationFailure):
-  "Socket does not speak the control protocol."
+  'Socket does not speak the control protocol.'
 
 
 class OpenAuthFailed(AuthenticationFailure):
-  "Failure to authenticate to an open socket."
+  'Failure to authenticate to an open socket.'
 
 
 class OpenAuthRejected(OpenAuthFailed):
-  "Attempt to connect to an open control socket was rejected."
+  'Attempt to connect to an open control socket was rejected.'
 
 
 class PasswordAuthFailed(AuthenticationFailure):
-  "Failure to authenticate with a password."
+  'Failure to authenticate with a password.'
 
 
 class PasswordAuthRejected(PasswordAuthFailed):
-  "Socket does not support password authentication."
+  'Socket does not support password authentication.'
 
 
 class IncorrectPassword(PasswordAuthFailed):
-  "Authentication password incorrect."
+  'Authentication password incorrect.'
 
 
 class MissingPassword(PasswordAuthFailed):
@@ -1190,19 +1190,19 @@ class CookieAuthFailed(AuthenticationFailure):
 
 
 class CookieAuthRejected(CookieAuthFailed):
-  "Socket does not support password authentication."
+  'Socket does not support password authentication.'
 
 
 class IncorrectCookieValue(CookieAuthFailed):
-  "Authentication cookie value was rejected."
+  'Authentication cookie value was rejected.'
 
 
 class IncorrectCookieSize(CookieAuthFailed):
-  "Aborted because the cookie file is the wrong size."
+  'Aborted because the cookie file is the wrong size.'
 
 
 class UnreadableCookieFile(CookieAuthFailed):
-  "Error arose in reading the authentication cookie."
+  'Error arose in reading the authentication cookie.'
 
 
 class AuthChallengeFailed(CookieAuthFailed):
@@ -1233,11 +1233,11 @@ class UnrecognizedAuthChallengeMethod(AuthChallengeFailed):
 
 
 class AuthSecurityFailure(AuthChallengeFailed):
-  "AUTHCHALLENGE response is invalid."
+  'AUTHCHALLENGE response is invalid.'
 
 
 class InvalidClientNonce(AuthChallengeFailed):
-  "AUTHCHALLENGE request contains an invalid client nonce."
+  'AUTHCHALLENGE request contains an invalid client nonce.'
 
 
 class MissingAuthInfo(AuthenticationFailure):
diff --git a/stem/control.py b/stem/control.py
index 3064e81..02c9fa5 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -236,56 +236,56 @@ from stem.util import log
 
 # state changes a control socket can have
 
-State = stem.util.enum.Enum("INIT", "RESET", "CLOSED")
+State = stem.util.enum.Enum('INIT', 'RESET', 'CLOSED')
 
 EventType = stem.util.enum.UppercaseEnum(
-  "ADDRMAP",
-  "AUTHDIR_NEWDESCS",
-  "BUILDTIMEOUT_SET",
-  "BW",
-  "CIRC",
-  "CIRC_MINOR",
-  "CONF_CHANGED",
-  "CLIENTS_SEEN",
-  "DEBUG",
-  "DESCCHANGED",
-  "ERR",
-  "GUARD",
-  "HS_DESC",
-  "INFO",
-  "NEWCONSENSUS",
-  "NEWDESC",
-  "NOTICE",
-  "NS",
-  "ORCONN",
-  "SIGNAL",
-  "STATUS_CLIENT",
-  "STATUS_GENERAL",
-  "STATUS_SERVER",
-  "STREAM",
-  "STREAM_BW",
-  "WARN",
+  'ADDRMAP',
+  'AUTHDIR_NEWDESCS',
+  'BUILDTIMEOUT_SET',
+  'BW',
+  'CIRC',
+  'CIRC_MINOR',
+  'CONF_CHANGED',
+  'CLIENTS_SEEN',
+  'DEBUG',
+  'DESCCHANGED',
+  'ERR',
+  'GUARD',
+  'HS_DESC',
+  'INFO',
+  'NEWCONSENSUS',
+  'NEWDESC',
+  'NOTICE',
+  'NS',
+  'ORCONN',
+  'SIGNAL',
+  'STATUS_CLIENT',
+  'STATUS_GENERAL',
+  'STATUS_SERVER',
+  'STREAM',
+  'STREAM_BW',
+  'WARN',
 )
 
 Listener = stem.util.enum.UppercaseEnum(
-  "OR",
-  "DIR",
-  "SOCKS",
-  "TRANS",
-  "NATD",
-  "DNS",
-  "CONTROL",
+  'OR',
+  'DIR',
+  'SOCKS',
+  'TRANS',
+  'NATD',
+  'DNS',
+  'CONTROL',
 )
 
 # Configuration options that are fetched by a special key. The keys are
 # lowercase to make case insensitive lookups easier.
 
 MAPPED_CONFIG_KEYS = {
-  "hiddenservicedir": "HiddenServiceOptions",
-  "hiddenserviceport": "HiddenServiceOptions",
-  "hiddenserviceversion": "HiddenServiceOptions",
-  "hiddenserviceauthorizeclient": "HiddenServiceOptions",
-  "hiddenserviceoptions": "HiddenServiceOptions"
+  'hiddenservicedir': 'HiddenServiceOptions',
+  'hiddenserviceport': 'HiddenServiceOptions',
+  'hiddenserviceversion': 'HiddenServiceOptions',
+  'hiddenserviceauthorizeclient': 'HiddenServiceOptions',
+  'hiddenserviceoptions': 'HiddenServiceOptions',
 }
 
 # unchangeable GETINFO parameters
@@ -429,11 +429,11 @@ class BaseController(object):
           if isinstance(response, stem.SocketClosed):
             pass  # this is fine
           elif isinstance(response, stem.ProtocolError):
-            log.info("Tor provided a malformed message (%s)" % response)
+            log.info('Tor provided a malformed message (%s)' % response)
           elif isinstance(response, stem.ControllerError):
-            log.info("Socket experienced a problem (%s)" % response)
+            log.info('Socket experienced a problem (%s)' % response)
           elif isinstance(response, stem.response.ControlMessage):
-            log.info("Failed to deliver a response: %s" % response)
+            log.info('Failed to deliver a response: %s' % response)
         except Queue.Empty:
           # the empty() method is documented to not be fully reliable so this
           # isn't entirely surprising
@@ -454,7 +454,7 @@ class BaseController(object):
           # this is the most reliable method I can think of for taking actions
           # immediately after successfully authenticating to a connection.
 
-          if message.upper().startswith("AUTHENTICATE"):
+          if message.upper().startswith('AUTHENTICATE'):
             self._post_authentication()
 
           return response
@@ -657,7 +657,7 @@ class BaseController(object):
 
         for listener, spawn in self._status_listeners:
           if spawn:
-            name = "%s notification" % state
+            name = '%s notification' % state
             args = (self, state, change_timestamp)
 
             notice_thread = threading.Thread(target = listener, args = args, name = name)
@@ -677,12 +677,12 @@ class BaseController(object):
 
     with self._socket._get_send_lock():
       if not self._reader_thread or not self._reader_thread.is_alive():
-        self._reader_thread = threading.Thread(target = self._reader_loop, name = "Tor Listener")
+        self._reader_thread = threading.Thread(target = self._reader_loop, name = 'Tor Listener')
         self._reader_thread.setDaemon(True)
         self._reader_thread.start()
 
       if not self._event_thread or not self._event_thread.is_alive():
-        self._event_thread = threading.Thread(target = self._event_loop, name = "Event Notifier")
+        self._event_thread = threading.Thread(target = self._event_loop, name = 'Event Notifier')
         self._event_thread.setDaemon(True)
         self._event_thread.start()
 
@@ -700,7 +700,7 @@ class BaseController(object):
         control_message = self._socket.recv()
         self._last_heartbeat = time.time()
 
-        if control_message.content()[-1][0] == "650":
+        if control_message.content()[-1][0] == '650':
           # asynchronous message, adds to the event queue and wakes up its handler
           self._event_queue.put(control_message)
           self._event_notice.set()
@@ -742,7 +742,7 @@ class Controller(BaseController):
   """
 
   @staticmethod
-  def from_port(address = "127.0.0.1", port = 9051):
+  def from_port(address = '127.0.0.1', port = 9051):
     """
     Constructs a :class:`~stem.socket.ControlPort` based Controller.
 
@@ -755,15 +755,15 @@ class Controller(BaseController):
     """
 
     if not stem.util.connection.is_valid_ipv4_address(address):
-      raise ValueError("Invalid IP address: %s" % address)
+      raise ValueError('Invalid IP address: %s' % address)
     elif not stem.util.connection.is_valid_port(port):
-      raise ValueError("Invalid port: %s" % port)
+      raise ValueError('Invalid port: %s' % port)
 
     control_port = stem.socket.ControlPort(address, port)
     return Controller(control_port)
 
   @staticmethod
-  def from_socket_file(path = "/var/run/tor/control"):
+  def from_socket_file(path = '/var/run/tor/control'):
     """
     Constructs a :class:`~stem.socket.ControlSocketFile` based Controller.
 
@@ -805,10 +805,10 @@ class Controller(BaseController):
 
     def _confchanged_listener(event):
       if self.is_caching_enabled():
-        self._set_cache(dict((k, None) for k in event.config), "getconf")
+        self._set_cache(dict((k, None) for k in event.config), 'getconf')
 
-        if "exitpolicy" in event.config.keys():
-          self._set_cache({"exitpolicy": None})
+        if 'exitpolicy' in event.config.keys():
+          self._set_cache({'exitpolicy': None})
 
     self.add_event_listener(_confchanged_listener, EventType.CONF_CHANGED)
 
@@ -820,7 +820,7 @@ class Controller(BaseController):
     # making a best-effort attempt to quit before detaching the socket
     if self.is_alive():
       try:
-        self.msg("QUIT")
+        self.msg('QUIT')
       except:
         pass
 
@@ -883,7 +883,7 @@ class Controller(BaseController):
     # check for cached results
 
     from_cache = [param.lower() for param in params]
-    cached_results = self._get_cache_map(from_cache, "getinfo")
+    cached_results = self._get_cache_map(from_cache, 'getinfo')
 
     for key in cached_results:
       user_expected_key = _case_insensitive_lookup(params, key)
@@ -894,13 +894,13 @@ class Controller(BaseController):
       if param.startswith('ip-to-country/') and self.is_geoip_unavailable():
         # the geoip database already looks to be unavailable - abort the request
         if default == UNDEFINED:
-          raise stem.ProtocolError("Tor geoip database is unavailable")
+          raise stem.ProtocolError('Tor geoip database is unavailable')
         else:
           return default
 
     # if everything was cached then short circuit making the query
     if not params:
-      log.trace("GETINFO %s (cache fetch)" % " ".join(reply.keys()))
+      log.trace('GETINFO %s (cache fetch)' % ' '.join(reply.keys()))
 
       if is_multiple:
         return reply
@@ -908,8 +908,8 @@ class Controller(BaseController):
         return reply.values()[0]
 
     try:
-      response = self.msg("GETINFO %s" % " ".join(params))
-      stem.response.convert("GETINFO", response)
+      response = self.msg('GETINFO %s' % ' '.join(params))
+      stem.response.convert('GETINFO', response)
       response._assert_matches(params)
 
       # usually we want unicode values under python 3.x
@@ -932,9 +932,9 @@ class Controller(BaseController):
             to_cache[key] = value
             self._geoip_failure_count = -1
 
-        self._set_cache(to_cache, "getinfo")
+        self._set_cache(to_cache, 'getinfo')
 
-      log.debug("GETINFO %s (runtime: %0.4f)" % (" ".join(params), time.time() - start_time))
+      log.debug('GETINFO %s (runtime: %0.4f)' % (' '.join(params), time.time() - start_time))
 
       if is_multiple:
         return reply
@@ -954,7 +954,7 @@ class Controller(BaseController):
         if self.is_geoip_unavailable():
           log.warn("Tor's geoip database is unavailable.")
 
-      log.debug("GETINFO %s (failed: %s)" % (" ".join(params), exc))
+      log.debug('GETINFO %s (failed: %s)' % (' '.join(params), exc))
 
       if default == UNDEFINED:
         raise exc
@@ -979,11 +979,11 @@ class Controller(BaseController):
     """
 
     try:
-      version = self._get_cache("version")
+      version = self._get_cache('version')
 
       if not version:
-        version = stem.version.Version(self.get_info("version"))
-        self._set_cache({"version": version})
+        version = stem.version.Version(self.get_info('version'))
+        self._set_cache({'version': version})
 
       return version
     except Exception as exc:
@@ -1008,28 +1008,29 @@ class Controller(BaseController):
 
       An exception is only raised if we weren't provided a default response.
     """
+
     with self._msg_lock:
       try:
-        config_policy = self._get_cache("exit_policy")
+        config_policy = self._get_cache('exit_policy')
 
         if not config_policy:
           policy = []
 
-          if self.get_conf("ExitPolicyRejectPrivate") == "1":
-            policy.append("reject private:*")
+          if self.get_conf('ExitPolicyRejectPrivate') == '1':
+            policy.append('reject private:*')
 
-            public_addr = self.get_info("address", None)
+            public_addr = self.get_info('address', None)
 
             if public_addr:
-              policy.append("reject %s:*" % public_addr)
+              policy.append('reject %s:*' % public_addr)
 
-          for policy_line in self.get_conf("ExitPolicy", multiple = True):
-            policy += policy_line.split(",")
+          for policy_line in self.get_conf('ExitPolicy', multiple = True):
+            policy += policy_line.split(',')
 
-          policy += self.get_info("exit-policy/default").split(",")
+          policy += self.get_info('exit-policy/default').split(',')
 
           config_policy = stem.exit_policy.get_config_policy(policy)
-          self._set_cache({"exit_policy": config_policy})
+          self._set_cache({'exit_policy': config_policy})
 
         return config_policy
       except Exception as exc:
@@ -1144,9 +1145,9 @@ class Controller(BaseController):
 
       for addr, port in proxy_addrs:
         if not stem.util.connection.is_valid_ipv4_address(addr):
-          raise stem.ProtocolError("Invalid address for a %s listener: %s" % (listener_type, addr))
+          raise stem.ProtocolError('Invalid address for a %s listener: %s' % (listener_type, addr))
         elif not stem.util.connection.is_valid_port(port):
-          raise stem.ProtocolError("Invalid port for a %s listener: %s" % (listener_type, port))
+          raise stem.ProtocolError('Invalid port for a %s listener: %s' % (listener_type, port))
 
       return [(addr, int(port)) for (addr, port) in proxy_addrs]
     except Exception as exc:
@@ -1214,10 +1215,10 @@ class Controller(BaseController):
     :returns: str with the username tor is running as
     """
 
-    user = self._get_cache("user")
+    user = self._get_cache('user')
 
     if not user:
-      user = self.get_info("process/user", None)
+      user = self.get_info('process/user', None)
 
     if not user and self.get_socket().is_localhost():
       pid = self.get_pid(None)
@@ -1226,7 +1227,7 @@ class Controller(BaseController):
         user = stem.util.system.get_user(pid)
 
     if user:
-      self._set_cache({"user": user})
+      self._set_cache({'user': user})
       return user
     elif default == UNDEFINED:
       if self.get_socket().is_localhost():
@@ -1252,16 +1253,16 @@ class Controller(BaseController):
       provided
     """
 
-    pid = self._get_cache("pid")
+    pid = self._get_cache('pid')
 
     if not pid:
-      getinfo_pid = self.get_info("process/pid", None)
+      getinfo_pid = self.get_info('process/pid', None)
 
       if getinfo_pid and getinfo_pid.isdigit():
         pid = int(getinfo_pid)
 
     if not pid and self.get_socket().is_localhost():
-      pid_file_path = self.get_conf("PidFile", None)
+      pid_file_path = self.get_conf('PidFile', None)
 
       if pid_file_path is not None:
         with open(pid_file_path) as pid_file:
@@ -1282,7 +1283,7 @@ class Controller(BaseController):
           pid = stem.util.system.get_pid_by_open_file(control_socket.get_socket_path())
 
     if pid:
-      self._set_cache({"pid": pid})
+      self._set_cache({'pid': pid})
       return pid
     elif default == UNDEFINED:
       if self.get_socket().is_localhost():
@@ -1313,9 +1314,9 @@ class Controller(BaseController):
 
     try:
       if stem.util.tor_tools.is_valid_fingerprint(relay):
-        query = "md/id/%s" % relay
+        query = 'md/id/%s' % relay
       elif stem.util.tor_tools.is_valid_nickname(relay):
-        query = "md/name/%s" % relay
+        query = 'md/name/%s' % relay
       else:
         raise ValueError("'%s' isn't a valid fingerprint or nickname" % relay)
 
@@ -1348,11 +1349,11 @@ class Controller(BaseController):
 
     try:
       try:
-        data_directory = self.get_conf("DataDirectory")
+        data_directory = self.get_conf('DataDirectory')
       except stem.ControllerError as exc:
-        raise stem.OperationFailed(message = "Unable to determine the data directory (%s)" % exc)
+        raise stem.OperationFailed(message = 'Unable to determine the data directory (%s)' % exc)
 
-      cached_descriptor_path = os.path.join(data_directory, "cached-microdescs")
+      cached_descriptor_path = os.path.join(data_directory, 'cached-microdescs')
 
       if not os.path.exists(data_directory):
         raise stem.OperationFailed(message = "Data directory reported by tor doesn't exist (%s)" % data_directory)
@@ -1365,7 +1366,7 @@ class Controller(BaseController):
           # microdescriptors but as the saying goes: trust but verify.
 
           if not isinstance(desc, stem.descriptor.microdescriptor.Microdescriptor):
-            raise stem.OperationFailed(message = "BUG: Descriptor reader provided non-microdescriptor content (%s)" % type(desc))
+            raise stem.OperationFailed(message = 'BUG: Descriptor reader provided non-microdescriptor content (%s)' % type(desc))
 
           yield desc
     except Exception as exc:
@@ -1402,9 +1403,9 @@ class Controller(BaseController):
 
     try:
       if stem.util.tor_tools.is_valid_fingerprint(relay):
-        query = "desc/id/%s" % relay
+        query = 'desc/id/%s' % relay
       elif stem.util.tor_tools.is_valid_nickname(relay):
-        query = "desc/name/%s" % relay
+        query = 'desc/name/%s' % relay
       else:
         raise ValueError("'%s' isn't a valid fingerprint or nickname" % relay)
 
@@ -1445,7 +1446,7 @@ class Controller(BaseController):
       #
       # https://trac.torproject.org/8248
 
-      desc_content = self.get_info("desc/all-recent", get_bytes = True)
+      desc_content = self.get_info('desc/all-recent', get_bytes = True)
 
       if not desc_content and not self._is_server_descriptors_available():
         raise ValueError(SERVER_DESCRIPTORS_UNSUPPORTED)
@@ -1506,9 +1507,9 @@ class Controller(BaseController):
 
     try:
       if stem.util.tor_tools.is_valid_fingerprint(relay):
-        query = "ns/id/%s" % relay
+        query = 'ns/id/%s' % relay
       elif stem.util.tor_tools.is_valid_nickname(relay):
-        query = "ns/name/%s" % relay
+        query = 'ns/name/%s' % relay
       else:
         raise ValueError("'%s' isn't a valid fingerprint or nickname" % relay)
 
@@ -1561,7 +1562,7 @@ class Controller(BaseController):
       #
       # https://trac.torproject.org/8248
 
-      desc_content = self.get_info("ns/all", get_bytes = True)
+      desc_content = self.get_info('ns/all', get_bytes = True)
 
       desc_iterator = stem.descriptor.router_status_entry._parse_file(
         io.BytesIO(desc_content),
@@ -1687,7 +1688,7 @@ class Controller(BaseController):
     # check for cached results
 
     from_cache = [param.lower() for param in lookup_params]
-    cached_results = self._get_cache_map(from_cache, "getconf")
+    cached_results = self._get_cache_map(from_cache, 'getconf')
 
     for key in cached_results:
       user_expected_key = _case_insensitive_lookup(lookup_params, key)
@@ -1696,12 +1697,12 @@ class Controller(BaseController):
 
     # if everything was cached then short circuit making the query
     if not lookup_params:
-      log.trace("GETCONF %s (cache fetch)" % " ".join(reply.keys()))
+      log.trace('GETCONF %s (cache fetch)' % ' '.join(reply.keys()))
       return self._get_conf_dict_to_response(reply, default, multiple)
 
     try:
-      response = self.msg("GETCONF %s" % ' '.join(lookup_params))
-      stem.response.convert("GETCONF", response)
+      response = self.msg('GETCONF %s' % ' '.join(lookup_params))
+      stem.response.convert('GETCONF', response)
       reply.update(response.entries)
 
       if self.is_caching_enabled():
@@ -1711,7 +1712,7 @@ class Controller(BaseController):
           if key in to_cache:
             del to_cache[key]
 
-        self._set_cache(to_cache, "getconf")
+        self._set_cache(to_cache, 'getconf')
 
       # Maps the entries back to the parameters that the user requested so the
       # capitalization matches (ie, if they request "exitpolicy" then that
@@ -1731,10 +1732,10 @@ class Controller(BaseController):
             reply[user_expected_key] = reply[key]
             del reply[key]
 
-      log.debug("GETCONF %s (runtime: %0.4f)" % (" ".join(lookup_params), time.time() - start_time))
+      log.debug('GETCONF %s (runtime: %0.4f)' % (' '.join(lookup_params), time.time() - start_time))
       return self._get_conf_dict_to_response(reply, default, multiple)
     except stem.ControllerError as exc:
-      log.debug("GETCONF %s (failed: %s)" % (" ".join(lookup_params), exc))
+      log.debug('GETCONF %s (failed: %s)' % (' '.join(lookup_params), exc))
 
       if default != UNDEFINED:
         return dict((param, default) for param in params)
@@ -1810,10 +1811,10 @@ class Controller(BaseController):
     ::
 
       my_controller.set_options({
-        "Nickname": "caerSidi",
-        "ExitPolicy": ["accept *:80", "accept *:443", "reject *:*"],
-        "ContactInfo": "caerSidi-exit@xxxxxxxxxxxxx",
-        "Log": None,
+        'Nickname': 'caerSidi',
+        'ExitPolicy': ['accept *:80', 'accept *:443', 'reject *:*'],
+        'ContactInfo': 'caerSidi-exit@xxxxxxxxxxxxx',
+        'Log': None,
       })
 
     The params can optionally be a list of key/value tuples, though the only
@@ -1836,25 +1837,25 @@ class Controller(BaseController):
     start_time = time.time()
 
     # constructs the SETCONF or RESETCONF query
-    query_comp = ["RESETCONF" if reset else "SETCONF"]
+    query_comp = ['RESETCONF' if reset else 'SETCONF']
 
     if isinstance(params, dict):
       params = params.items()
 
     for param, value in params:
       if isinstance(value, str):
-        query_comp.append("%s=\"%s\"" % (param, value.strip()))
+        query_comp.append('%s="%s"' % (param, value.strip()))
       elif value:
-        query_comp.extend(["%s=\"%s\"" % (param, val.strip()) for val in value])
+        query_comp.extend(['%s="%s"' % (param, val.strip()) for val in value])
       else:
         query_comp.append(param)
 
-    query = " ".join(query_comp)
+    query = ' '.join(query_comp)
     response = self.msg(query)
-    stem.response.convert("SINGLELINE", response)
+    stem.response.convert('SINGLELINE', response)
 
     if response.is_ok():
-      log.debug("%s (runtime: %0.4f)" % (query, time.time() - start_time))
+      log.debug('%s (runtime: %0.4f)' % (query, time.time() - start_time))
 
       if self.is_caching_enabled():
         to_cache = {}
@@ -1867,22 +1868,22 @@ class Controller(BaseController):
 
           to_cache[param] = value
 
-          if param == "exitpolicy":
-            self._set_cache({"exitpolicy": None})
+          if param == 'exitpolicy':
+            self._set_cache({'exitpolicy': None})
 
-        self._set_cache(to_cache, "getconf")
+        self._set_cache(to_cache, 'getconf')
     else:
-      log.debug("%s (failed, code: %s, message: %s)" % (query, response.code, response.message))
+      log.debug('%s (failed, code: %s, message: %s)' % (query, response.code, response.message))
 
-      if response.code == "552":
+      if response.code == '552':
         if response.message.startswith("Unrecognized option: Unknown option '"):
-          key = response.message[37:response.message.find("\'", 37)]
+          key = response.message[37:response.message.find("'", 37)]
           raise stem.InvalidArguments(response.code, response.message, [key])
         raise stem.InvalidRequest(response.code, response.message)
-      elif response.code in ("513", "553"):
+      elif response.code in ('513', '553'):
         raise stem.InvalidRequest(response.code, response.message)
       else:
-        raise stem.ProtocolError("Returned unexpected status code: %s" % response.code)
+        raise stem.ProtocolError('Returned unexpected status code: %s' % response.code)
 
   def add_event_listener(self, listener, *events):
     """
@@ -1897,7 +1898,7 @@ class Controller(BaseController):
       from stem.control import Controller, EventType
 
       def print_bw(event):
-        print "sent: %i, received: %i" % (event.written, event.read)
+        print 'sent: %i, received: %i' % (event.written, event.read)
 
       with Controller.from_port(port = 9051) as controller:
         controller.authenticate()
@@ -1920,7 +1921,7 @@ class Controller(BaseController):
           event_type = stem.response.events.EVENT_TYPE_TO_CLASS.get(event_type)
 
           if event_type and (self.get_version() < event_type._VERSION_ADDED):
-            raise stem.InvalidRequest(552, "%s event requires Tor version %s or later" % (event_type, event_type._VERSION_ADDED))
+            raise stem.InvalidRequest(552, '%s event requires Tor version %s or later' % (event_type, event_type._VERSION_ADDED))
 
       for event_type in events:
         self._event_listeners.setdefault(event_type, []).append(listener)
@@ -1931,7 +1932,7 @@ class Controller(BaseController):
       failed_events = set(failed_events).intersection(set(events))
 
       if failed_events:
-        raise stem.ProtocolError("SETEVENTS rejected %s" % ", ".join(failed_events))
+        raise stem.ProtocolError('SETEVENTS rejected %s' % ', '.join(failed_events))
 
   def remove_event_listener(self, listener):
     """
@@ -1954,10 +1955,10 @@ class Controller(BaseController):
             del self._event_listeners[event_type]
 
       if event_types_changed:
-        response = self.msg("SETEVENTS %s" % " ".join(self._event_listeners.keys()))
+        response = self.msg('SETEVENTS %s' % ' '.join(self._event_listeners.keys()))
 
         if not response.is_ok():
-          raise stem.ProtocolError("SETEVENTS received unexpected response\n%s" % response)
+          raise stem.ProtocolError('SETEVENTS received unexpected response\n%s' % response)
 
   def _get_cache(self, param, namespace = None):
     """
@@ -1987,7 +1988,7 @@ class Controller(BaseController):
       if self.is_caching_enabled():
         for param in params:
           if namespace:
-            cache_key = "%s.%s" % (namespace, param)
+            cache_key = '%s.%s' % (namespace, param)
           else:
             cache_key = param
 
@@ -2011,7 +2012,7 @@ class Controller(BaseController):
 
       for key, value in params.items():
         if namespace:
-          cache_key = "%s.%s" % (namespace, key)
+          cache_key = '%s.%s' % (namespace, key)
         else:
           cache_key = key
 
@@ -2062,15 +2063,15 @@ class Controller(BaseController):
     :raises: :class:`stem.ControllerError` if the call fails
     """
 
-    response = self.msg("LOADCONF\n%s" % configtext)
-    stem.response.convert("SINGLELINE", response)
+    response = self.msg('LOADCONF\n%s' % configtext)
+    stem.response.convert('SINGLELINE', response)
 
-    if response.code in ("552", "553"):
-      if response.code == "552" and response.message.startswith("Invalid config file: Failed to parse/validate config: Unknown option"):
+    if response.code in ('552', '553'):
+      if response.code == '552' and response.message.startswith('Invalid config file: Failed to parse/validate config: Unknown option'):
         raise stem.InvalidArguments(response.code, response.message, [response.message[70:response.message.find('.', 70) - 1]])
       raise stem.InvalidRequest(response.code, response.message)
     elif not response.is_ok():
-      raise stem.ProtocolError("+LOADCONF Received unexpected response\n%s" % str(response))
+      raise stem.ProtocolError('+LOADCONF Received unexpected response\n%s' % str(response))
 
   def save_conf(self):
     """
@@ -2082,15 +2083,15 @@ class Controller(BaseController):
         the configuration file
     """
 
-    response = self.msg("SAVECONF")
-    stem.response.convert("SINGLELINE", response)
+    response = self.msg('SAVECONF')
+    stem.response.convert('SINGLELINE', response)
 
     if response.is_ok():
       return True
-    elif response.code == "551":
+    elif response.code == '551':
       raise stem.OperationFailed(response.code, response.message)
     else:
-      raise stem.ProtocolError("SAVECONF returned unexpected response code")
+      raise stem.ProtocolError('SAVECONF returned unexpected response code')
 
   def is_feature_enabled(self, feature):
     """
@@ -2110,9 +2111,9 @@ class Controller(BaseController):
       # check if this feature is on by default
       defaulted_version = None
 
-      if feature == "EXTENDED_EVENTS":
+      if feature == 'EXTENDED_EVENTS':
         defaulted_version = stem.version.Requirement.FEATURE_EXTENDED_EVENTS
-      elif feature == "VERBOSE_NAMES":
+      elif feature == 'VERBOSE_NAMES':
         defaulted_version = stem.version.Requirement.FEATURE_VERBOSE_NAMES
 
       if defaulted_version:
@@ -2145,19 +2146,19 @@ class Controller(BaseController):
     if isinstance(features, (bytes, unicode)):
       features = [features]
 
-    response = self.msg("USEFEATURE %s" % " ".join(features))
-    stem.response.convert("SINGLELINE", response)
+    response = self.msg('USEFEATURE %s' % ' '.join(features))
+    stem.response.convert('SINGLELINE', response)
 
     if not response.is_ok():
-      if response.code == "552":
+      if response.code == '552':
         invalid_feature = []
 
-        if response.message.startswith("Unrecognized feature \""):
-          invalid_feature = [response.message[22:response.message.find("\"", 22)]]
+        if response.message.startswith('Unrecognized feature "'):
+          invalid_feature = [response.message[22:response.message.find('"', 22)]]
 
         raise stem.InvalidArguments(response.code, response.message, invalid_feature)
 
-      raise stem.ProtocolError("USEFEATURE provided an invalid response code: %s" % response.code)
+      raise stem.ProtocolError('USEFEATURE provided an invalid response code: %s' % response.code)
 
     self._enabled_features += [entry.upper() for entry in features]
 
@@ -2202,11 +2203,11 @@ class Controller(BaseController):
 
     try:
       circuits = []
-      response = self.get_info("circuit-status")
+      response = self.get_info('circuit-status')
 
       for circ in response.splitlines():
-        circ_message = stem.socket.recv_message(StringIO.StringIO("650 CIRC " + circ + "\r\n"))
-        stem.response.convert("EVENT", circ_message, arrived_at = 0)
+        circ_message = stem.socket.recv_message(StringIO.StringIO('650 CIRC ' + circ + '\r\n'))
+        stem.response.convert('EVENT', circ_message, arrived_at = 0)
         circuits.append(circ_message)
 
       return circuits
@@ -2216,13 +2217,13 @@ class Controller(BaseController):
       else:
         return default
 
-  def new_circuit(self, path = None, purpose = "general", await_build = False):
+  def new_circuit(self, path = None, purpose = 'general', await_build = False):
     """
     Requests a new circuit. If the path isn't provided, one is automatically
     selected.
 
     :param list,str path: one or more relays to make a circuit through
-    :param str purpose: "general" or "controller"
+    :param str purpose: 'general' or 'controller'
     :param bool await_build: blocks until the circuit is built if **True**
 
     :returns: str of the circuit id of the newly created circuit
@@ -2232,7 +2233,7 @@ class Controller(BaseController):
 
     return self.extend_circuit('0', path, purpose, await_build)
 
-  def extend_circuit(self, circuit_id = "0", path = None, purpose = "general", await_build = False):
+  def extend_circuit(self, circuit_id = '0', path = None, purpose = 'general', await_build = False):
     """
     Either requests the creation of a new circuit or extends an existing one.
 
@@ -2244,7 +2245,7 @@ class Controller(BaseController):
 
     ::
 
-      >>> controller.extend_circuit('0', ["718BCEA286B531757ACAFF93AE04910EA73DE617", "30BAB8EE7606CBD12F3CC269AE976E0153E7A58D", "2765D8A8C4BBA3F89585A9FFE0E8575615880BEB"])
+      >>> controller.extend_circuit('0', ['718BCEA286B531757ACAFF93AE04910EA73DE617', '30BAB8EE7606CBD12F3CC269AE976E0153E7A58D', '2765D8A8C4BBA3F89585A9FFE0E8575615880BEB'])
       19
       >>> controller.extend_circuit('0')
       20
@@ -2255,7 +2256,7 @@ class Controller(BaseController):
     :param str circuit_id: id of a circuit to be extended
     :param list,str path: one or more relays to make a circuit through, this is
       required if the circuit id is non-zero
-    :param str purpose: "general" or "controller"
+    :param str purpose: 'general' or 'controller'
     :param bool await_build: blocks until the circuit is built if **True**
 
     :returns: str of the circuit id of the created or extended circuit
@@ -2289,7 +2290,7 @@ class Controller(BaseController):
         path_opt_version = stem.version.Requirement.EXTENDCIRCUIT_PATH_OPTIONAL
 
         if not self.get_version() >= path_opt_version:
-          raise stem.InvalidRequest(512, "EXTENDCIRCUIT requires the path prior to version %s" % path_opt_version)
+          raise stem.InvalidRequest(512, 'EXTENDCIRCUIT requires the path prior to version %s' % path_opt_version)
 
       args = [circuit_id]
 
@@ -2297,23 +2298,23 @@ class Controller(BaseController):
         path = [path]
 
       if path:
-        args.append(",".join(path))
+        args.append(','.join(path))
 
       if purpose:
-        args.append("purpose=%s" % purpose)
+        args.append('purpose=%s' % purpose)
 
-      response = self.msg("EXTENDCIRCUIT %s" % " ".join(args))
-      stem.response.convert("SINGLELINE", response)
+      response = self.msg('EXTENDCIRCUIT %s' % ' '.join(args))
+      stem.response.convert('SINGLELINE', response)
 
       if response.code in ('512', '552'):
         raise stem.InvalidRequest(response.code, response.message)
       elif not response.is_ok():
-        raise stem.ProtocolError("EXTENDCIRCUIT returned unexpected response code: %s" % response.code)
+        raise stem.ProtocolError('EXTENDCIRCUIT returned unexpected response code: %s' % response.code)
 
-      if not response.message.startswith("EXTENDED "):
-        raise stem.ProtocolError("EXTENDCIRCUIT response invalid:\n%s", response)
+      if not response.message.startswith('EXTENDED '):
+        raise stem.ProtocolError('EXTENDCIRCUIT response invalid:\n%s', response)
 
-      new_circuit = response.message.split(" ", 1)[1]
+      new_circuit = response.message.split(' ', 1)[1]
 
       if await_build:
         while True:
@@ -2323,9 +2324,9 @@ class Controller(BaseController):
             if circ.status == CircStatus.BUILT:
               break
             elif circ.status == CircStatus.FAILED:
-              raise stem.CircuitExtensionFailed("Circuit failed to be created: %s" % circ.reason, circ)
+              raise stem.CircuitExtensionFailed('Circuit failed to be created: %s' % circ.reason, circ)
             elif circ.status == CircStatus.CLOSED:
-              raise stem.CircuitExtensionFailed("Circuit was closed prior to build", circ)
+              raise stem.CircuitExtensionFailed('Circuit was closed prior to build', circ)
 
       return new_circuit
     finally:
@@ -2339,19 +2340,19 @@ class Controller(BaseController):
       * controller
 
     :param str circuit_id: id of the circuit whose purpose is to be changed
-    :param str purpose: purpose (either "general" or "controller")
+    :param str purpose: purpose (either 'general' or 'controller')
 
     :raises: :class:`stem.InvalidArguments` if the circuit doesn't exist or if the purpose was invalid
     """
 
-    response = self.msg("SETCIRCUITPURPOSE %s purpose=%s" % (circuit_id, purpose))
-    stem.response.convert("SINGLELINE", response)
+    response = self.msg('SETCIRCUITPURPOSE %s purpose=%s' % (circuit_id, purpose))
+    stem.response.convert('SINGLELINE', response)
 
     if not response.is_ok():
-      if response.code == "552":
+      if response.code == '552':
         raise stem.InvalidRequest(response.code, response.message)
       else:
-        raise stem.ProtocolError("SETCIRCUITPURPOSE returned unexpected response code: %s" % response.code)
+        raise stem.ProtocolError('SETCIRCUITPURPOSE returned unexpected response code: %s' % response.code)
 
   def close_circuit(self, circuit_id, flag = ''):
     """
@@ -2359,22 +2360,22 @@ class Controller(BaseController):
 
     :param str circuit_id: id of the circuit to be closed
     :param str flag: optional value to modify closing, the only flag available
-      is "IfUnused" which will not close the circuit unless it is unused
+      is 'IfUnused' which will not close the circuit unless it is unused
 
     :raises: :class:`stem.InvalidArguments` if the circuit is unknown
     :raises: :class:`stem.InvalidRequest` if not enough information is provided
     """
 
-    response = self.msg("CLOSECIRCUIT %s %s" % (circuit_id, flag))
-    stem.response.convert("SINGLELINE", response)
+    response = self.msg('CLOSECIRCUIT %s %s' % (circuit_id, flag))
+    stem.response.convert('SINGLELINE', response)
 
     if not response.is_ok():
       if response.code in ('512', '552'):
-        if response.message.startswith("Unknown circuit "):
+        if response.message.startswith('Unknown circuit '):
           raise stem.InvalidArguments(response.code, response.message, [circuit_id])
         raise stem.InvalidRequest(response.code, response.message)
       else:
-        raise stem.ProtocolError("CLOSECIRCUIT returned unexpected response code: %s" % response.code)
+        raise stem.ProtocolError('CLOSECIRCUIT returned unexpected response code: %s' % response.code)
 
   def get_streams(self, default = UNDEFINED):
     """
@@ -2390,11 +2391,11 @@ class Controller(BaseController):
 
     try:
       streams = []
-      response = self.get_info("stream-status")
+      response = self.get_info('stream-status')
 
       for stream in response.splitlines():
-        message = stem.socket.recv_message(StringIO.StringIO("650 STREAM " + stream + "\r\n"))
-        stem.response.convert("EVENT", message, arrived_at = 0)
+        message = stem.socket.recv_message(StringIO.StringIO('650 STREAM ' + stream + '\r\n'))
+        stem.response.convert('EVENT', message, arrived_at = 0)
         streams.append(message)
 
       return streams
@@ -2409,7 +2410,7 @@ class Controller(BaseController):
     Attaches a stream to a circuit.
 
     Note: Tor attaches streams to circuits automatically unless the
-    __LeaveStreamsUnattached configuration variable is set to "1"
+    __LeaveStreamsUnattached configuration variable is set to '1'
 
     :param str stream_id: id of the stream that must be attached
     :param str circuit_id: id of the circuit to which it must be attached
@@ -2421,13 +2422,13 @@ class Controller(BaseController):
       * :class:`stem.OperationFailed` if the stream couldn't be attached for any other reason
     """
 
-    query = "ATTACHSTREAM %s %s" % (stream_id, circuit_id)
+    query = 'ATTACHSTREAM %s %s' % (stream_id, circuit_id)
 
     if exiting_hop:
-      query += " HOP=%s" % exiting_hop
+      query += ' HOP=%s' % exiting_hop
 
     response = self.msg(query)
-    stem.response.convert("SINGLELINE", response)
+    stem.response.convert('SINGLELINE', response)
 
     if not response.is_ok():
       if response.code == '552':
@@ -2437,7 +2438,7 @@ class Controller(BaseController):
       elif response.code == '555':
         raise stem.UnsatisfiableRequest(response.code, response.message)
       else:
-        raise stem.ProtocolError("ATTACHSTREAM returned unexpected response code: %s" % response.code)
+        raise stem.ProtocolError('ATTACHSTREAM returned unexpected response code: %s' % response.code)
 
   def close_stream(self, stream_id, reason = stem.RelayEndReason.MISC, flag = ''):
     """
@@ -2454,18 +2455,18 @@ class Controller(BaseController):
     # there's a single value offset between RelayEndReason.index_of() and the
     # value that tor expects since tor's value starts with the index of one
 
-    response = self.msg("CLOSESTREAM %s %s %s" % (stream_id, stem.RelayEndReason.index_of(reason) + 1, flag))
-    stem.response.convert("SINGLELINE", response)
+    response = self.msg('CLOSESTREAM %s %s %s' % (stream_id, stem.RelayEndReason.index_of(reason) + 1, flag))
+    stem.response.convert('SINGLELINE', response)
 
     if not response.is_ok():
       if response.code in ('512', '552'):
-        if response.message.startswith("Unknown stream "):
+        if response.message.startswith('Unknown stream '):
           raise stem.InvalidArguments(response.code, response.message, [stream_id])
-        elif response.message.startswith("Unrecognized reason "):
+        elif response.message.startswith('Unrecognized reason '):
           raise stem.InvalidArguments(response.code, response.message, [reason])
         raise stem.InvalidRequest(response.code, response.message)
       else:
-        raise stem.ProtocolError("CLOSESTREAM returned unexpected response code: %s" % response.code)
+        raise stem.ProtocolError('CLOSESTREAM returned unexpected response code: %s' % response.code)
 
   def signal(self, signal):
     """
@@ -2476,17 +2477,17 @@ class Controller(BaseController):
     :raises: :class:`stem.InvalidArguments` if signal provided wasn't recognized
     """
 
-    response = self.msg("SIGNAL %s" % signal)
-    stem.response.convert("SINGLELINE", response)
+    response = self.msg('SIGNAL %s' % signal)
+    stem.response.convert('SINGLELINE', response)
 
     if response.is_ok():
       if signal == stem.Signal.NEWNYM:
         self._last_newnym = time.time()
     else:
-      if response.code == "552":
+      if response.code == '552':
         raise stem.InvalidArguments(response.code, response.message, [signal])
 
-      raise stem.ProtocolError("SIGNAL response contained unrecognized status code: %s" % response.code)
+      raise stem.ProtocolError('SIGNAL response contained unrecognized status code: %s' % response.code)
 
   def is_newnym_available(self):
     """
@@ -2537,8 +2538,8 @@ class Controller(BaseController):
     Map addresses to replacement addresses. Tor replaces subseqent connections
     to the original addresses with the replacement addresses.
 
-    If the original address is a null address, i.e., one of "0.0.0.0", "::0", or
-    "." Tor picks an original address itself and returns it in the reply. If the
+    If the original address is a null address, i.e., one of '0.0.0.0', '::0', or
+    '.' Tor picks an original address itself and returns it in the reply. If the
     original address is already mapped to a different address the mapping is
     removed.
 
@@ -2551,9 +2552,9 @@ class Controller(BaseController):
     :returns: **dict** with 'original -> replacement' address mappings
     """
 
-    mapaddress_arg = " ".join(["%s=%s" % (k, v) for (k, v) in mapping.items()])
-    response = self.msg("MAPADDRESS %s" % mapaddress_arg)
-    stem.response.convert("MAPADDRESS", response)
+    mapaddress_arg = ' '.join(['%s=%s' % (k, v) for (k, v) in mapping.items()])
+    response = self.msg('MAPADDRESS %s' % mapaddress_arg)
+    stem.response.convert('MAPADDRESS', response)
 
     return response.entries
 
@@ -2571,32 +2572,32 @@ class Controller(BaseController):
           for event_type in failed_events:
             del self._event_listeners[event_type]
 
-          logging_id = "stem.controller.event_reattach-%s" % "-".join(failed_events)
-          log.log_once(logging_id, log.WARN, "We were unable to re-attach our event listeners to the new tor instance for: %s" % ", ".join(failed_events))
+          logging_id = 'stem.controller.event_reattach-%s' % '-'.join(failed_events)
+          log.log_once(logging_id, log.WARN, 'We were unable to re-attach our event listeners to the new tor instance for: %s' % ', '.join(failed_events))
       except stem.ProtocolError as exc:
-        log.warn("Unable to issue the SETEVENTS request to re-attach our listeners (%s)" % exc)
+        log.warn('Unable to issue the SETEVENTS request to re-attach our listeners (%s)' % exc)
 
     # issue TAKEOWNERSHIP if we're the owning process for this tor instance
 
-    owning_pid = self.get_conf("__OwningControllerProcess", None)
+    owning_pid = self.get_conf('__OwningControllerProcess', None)
 
     if owning_pid == str(os.getpid()) and self.get_socket().is_localhost():
-      response = self.msg("TAKEOWNERSHIP")
-      stem.response.convert("SINGLELINE", response)
+      response = self.msg('TAKEOWNERSHIP')
+      stem.response.convert('SINGLELINE', response)
 
       if response.is_ok():
         # Now that tor is tracking our ownership of the process via the control
         # connection, we can stop having it check for us via our pid.
 
         try:
-          self.reset_conf("__OwningControllerProcess")
+          self.reset_conf('__OwningControllerProcess')
         except stem.ControllerError as exc:
           log.warn("We were unable to reset tor's __OwningControllerProcess configuration. It will continue to periodically check if our pid exists. (%s)" % exc)
       else:
-        log.warn("We were unable assert ownership of tor through TAKEOWNERSHIP, despite being configured to be the owning process through __OwningControllerProcess. (%s)" % response)
+        log.warn('We were unable assert ownership of tor through TAKEOWNERSHIP, despite being configured to be the owning process through __OwningControllerProcess. (%s)' % response)
 
   def _handle_event(self, event_message):
-    stem.response.convert("EVENT", event_message, arrived_at = time.time())
+    stem.response.convert('EVENT', event_message, arrived_at = time.time())
 
     with self._event_listeners_lock:
       for event_type, event_listeners in self._event_listeners.items():
@@ -2619,7 +2620,7 @@ class Controller(BaseController):
     with self._event_listeners_lock:
       if self.is_authenticated():
         # try to set them all
-        response = self.msg("SETEVENTS %s" % " ".join(self._event_listeners.keys()))
+        response = self.msg('SETEVENTS %s' % ' '.join(self._event_listeners.keys()))
 
         if response.is_ok():
           set_events = self._event_listeners.keys()
@@ -2638,7 +2639,7 @@ class Controller(BaseController):
           # See if we can set some subset of our events.
 
           for event in self._event_listeners.keys():
-            response = self.msg("SETEVENTS %s" % " ".join(set_events + [event]))
+            response = self.msg('SETEVENTS %s' % ' '.join(set_events + [event]))
 
             if response.is_ok():
               set_events.append(event)
@@ -2686,7 +2687,7 @@ def _parse_circ_path(path):
       return [_parse_circ_entry(entry) for entry in path.split(',')]
     except stem.ProtocolError as exc:
       # include the path with the exception
-      raise stem.ProtocolError("%s: %s" % (exc, path))
+      raise stem.ProtocolError('%s: %s' % (exc, path))
   else:
     return []
 
@@ -2718,12 +2719,12 @@ def _parse_circ_entry(entry):
 
   if fingerprint is not None:
     if not stem.util.tor_tools.is_valid_fingerprint(fingerprint, True):
-      raise stem.ProtocolError("Fingerprint in the circuit path is malformed (%s)" % fingerprint)
+      raise stem.ProtocolError('Fingerprint in the circuit path is malformed (%s)' % fingerprint)
 
     fingerprint = fingerprint[1:]  # strip off the leading '$'
 
   if nickname is not None and not stem.util.tor_tools.is_valid_nickname(nickname):
-    raise stem.ProtocolError("Nickname in the circuit path is malformed (%s)" % nickname)
+    raise stem.ProtocolError('Nickname in the circuit path is malformed (%s)' % nickname)
 
   return (fingerprint, nickname)
 
diff --git a/stem/descriptor/__init__.py b/stem/descriptor/__init__.py
index 7d08e91..2d7cc69 100644
--- a/stem/descriptor/__init__.py
+++ b/stem/descriptor/__init__.py
@@ -37,17 +37,17 @@ Package for parsing and processing descriptor data.
 """
 
 __all__ = [
-  "export",
-  "reader",
-  "remote",
-  "extrainfo_descriptor",
-  "server_descriptor",
-  "microdescriptor",
-  "networkstatus",
-  "router_status_entry",
-  "tordnsel",
-  "parse_file",
-  "Descriptor",
+  'export',
+  'reader',
+  'remote',
+  'extrainfo_descriptor',
+  'server_descriptor',
+  'microdescriptor',
+  'networkstatus',
+  'router_status_entry',
+  'tordnsel',
+  'parse_file',
+  'Descriptor',
 ]
 
 import os
@@ -63,16 +63,16 @@ try:
 except ImportError:
   from stem.util.ordereddict import OrderedDict
 
-KEYWORD_CHAR = "a-zA-Z0-9-"
-WHITESPACE = " \t"
-KEYWORD_LINE = re.compile("^([%s]+)(?:[%s]+(.*))?$" % (KEYWORD_CHAR, WHITESPACE))
-PGP_BLOCK_START = re.compile("^-----BEGIN ([%s%s]+)-----$" % (KEYWORD_CHAR, WHITESPACE))
-PGP_BLOCK_END = "-----END %s-----"
+KEYWORD_CHAR = 'a-zA-Z0-9-'
+WHITESPACE = ' \t'
+KEYWORD_LINE = re.compile('^([%s]+)(?:[%s]+(.*))?$' % (KEYWORD_CHAR, WHITESPACE))
+PGP_BLOCK_START = re.compile('^-----BEGIN ([%s%s]+)-----$' % (KEYWORD_CHAR, WHITESPACE))
+PGP_BLOCK_END = '-----END %s-----'
 
 DocumentHandler = stem.util.enum.UppercaseEnum(
-  "ENTRIES",
-  "DOCUMENT",
-  "BARE_DOCUMENT",
+  'ENTRIES',
+  'DOCUMENT',
+  'BARE_DOCUMENT',
 )
 
 
@@ -160,7 +160,7 @@ def parse_file(descriptor_file, descriptor_type = None, validate = True, documen
 
   initial_position = descriptor_file.tell()
   first_line = stem.util.str_tools._to_unicode(descriptor_file.readline().strip())
-  metrics_header_match = re.match("^@type (\S+) (\d+).(\d+)$", first_line)
+  metrics_header_match = re.match('^@type (\S+) (\d+).(\d+)$', first_line)
 
   if not metrics_header_match:
     descriptor_file.seek(initial_position)
@@ -170,7 +170,7 @@ def parse_file(descriptor_file, descriptor_type = None, validate = True, documen
   file_parser = None
 
   if descriptor_type is not None:
-    descriptor_type_match = re.match("^(\S+) (\d+).(\d+)$", descriptor_type)
+    descriptor_type_match = re.match('^(\S+) (\d+).(\d+)$', descriptor_type)
 
     if descriptor_type_match:
       desc_type, major_version, minor_version = descriptor_type_match.groups()
@@ -185,15 +185,15 @@ def parse_file(descriptor_file, descriptor_type = None, validate = True, documen
   else:
     # Cached descriptor handling. These contain multiple descriptors per file.
 
-    if filename == "cached-descriptors":
+    if filename == 'cached-descriptors':
       file_parser = lambda f: stem.descriptor.server_descriptor._parse_file(f, validate = validate, **kwargs)
-    elif filename == "cached-extrainfo":
+    elif filename == 'cached-extrainfo':
       file_parser = lambda f: stem.descriptor.extrainfo_descriptor._parse_file(f, validate = validate, **kwargs)
-    elif filename == "cached-microdescs":
+    elif filename == 'cached-microdescs':
       file_parser = lambda f: stem.descriptor.microdescriptor._parse_file(f, validate = validate, **kwargs)
-    elif filename == "cached-consensus":
+    elif filename == 'cached-consensus':
       file_parser = lambda f: stem.descriptor.networkstatus._parse_file(f, validate = validate, document_handler = document_handler, **kwargs)
-    elif filename == "cached-microdesc-consensus":
+    elif filename == 'cached-microdesc-consensus':
       file_parser = lambda f: stem.descriptor.networkstatus._parse_file(f, is_microdescriptor = True, validate = validate, document_handler = document_handler, **kwargs)
 
   if file_parser:
@@ -214,48 +214,48 @@ def _parse_metrics_file(descriptor_type, major_version, minor_version, descripto
   # Parses descriptor files from metrics, yielding individual descriptors. This
   # throws a TypeError if the descriptor_type or version isn't recognized.
 
-  if descriptor_type == "server-descriptor" and major_version == 1:
+  if descriptor_type == 'server-descriptor' and major_version == 1:
     for desc in stem.descriptor.server_descriptor._parse_file(descriptor_file, is_bridge = False, validate = validate, **kwargs):
       yield desc
-  elif descriptor_type == "bridge-server-descriptor" and major_version == 1:
+  elif descriptor_type == 'bridge-server-descriptor' and major_version == 1:
     for desc in stem.descriptor.server_descriptor._parse_file(descriptor_file, is_bridge = True, validate = validate, **kwargs):
       yield desc
-  elif descriptor_type == "extra-info" and major_version == 1:
+  elif descriptor_type == 'extra-info' and major_version == 1:
     for desc in stem.descriptor.extrainfo_descriptor._parse_file(descriptor_file, is_bridge = False, validate = validate, **kwargs):
       yield desc
-  elif descriptor_type == "microdescriptor" and major_version == 1:
+  elif descriptor_type == 'microdescriptor' and major_version == 1:
     for desc in stem.descriptor.microdescriptor._parse_file(descriptor_file, validate = validate, **kwargs):
       yield desc
-  elif descriptor_type == "bridge-extra-info" and major_version == 1:
+  elif descriptor_type == 'bridge-extra-info' and major_version == 1:
     # version 1.1 introduced a 'transport' field...
     # https://trac.torproject.org/6257
 
     for desc in stem.descriptor.extrainfo_descriptor._parse_file(descriptor_file, is_bridge = True, validate = validate, **kwargs):
       yield desc
-  elif descriptor_type == "network-status-2" and major_version == 1:
+  elif descriptor_type == 'network-status-2' and major_version == 1:
     document_type = stem.descriptor.networkstatus.NetworkStatusDocumentV2
 
     for desc in stem.descriptor.networkstatus._parse_file(descriptor_file, document_type, validate = validate, document_handler = document_handler, **kwargs):
       yield desc
-  elif descriptor_type == "dir-key-certificate-3" and major_version == 1:
+  elif descriptor_type == 'dir-key-certificate-3' and major_version == 1:
     for desc in stem.descriptor.networkstatus._parse_file_key_certs(descriptor_file, validate = validate, **kwargs):
       yield desc
-  elif descriptor_type in ("network-status-consensus-3", "network-status-vote-3") and major_version == 1:
+  elif descriptor_type in ('network-status-consensus-3', 'network-status-vote-3') and major_version == 1:
     document_type = stem.descriptor.networkstatus.NetworkStatusDocumentV3
 
     for desc in stem.descriptor.networkstatus._parse_file(descriptor_file, document_type, validate = validate, document_handler = document_handler, **kwargs):
       yield desc
-  elif descriptor_type == "network-status-microdesc-consensus-3" and major_version == 1:
+  elif descriptor_type == 'network-status-microdesc-consensus-3' and major_version == 1:
     document_type = stem.descriptor.networkstatus.NetworkStatusDocumentV3
 
     for desc in stem.descriptor.networkstatus._parse_file(descriptor_file, document_type, is_microdescriptor = True, validate = validate, document_handler = document_handler, **kwargs):
       yield desc
-  elif descriptor_type == "bridge-network-status" and major_version == 1:
+  elif descriptor_type == 'bridge-network-status' and major_version == 1:
     document_type = stem.descriptor.networkstatus.BridgeNetworkStatusDocument
 
     for desc in stem.descriptor.networkstatus._parse_file(descriptor_file, document_type, validate = validate, document_handler = document_handler, **kwargs):
       yield desc
-  elif descriptor_type == "tordnsel" and major_version == 1:
+  elif descriptor_type == 'tordnsel' and major_version == 1:
     document_type = stem.descriptor.tordnsel.TorDNSEL
 
     for desc in stem.descriptor.tordnsel._parse_file(descriptor_file, validate = validate, **kwargs):
@@ -346,13 +346,13 @@ def _get_bytes_field(keyword, content):
   """
 
   if not isinstance(content, bytes):
-    raise ValueError("Content must be bytes, got a %s" % type(content))
+    raise ValueError('Content must be bytes, got a %s' % type(content))
 
-  line_match = re.search(stem.util.str_tools._to_bytes("^(opt )?%s(?:[%s]+(.*))?$" % (keyword, WHITESPACE)), content, re.MULTILINE)
+  line_match = re.search(stem.util.str_tools._to_bytes('^(opt )?%s(?:[%s]+(.*))?$' % (keyword, WHITESPACE)), content, re.MULTILINE)
 
   if line_match:
     value = line_match.groups()[1]
-    return b"" if value is None else value
+    return b'' if value is None else value
   else:
     return None
 
@@ -450,13 +450,13 @@ def _get_pseudo_pgp_block(remaining_contents):
 
     while True:
       if not remaining_contents:
-        raise ValueError("Unterminated pgp style block (looking for '%s'):\n%s" % (end_line, "\n".join(block_lines)))
+        raise ValueError("Unterminated pgp style block (looking for '%s'):\n%s" % (end_line, '\n'.join(block_lines)))
 
       line = remaining_contents.pop(0)
       block_lines.append(line)
 
       if line == end_line:
-        return "\n".join(block_lines)
+        return '\n'.join(block_lines)
   else:
     return None
 
@@ -489,7 +489,7 @@ def _get_descriptor_components(raw_contents, validate, extra_keywords = ()):
 
   entries = OrderedDict()
   extra_entries = []  # entries with a keyword in extra_keywords
-  remaining_lines = raw_contents.split("\n")
+  remaining_lines = raw_contents.split('\n')
 
   while remaining_lines:
     line = remaining_lines.pop(0)
@@ -509,7 +509,7 @@ def _get_descriptor_components(raw_contents, validate, extra_keywords = ()):
     # ignored. This prefix is being removed in...
     # https://trac.torproject.org/projects/tor/ticket/5124
 
-    if line.startswith("opt "):
+    if line.startswith('opt '):
       line = line[4:]
 
     line_match = KEYWORD_LINE.match(line)
@@ -518,7 +518,7 @@ def _get_descriptor_components(raw_contents, validate, extra_keywords = ()):
       if not validate:
         continue
 
-      raise ValueError("Line contains invalid characters: %s" % line)
+      raise ValueError('Line contains invalid characters: %s' % line)
 
     keyword, value = line_match.groups()
 
@@ -534,7 +534,7 @@ def _get_descriptor_components(raw_contents, validate, extra_keywords = ()):
       raise exc
 
     if keyword in extra_keywords:
-      extra_entries.append("%s %s" % (keyword, value))
+      extra_entries.append('%s %s' % (keyword, value))
     else:
       entries.setdefault(keyword, []).append((value, block_contents))
 
diff --git a/stem/descriptor/export.py b/stem/descriptor/export.py
index ed4ef5a..09454c5 100644
--- a/stem/descriptor/export.py
+++ b/stem/descriptor/export.py
@@ -82,7 +82,7 @@ def export_csv_file(output_file, descriptors, included_fields = (), excluded_fie
   if included_fields:
     for field in included_fields:
       if not field in desc_attr:
-        raise ValueError("%s does not have a '%s' attribute, valid fields are: %s" % (descriptor_type_label, field, ", ".join(desc_attr)))
+        raise ValueError("%s does not have a '%s' attribute, valid fields are: %s" % (descriptor_type_label, field, ', '.join(desc_attr)))
   else:
     included_fields = [attr for attr in desc_attr if not attr.startswith('_')]
 
@@ -99,8 +99,8 @@ def export_csv_file(output_file, descriptors, included_fields = (), excluded_fie
 
   for desc in descriptors:
     if not isinstance(desc, stem.descriptor.Descriptor):
-      raise ValueError("Unable to export a descriptor CSV since %s is not a descriptor." % type(desc).__name__)
+      raise ValueError('Unable to export a descriptor CSV since %s is not a descriptor.' % type(desc).__name__)
     elif descriptor_type != type(desc):
-      raise ValueError("To export a descriptor CSV all of the descriptors must be of the same type. First descriptor was a %s but we later got a %s." % (descriptor_type_label, type(desc)))
+      raise ValueError('To export a descriptor CSV all of the descriptors must be of the same type. First descriptor was a %s but we later got a %s.' % (descriptor_type_label, type(desc)))
 
     writer.writerow(vars(desc))
diff --git a/stem/descriptor/extrainfo_descriptor.py b/stem/descriptor/extrainfo_descriptor.py
index 23a5917..3ccdd27 100644
--- a/stem/descriptor/extrainfo_descriptor.py
+++ b/stem/descriptor/extrainfo_descriptor.py
@@ -90,12 +90,12 @@ except ImportError:
 
 # known statuses for dirreq-v2-resp and dirreq-v3-resp...
 DirResponse = stem.util.enum.Enum(
-  ("OK", "ok"),
-  ("NOT_ENOUGH_SIGS", "not-enough-sigs"),
-  ("UNAVAILABLE", "unavailable"),
-  ("NOT_FOUND", "not-found"),
-  ("NOT_MODIFIED", "not-modified"),
-  ("BUSY", "busy"),
+  ('OK', 'ok'),
+  ('NOT_ENOUGH_SIGS', 'not-enough-sigs'),
+  ('UNAVAILABLE', 'unavailable'),
+  ('NOT_FOUND', 'not-found'),
+  ('NOT_MODIFIED', 'not-modified'),
+  ('BUSY', 'busy'),
 )
 
 # known stats for dirreq-v2/3-direct-dl and dirreq-v2/3-tunneled-dl...
@@ -106,46 +106,46 @@ DirStat = stem.util.enum.Enum(*[(stat.upper(), stat) for stat in dir_stats])
 
 # relay descriptors must have exactly one of the following
 REQUIRED_FIELDS = (
-  "extra-info",
-  "published",
-  "router-signature",
+  'extra-info',
+  'published',
+  'router-signature',
 )
 
 # optional entries that can appear at most once
 SINGLE_FIELDS = (
-  "read-history",
-  "write-history",
-  "geoip-db-digest",
-  "geoip6-db-digest",
-  "bridge-stats-end",
-  "bridge-ips",
-  "dirreq-stats-end",
-  "dirreq-v2-ips",
-  "dirreq-v3-ips",
-  "dirreq-v2-reqs",
-  "dirreq-v3-reqs",
-  "dirreq-v2-share",
-  "dirreq-v3-share",
-  "dirreq-v2-resp",
-  "dirreq-v3-resp",
-  "dirreq-v2-direct-dl",
-  "dirreq-v3-direct-dl",
-  "dirreq-v2-tunneled-dl",
-  "dirreq-v3-tunneled-dl",
-  "dirreq-read-history",
-  "dirreq-write-history",
-  "entry-stats-end",
-  "entry-ips",
-  "cell-stats-end",
-  "cell-processed-cells",
-  "cell-queued-cells",
-  "cell-time-in-queue",
-  "cell-circuits-per-decile",
-  "conn-bi-direct",
-  "exit-stats-end",
-  "exit-kibibytes-written",
-  "exit-kibibytes-read",
-  "exit-streams-opened",
+  'read-history',
+  'write-history',
+  'geoip-db-digest',
+  'geoip6-db-digest',
+  'bridge-stats-end',
+  'bridge-ips',
+  'dirreq-stats-end',
+  'dirreq-v2-ips',
+  'dirreq-v3-ips',
+  'dirreq-v2-reqs',
+  'dirreq-v3-reqs',
+  'dirreq-v2-share',
+  'dirreq-v3-share',
+  'dirreq-v2-resp',
+  'dirreq-v3-resp',
+  'dirreq-v2-direct-dl',
+  'dirreq-v3-direct-dl',
+  'dirreq-v2-tunneled-dl',
+  'dirreq-v3-tunneled-dl',
+  'dirreq-read-history',
+  'dirreq-write-history',
+  'entry-stats-end',
+  'entry-ips',
+  'cell-stats-end',
+  'cell-processed-cells',
+  'cell-queued-cells',
+  'cell-time-in-queue',
+  'cell-circuits-per-decile',
+  'conn-bi-direct',
+  'exit-stats-end',
+  'exit-kibibytes-written',
+  'exit-kibibytes-read',
+  'exit-streams-opened',
 )
 
 
@@ -168,7 +168,7 @@ def _parse_file(descriptor_file, is_bridge = False, validate = True, **kwargs):
   """
 
   while True:
-    extrainfo_content = _read_until_keywords("router-signature", descriptor_file)
+    extrainfo_content = _read_until_keywords('router-signature', descriptor_file)
 
     # we've reached the 'router-signature', now include the pgp style block
     block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0]
@@ -176,9 +176,9 @@ def _parse_file(descriptor_file, is_bridge = False, validate = True, **kwargs):
 
     if extrainfo_content:
       if is_bridge:
-        yield BridgeExtraInfoDescriptor(bytes.join(b"", extrainfo_content), validate, **kwargs)
+        yield BridgeExtraInfoDescriptor(bytes.join(b'', extrainfo_content), validate, **kwargs)
       else:
-        yield RelayExtraInfoDescriptor(bytes.join(b"", extrainfo_content), validate, **kwargs)
+        yield RelayExtraInfoDescriptor(bytes.join(b'', extrainfo_content), validate, **kwargs)
     else:
       break  # done parsing file
 
@@ -196,11 +196,11 @@ def _parse_timestamp_and_interval(keyword, content):
   :raises: **ValueError** if the content is malformed
   """
 
-  line = "%s %s" % (keyword, content)
-  content_match = re.match("^(.*) \(([0-9]+) s\)( .*)?$", content)
+  line = '%s %s' % (keyword, content)
+  content_match = re.match('^(.*) \(([0-9]+) s\)( .*)?$', content)
 
   if not content_match:
-    raise ValueError("Malformed %s line: %s" % (keyword, line))
+    raise ValueError('Malformed %s line: %s' % (keyword, line))
 
   timestamp_str, interval, remainder = content_match.groups()
 
@@ -211,7 +211,7 @@ def _parse_timestamp_and_interval(keyword, content):
     raise ValueError("%s line's interval wasn't a number: %s" % (keyword, line))
 
   try:
-    timestamp = datetime.datetime.strptime(timestamp_str, "%Y-%m-%d %H:%M:%S")
+    timestamp = datetime.datetime.strptime(timestamp_str, '%Y-%m-%d %H:%M:%S')
     return timestamp, int(interval), remainder
   except ValueError:
     raise ValueError("%s line's timestamp wasn't parsable: %s" % (keyword, line))
@@ -455,9 +455,9 @@ class ExtraInfoDescriptor(Descriptor):
     for keyword, values in entries.items():
       # most just work with the first (and only) value
       value, _ = values[0]
-      line = "%s %s" % (keyword, value)  # original line
+      line = '%s %s' % (keyword, value)  # original line
 
-      if keyword == "extra-info":
+      if keyword == 'extra-info':
         # "extra-info" Nickname Fingerprint
         extra_info_comp = value.split()
 
@@ -465,31 +465,31 @@ class ExtraInfoDescriptor(Descriptor):
           if not validate:
             continue
 
-          raise ValueError("Extra-info line must have two values: %s" % line)
+          raise ValueError('Extra-info line must have two values: %s' % line)
 
         if validate:
           if not stem.util.tor_tools.is_valid_nickname(extra_info_comp[0]):
             raise ValueError("Extra-info line entry isn't a valid nickname: %s" % extra_info_comp[0])
           elif not stem.util.tor_tools.is_valid_fingerprint(extra_info_comp[1]):
-            raise ValueError("Tor relay fingerprints consist of forty hex digits: %s" % extra_info_comp[1])
+            raise ValueError('Tor relay fingerprints consist of forty hex digits: %s' % extra_info_comp[1])
 
         self.nickname = extra_info_comp[0]
         self.fingerprint = extra_info_comp[1]
-      elif keyword == "geoip-db-digest":
+      elif keyword == 'geoip-db-digest':
         # "geoip-db-digest" Digest
 
         if validate and not stem.util.tor_tools.is_hex_digits(value, 40):
-          raise ValueError("Geoip digest line had an invalid sha1 digest: %s" % line)
+          raise ValueError('Geoip digest line had an invalid sha1 digest: %s' % line)
 
         self.geoip_db_digest = value
-      elif keyword == "geoip6-db-digest":
+      elif keyword == 'geoip6-db-digest':
         # "geoip6-db-digest" Digest
 
         if validate and not stem.util.tor_tools.is_hex_digits(value, 40):
-          raise ValueError("Geoip v6 digest line had an invalid sha1 digest: %s" % line)
+          raise ValueError('Geoip v6 digest line had an invalid sha1 digest: %s' % line)
 
         self.geoip6_db_digest = value
-      elif keyword == "transport":
+      elif keyword == 'transport':
         # "transport" transportname address:port [arglist]
         # Everything after the transportname is scrubbed in published bridge
         # descriptors, so we'll never see it in practice.
@@ -509,22 +509,22 @@ class ExtraInfoDescriptor(Descriptor):
             value_comp = transport_value.split()
 
             if len(value_comp) < 1:
-              raise ValueError("Transport line is missing its transport name: %s" % line)
+              raise ValueError('Transport line is missing its transport name: %s' % line)
             else:
               name = value_comp[0]
 
             if len(value_comp) < 2:
-              raise ValueError("Transport line is missing its address:port value: %s" % line)
-            elif not ":" in value_comp[1]:
+              raise ValueError('Transport line is missing its address:port value: %s' % line)
+            elif not ':' in value_comp[1]:
               raise ValueError("Transport line's address:port entry is missing a colon: %s" % line)
             else:
               address, port_str = value_comp[1].split(':', 1)
 
               if not stem.util.connection.is_valid_ipv4_address(address) or \
                      stem.util.connection.is_valid_ipv6_address(address):
-                raise ValueError("Transport line has a malformed address: %s" % line)
+                raise ValueError('Transport line has a malformed address: %s' % line)
               elif not stem.util.connection.is_valid_port(port_str):
-                raise ValueError("Transport line has a malformed port: %s" % line)
+                raise ValueError('Transport line has a malformed port: %s' % line)
 
               port = int(port_str)
 
@@ -534,40 +534,40 @@ class ExtraInfoDescriptor(Descriptor):
               args = []
 
           self.transport[name] = (address, port, args)
-      elif keyword == "cell-circuits-per-decile":
+      elif keyword == 'cell-circuits-per-decile':
         # "cell-circuits-per-decile" num
 
         if not value.isdigit():
           if validate:
-            raise ValueError("Non-numeric cell-circuits-per-decile value: %s" % line)
+            raise ValueError('Non-numeric cell-circuits-per-decile value: %s' % line)
           else:
             continue
 
         stat = int(value)
 
         if validate and stat < 0:
-          raise ValueError("Negative cell-circuits-per-decile value: %s" % line)
+          raise ValueError('Negative cell-circuits-per-decile value: %s' % line)
 
         self.cell_circuits_per_decile = stat
-      elif keyword in ("dirreq-v2-resp", "dirreq-v3-resp", "dirreq-v2-direct-dl", "dirreq-v3-direct-dl", "dirreq-v2-tunneled-dl", "dirreq-v3-tunneled-dl"):
+      elif keyword in ('dirreq-v2-resp', 'dirreq-v3-resp', 'dirreq-v2-direct-dl', 'dirreq-v3-direct-dl', 'dirreq-v2-tunneled-dl', 'dirreq-v3-tunneled-dl'):
         recognized_counts = {}
         unrecognized_counts = {}
 
-        is_response_stats = keyword in ("dirreq-v2-resp", "dirreq-v3-resp")
+        is_response_stats = keyword in ('dirreq-v2-resp', 'dirreq-v3-resp')
         key_set = DirResponse if is_response_stats else DirStat
 
-        key_type = "STATUS" if is_response_stats else "STAT"
-        error_msg = "%s lines should contain %s=COUNT mappings: %s" % (keyword, key_type, line)
+        key_type = 'STATUS' if is_response_stats else 'STAT'
+        error_msg = '%s lines should contain %s=COUNT mappings: %s' % (keyword, key_type, line)
 
         if value:
-          for entry in value.split(","):
-            if not "=" in entry:
+          for entry in value.split(','):
+            if not '=' in entry:
               if validate:
                 raise ValueError(error_msg)
               else:
                 continue
 
-            status, count = entry.split("=", 1)
+            status, count = entry.split('=', 1)
 
             if count.isdigit():
               if status in key_set:
@@ -577,29 +577,29 @@ class ExtraInfoDescriptor(Descriptor):
             elif validate:
               raise ValueError(error_msg)
 
-        if keyword == "dirreq-v2-resp":
+        if keyword == 'dirreq-v2-resp':
           self.dir_v2_responses = recognized_counts
           self.dir_v2_responses_unknown = unrecognized_counts
-        elif keyword == "dirreq-v3-resp":
+        elif keyword == 'dirreq-v3-resp':
           self.dir_v3_responses = recognized_counts
           self.dir_v3_responses_unknown = unrecognized_counts
-        elif keyword == "dirreq-v2-direct-dl":
+        elif keyword == 'dirreq-v2-direct-dl':
           self.dir_v2_direct_dl = recognized_counts
           self.dir_v2_direct_dl_unknown = unrecognized_counts
-        elif keyword == "dirreq-v3-direct-dl":
+        elif keyword == 'dirreq-v3-direct-dl':
           self.dir_v3_direct_dl = recognized_counts
           self.dir_v3_direct_dl_unknown = unrecognized_counts
-        elif keyword == "dirreq-v2-tunneled-dl":
+        elif keyword == 'dirreq-v2-tunneled-dl':
           self.dir_v2_tunneled_dl = recognized_counts
           self.dir_v2_tunneled_dl_unknown = unrecognized_counts
-        elif keyword == "dirreq-v3-tunneled-dl":
+        elif keyword == 'dirreq-v3-tunneled-dl':
           self.dir_v3_tunneled_dl = recognized_counts
           self.dir_v3_tunneled_dl_unknown = unrecognized_counts
-      elif keyword in ("dirreq-v2-share", "dirreq-v3-share"):
+      elif keyword in ('dirreq-v2-share', 'dirreq-v3-share'):
         # "<keyword>" num%
 
         try:
-          if not value.endswith("%"):
+          if not value.endswith('%'):
             raise ValueError()
 
           percentage = float(value[:-1]) / 100
@@ -608,22 +608,22 @@ class ExtraInfoDescriptor(Descriptor):
           # https://lists.torproject.org/pipermail/tor-dev/2012-June/003679.html
 
           if validate and percentage < 0:
-            raise ValueError("Negative percentage value: %s" % line)
+            raise ValueError('Negative percentage value: %s' % line)
 
-          if keyword == "dirreq-v2-share":
+          if keyword == 'dirreq-v2-share':
             self.dir_v2_share = percentage
-          elif keyword == "dirreq-v3-share":
+          elif keyword == 'dirreq-v3-share':
             self.dir_v3_share = percentage
         except ValueError as exc:
           if validate:
             raise ValueError("Value can't be parsed as a percentage: %s" % line)
-      elif keyword in ("cell-processed-cells", "cell-queued-cells", "cell-time-in-queue"):
+      elif keyword in ('cell-processed-cells', 'cell-queued-cells', 'cell-time-in-queue'):
         # "<keyword>" num,...,num
 
         entries = []
 
         if value:
-          for entry in value.split(","):
+          for entry in value.split(','):
             try:
               # Values should be positive but as discussed in ticket #5849
               # there was a bug around this. It was fixed in tor 0.2.2.1.
@@ -631,61 +631,61 @@ class ExtraInfoDescriptor(Descriptor):
               entries.append(float(entry))
             except ValueError:
               if validate:
-                raise ValueError("Non-numeric entry in %s listing: %s" % (keyword, line))
+                raise ValueError('Non-numeric entry in %s listing: %s' % (keyword, line))
 
-        if keyword == "cell-processed-cells":
+        if keyword == 'cell-processed-cells':
           self.cell_processed_cells = entries
-        elif keyword == "cell-queued-cells":
+        elif keyword == 'cell-queued-cells':
           self.cell_queued_cells = entries
-        elif keyword == "cell-time-in-queue":
+        elif keyword == 'cell-time-in-queue':
           self.cell_time_in_queue = entries
-      elif keyword in ("published", "geoip-start-time"):
+      elif keyword in ('published', 'geoip-start-time'):
         # "<keyword>" YYYY-MM-DD HH:MM:SS
 
         try:
-          timestamp = datetime.datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
+          timestamp = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
 
-          if keyword == "published":
+          if keyword == 'published':
             self.published = timestamp
-          elif keyword == "geoip-start-time":
+          elif keyword == 'geoip-start-time':
             self.geoip_start_time = timestamp
         except ValueError:
           if validate:
             raise ValueError("Timestamp on %s line wasn't parsable: %s" % (keyword, line))
-      elif keyword in ("cell-stats-end", "entry-stats-end", "exit-stats-end", "bridge-stats-end", "dirreq-stats-end"):
+      elif keyword in ('cell-stats-end', 'entry-stats-end', 'exit-stats-end', 'bridge-stats-end', 'dirreq-stats-end'):
         # "<keyword>" YYYY-MM-DD HH:MM:SS (NSEC s)
 
         try:
           timestamp, interval, _ = _parse_timestamp_and_interval(keyword, value)
 
-          if keyword == "cell-stats-end":
+          if keyword == 'cell-stats-end':
             self.cell_stats_end = timestamp
             self.cell_stats_interval = interval
-          elif keyword == "entry-stats-end":
+          elif keyword == 'entry-stats-end':
             self.entry_stats_end = timestamp
             self.entry_stats_interval = interval
-          elif keyword == "exit-stats-end":
+          elif keyword == 'exit-stats-end':
             self.exit_stats_end = timestamp
             self.exit_stats_interval = interval
-          elif keyword == "bridge-stats-end":
+          elif keyword == 'bridge-stats-end':
             self.bridge_stats_end = timestamp
             self.bridge_stats_interval = interval
-          elif keyword == "dirreq-stats-end":
+          elif keyword == 'dirreq-stats-end':
             self.dir_stats_end = timestamp
             self.dir_stats_interval = interval
         except ValueError as exc:
           if validate:
             raise exc
-      elif keyword == "conn-bi-direct":
+      elif keyword == 'conn-bi-direct':
         # "conn-bi-direct" YYYY-MM-DD HH:MM:SS (NSEC s) BELOW,READ,WRITE,BOTH
 
         try:
           timestamp, interval, remainder = _parse_timestamp_and_interval(keyword, value)
-          stats = remainder.split(",")
+          stats = remainder.split(',')
 
           if len(stats) != 4 or not \
             (stats[0].isdigit() and stats[1].isdigit() and stats[2].isdigit() and stats[3].isdigit()):
-            raise ValueError("conn-bi-direct line should end with four numeric values: %s" % line)
+            raise ValueError('conn-bi-direct line should end with four numeric values: %s' % line)
 
           self.conn_bi_direct_end = timestamp
           self.conn_bi_direct_interval = interval
@@ -696,7 +696,7 @@ class ExtraInfoDescriptor(Descriptor):
         except ValueError as exc:
           if validate:
             raise exc
-      elif keyword in ("read-history", "write-history", "dirreq-read-history", "dirreq-write-history"):
+      elif keyword in ('read-history', 'write-history', 'dirreq-read-history', 'dirreq-write-history'):
         # "<keyword>" YYYY-MM-DD HH:MM:SS (NSEC s) NUM,NUM,NUM,NUM,NUM...
         try:
           timestamp, interval, remainder = _parse_timestamp_and_interval(keyword, value)
@@ -706,42 +706,42 @@ class ExtraInfoDescriptor(Descriptor):
             try:
               history_values = [int(entry) for entry in remainder.split(",")]
             except ValueError:
-              raise ValueError("%s line has non-numeric values: %s" % (keyword, line))
+              raise ValueError('%s line has non-numeric values: %s' % (keyword, line))
 
-          if keyword == "read-history":
+          if keyword == 'read-history':
             self.read_history_end = timestamp
             self.read_history_interval = interval
             self.read_history_values = history_values
-          elif keyword == "write-history":
+          elif keyword == 'write-history':
             self.write_history_end = timestamp
             self.write_history_interval = interval
             self.write_history_values = history_values
-          elif keyword == "dirreq-read-history":
+          elif keyword == 'dirreq-read-history':
             self.dir_read_history_end = timestamp
             self.dir_read_history_interval = interval
             self.dir_read_history_values = history_values
-          elif keyword == "dirreq-write-history":
+          elif keyword == 'dirreq-write-history':
             self.dir_write_history_end = timestamp
             self.dir_write_history_interval = interval
             self.dir_write_history_values = history_values
         except ValueError as exc:
           if validate:
             raise exc
-      elif keyword in ("exit-kibibytes-written", "exit-kibibytes-read", "exit-streams-opened"):
+      elif keyword in ('exit-kibibytes-written', 'exit-kibibytes-read', 'exit-streams-opened'):
         # "<keyword>" port=N,port=N,...
 
         port_mappings = {}
-        error_msg = "Entries in %s line should only be PORT=N entries: %s" % (keyword, line)
+        error_msg = 'Entries in %s line should only be PORT=N entries: %s' % (keyword, line)
 
         if value:
-          for entry in value.split(","):
-            if not "=" in entry:
+          for entry in value.split(','):
+            if not '=' in entry:
               if validate:
                 raise ValueError(error_msg)
               else:
                 continue
 
-            port, stat = entry.split("=", 1)
+            port, stat = entry.split('=', 1)
 
             if (port == 'other' or stem.util.connection.is_valid_port(port)) and stat.isdigit():
               if port != 'other':
@@ -750,13 +750,13 @@ class ExtraInfoDescriptor(Descriptor):
             elif validate:
               raise ValueError(error_msg)
 
-        if keyword == "exit-kibibytes-written":
+        if keyword == 'exit-kibibytes-written':
           self.exit_kibibytes_written = port_mappings
-        elif keyword == "exit-kibibytes-read":
+        elif keyword == 'exit-kibibytes-read':
           self.exit_kibibytes_read = port_mappings
-        elif keyword == "exit-streams-opened":
+        elif keyword == 'exit-streams-opened':
           self.exit_streams_opened = port_mappings
-      elif keyword in ("dirreq-v2-ips", "dirreq-v3-ips", "dirreq-v2-reqs", "dirreq-v3-reqs", "geoip-client-origins", "entry-ips", "bridge-ips"):
+      elif keyword in ('dirreq-v2-ips', 'dirreq-v3-ips', 'dirreq-v2-reqs', 'dirreq-v3-reqs', 'geoip-client-origins', 'entry-ips', 'bridge-ips'):
         # "<keyword>" CC=N,CC=N,...
         #
         # The maxmind geoip (https://www.maxmind.com/app/iso3166) has numeric
@@ -766,38 +766,38 @@ class ExtraInfoDescriptor(Descriptor):
         #   ??,"Unknown"
 
         locale_usage = {}
-        error_msg = "Entries in %s line should only be CC=N entries: %s" % (keyword, line)
+        error_msg = 'Entries in %s line should only be CC=N entries: %s' % (keyword, line)
 
         if value:
-          for entry in value.split(","):
-            if not "=" in entry:
+          for entry in value.split(','):
+            if not '=' in entry:
               if validate:
                 raise ValueError(error_msg)
               else:
                 continue
 
-            locale, count = entry.split("=", 1)
+            locale, count = entry.split('=', 1)
 
-            if re.match("^[a-zA-Z0-9\?]{2}$", locale) and count.isdigit():
+            if re.match('^[a-zA-Z0-9\?]{2}$', locale) and count.isdigit():
               locale_usage[locale] = int(count)
             elif validate:
               raise ValueError(error_msg)
 
-        if keyword == "dirreq-v2-ips":
+        if keyword == 'dirreq-v2-ips':
           self.dir_v2_ips = locale_usage
-        elif keyword == "dirreq-v3-ips":
+        elif keyword == 'dirreq-v3-ips':
           self.dir_v3_ips = locale_usage
-        elif keyword == "dirreq-v2-reqs":
+        elif keyword == 'dirreq-v2-reqs':
           self.dir_v2_requests = locale_usage
-        elif keyword == "dirreq-v3-reqs":
+        elif keyword == 'dirreq-v3-reqs':
           self.dir_v3_requests = locale_usage
-        elif keyword == "geoip-client-origins":
+        elif keyword == 'geoip-client-origins':
           self.geoip_client_origins = locale_usage
-        elif keyword == "entry-ips":
+        elif keyword == 'entry-ips':
           self.entry_ips = locale_usage
-        elif keyword == "bridge-ips":
+        elif keyword == 'bridge-ips':
           self.bridge_ips = locale_usage
-      elif keyword == "bridge-ip-versions":
+      elif keyword == 'bridge-ip-versions':
         self.ip_versions = {}
 
         if value:
@@ -808,10 +808,10 @@ class ExtraInfoDescriptor(Descriptor):
             protocol, count = entry.split('=', 1)
 
             if not count.isdigit():
-              raise stem.ProtocolError("IP protocol count was non-numeric (%s): %s" % (count, line))
+              raise stem.ProtocolError('IP protocol count was non-numeric (%s): %s' % (count, line))
 
             self.ip_versions[protocol] = int(count)
-      elif keyword == "bridge-ip-transports":
+      elif keyword == 'bridge-ip-transports':
         self.ip_transports = {}
 
         if value:
@@ -822,7 +822,7 @@ class ExtraInfoDescriptor(Descriptor):
             protocol, count = entry.split('=', 1)
 
             if not count.isdigit():
-              raise stem.ProtocolError("Transport count was non-numeric (%s): %s" % (count, line))
+              raise stem.ProtocolError('Transport count was non-numeric (%s): %s' % (count, line))
 
             self.ip_transports[protocol] = int(count)
       else:
@@ -837,22 +837,22 @@ class ExtraInfoDescriptor(Descriptor):
       descriptor
     """
 
-    raise NotImplementedError("Unsupported Operation: this should be implemented by the ExtraInfoDescriptor subclass")
+    raise NotImplementedError('Unsupported Operation: this should be implemented by the ExtraInfoDescriptor subclass')
 
   def _required_fields(self):
     return REQUIRED_FIELDS
 
   def _first_keyword(self):
-    return "extra-info"
+    return 'extra-info'
 
   def _last_keyword(self):
-    return "router-signature"
+    return 'router-signature'
 
 
 class RelayExtraInfoDescriptor(ExtraInfoDescriptor):
   """
   Relay extra-info descriptor, constructed from data such as that provided by
-  "GETINFO extra-info/digest/\*", cached descriptors, and metrics
+  'GETINFO extra-info/digest/\*', cached descriptors, and metrics
   (`specification <https://gitweb.torproject.org/torspec.git/blob/HEAD:/dir-spec.txt>`_).
 
   :var str signature: **\*** signature for this extrainfo descriptor
@@ -868,7 +868,7 @@ class RelayExtraInfoDescriptor(ExtraInfoDescriptor):
   @lru_cache()
   def digest(self):
     # our digest is calculated from everything except our signature
-    raw_content, ending = str(self), "\nrouter-signature\n"
+    raw_content, ending = str(self), '\nrouter-signature\n'
     raw_content = raw_content[:raw_content.find(ending) + len(ending)]
     return hashlib.sha1(stem.util.str_tools._to_bytes(raw_content)).hexdigest().upper()
 
@@ -879,17 +879,17 @@ class RelayExtraInfoDescriptor(ExtraInfoDescriptor):
     for keyword, values in entries.items():
       value, block_contents = values[0]
 
-      line = "%s %s" % (keyword, value)  # original line
+      line = '%s %s' % (keyword, value)  # original line
 
       if block_contents:
-        line += "\n%s" % block_contents
+        line += '\n%s' % block_contents
 
-      if keyword == "router-signature":
+      if keyword == 'router-signature':
         if validate and not block_contents:
-          raise ValueError("Router signature line must be followed by a signature block: %s" % line)
+          raise ValueError('Router signature line must be followed by a signature block: %s' % line)
 
         self.signature = block_contents
-        del entries["router-signature"]
+        del entries['router-signature']
 
     ExtraInfoDescriptor._parse(self, entries, validate)
 
@@ -914,24 +914,24 @@ class BridgeExtraInfoDescriptor(ExtraInfoDescriptor):
     # handles fields only in server descriptors
     for keyword, values in entries.items():
       value, _ = values[0]
-      line = "%s %s" % (keyword, value)  # original line
+      line = '%s %s' % (keyword, value)  # original line
 
-      if keyword == "router-digest":
+      if keyword == 'router-digest':
         if validate and not stem.util.tor_tools.is_hex_digits(value, 40):
-          raise ValueError("Router digest line had an invalid sha1 digest: %s" % line)
+          raise ValueError('Router digest line had an invalid sha1 digest: %s' % line)
 
         self._digest = value
-        del entries["router-digest"]
+        del entries['router-digest']
 
     ExtraInfoDescriptor._parse(self, entries, validate)
 
   def _required_fields(self):
     excluded_fields = [
-      "router-signature",
+      'router-signature',
     ]
 
     included_fields = [
-      "router-digest",
+      'router-digest',
     ]
 
     return tuple(included_fields + [f for f in REQUIRED_FIELDS if not f in excluded_fields])
diff --git a/stem/descriptor/microdescriptor.py b/stem/descriptor/microdescriptor.py
index 37e49f1..f308da4 100644
--- a/stem/descriptor/microdescriptor.py
+++ b/stem/descriptor/microdescriptor.py
@@ -33,17 +33,17 @@ the exit relays.
     controller.authenticate()
 
     exit_digests = set()
-    data_dir = controller.get_conf("DataDirectory")
+    data_dir = controller.get_conf('DataDirectory')
 
     for desc in controller.get_microdescriptors():
       if desc.exit_policy.is_exiting_allowed():
         exit_digests.add(desc.digest)
 
-    print "Exit Relays:"
+    print 'Exit Relays:'
 
     for desc in parse_file(os.path.join(data_dir, 'cached-microdesc-consensus')):
       if desc.digest in exit_digests:
-        print "  %s (%s)" % (desc.nickname, desc.fingerprint)
+        print '  %s (%s)' % (desc.nickname, desc.fingerprint)
 
 Doing the same is trivial with server descriptors...
 
@@ -51,11 +51,11 @@ Doing the same is trivial with server descriptors...
 
   from stem.descriptor import parse_file
 
-  print "Exit Relays:"
+  print 'Exit Relays:'
 
-  for desc in parse_file("/home/atagar/.tor/cached-descriptors"):
+  for desc in parse_file('/home/atagar/.tor/cached-descriptors'):
     if desc.exit_policy.is_exiting_allowed():
-      print "  %s (%s)" % (desc.nickname, desc.fingerprint)
+      print '  %s (%s)' % (desc.nickname, desc.fingerprint)
 
 **Module Overview:**
 
@@ -82,15 +82,15 @@ except ImportError:
   from stem.util.lru_cache import lru_cache
 
 REQUIRED_FIELDS = (
-  "onion-key",
+  'onion-key',
 )
 
 SINGLE_FIELDS = (
-  "onion-key",
-  "ntor-onion-key",
-  "family",
-  "p",
-  "p6",
+  'onion-key',
+  'ntor-onion-key',
+  'family',
+  'p',
+  'p6',
 )
 
 
@@ -111,7 +111,7 @@ def _parse_file(descriptor_file, validate = True, **kwargs):
   """
 
   while True:
-    annotations = _read_until_keywords("onion-key", descriptor_file)
+    annotations = _read_until_keywords('onion-key', descriptor_file)
 
     # read until we reach an annotation or onion-key line
     descriptor_lines = []
@@ -131,7 +131,7 @@ def _parse_file(descriptor_file, validate = True, **kwargs):
 
       if not line:
         break  # EOF
-      elif line.startswith(b"@") or line.startswith(b"onion-key"):
+      elif line.startswith(b'@') or line.startswith(b'onion-key'):
         descriptor_file.seek(last_position)
         break
       else:
@@ -141,7 +141,7 @@ def _parse_file(descriptor_file, validate = True, **kwargs):
       # strip newlines from annotations
       annotations = map(bytes.strip, annotations)
 
-      descriptor_text = bytes.join(b"", descriptor_lines)
+      descriptor_text = bytes.join(b'', descriptor_lines)
 
       yield Microdescriptor(descriptor_text, validate, annotations, **kwargs)
     else:
@@ -180,7 +180,7 @@ class Microdescriptor(Descriptor):
     self.ntor_onion_key = None
     self.or_addresses = []
     self.family = []
-    self.exit_policy = stem.exit_policy.MicroExitPolicy("reject 1-65535")
+    self.exit_policy = stem.exit_policy.MicroExitPolicy('reject 1-65535')
     self.exit_policy_v6 = None
     self.identifier_type = None
     self.identifier = None
@@ -214,8 +214,8 @@ class Microdescriptor(Descriptor):
     annotation_dict = {}
 
     for line in self._annotation_lines:
-      if b" " in line:
-        key, value = line.split(b" ", 1)
+      if b' ' in line:
+        key, value = line.split(b' ', 1)
         annotation_dict[key] = value
       else:
         annotation_dict[line] = None
@@ -249,28 +249,28 @@ class Microdescriptor(Descriptor):
       # most just work with the first (and only) value
       value, block_contents = values[0]
 
-      line = "%s %s" % (keyword, value)  # original line
+      line = '%s %s' % (keyword, value)  # original line
 
       if block_contents:
-        line += "\n%s" % block_contents
+        line += '\n%s' % block_contents
 
-      if keyword == "onion-key":
+      if keyword == 'onion-key':
         if validate and not block_contents:
-          raise ValueError("Onion key line must be followed by a public key: %s" % line)
+          raise ValueError('Onion key line must be followed by a public key: %s' % line)
 
         self.onion_key = block_contents
-      elif keyword == "ntor-onion-key":
+      elif keyword == 'ntor-onion-key':
         self.ntor_onion_key = value
-      elif keyword == "a":
+      elif keyword == 'a':
         for entry, _ in values:
           stem.descriptor.router_status_entry._parse_a_line(self, entry, validate)
-      elif keyword == "family":
-        self.family = value.split(" ")
-      elif keyword == "p":
+      elif keyword == 'family':
+        self.family = value.split(' ')
+      elif keyword == 'p':
         stem.descriptor.router_status_entry._parse_p_line(self, value, validate)
-      elif keyword == "p6":
+      elif keyword == 'p6':
         self.exit_policy_v6 = stem.exit_policy.MicroExitPolicy(value)
-      elif keyword == "id":
+      elif keyword == 'id':
         value_comp = value.split()
 
         if len(value_comp) >= 2:
diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py
index 0576375..588d4ac 100644
--- a/stem/descriptor/networkstatus.py
+++ b/stem/descriptor/networkstatus.py
@@ -66,16 +66,16 @@ from stem.descriptor import (
 # (keyword, is_mandatory)
 
 NETWORK_STATUS_V2_FIELDS = (
-  ("network-status-version", True),
-  ("dir-source", True),
-  ("fingerprint", True),
-  ("contact", True),
-  ("dir-signing-key", True),
-  ("client-versions", False),
-  ("server-versions", False),
-  ("published", True),
-  ("dir-options", False),
-  ("directory-signature", True),
+  ('network-status-version', True),
+  ('dir-source', True),
+  ('fingerprint', True),
+  ('contact', True),
+  ('dir-signing-key', True),
+  ('client-versions', False),
+  ('server-versions', False),
+  ('published', True),
+  ('dir-options', False),
+  ('directory-signature', True),
 )
 
 # Network status document are either a 'vote' or 'consensus', with different
@@ -85,50 +85,50 @@ NETWORK_STATUS_V2_FIELDS = (
 # (field, in_votes, in_consensus, is_mandatory)
 
 HEADER_STATUS_DOCUMENT_FIELDS = (
-  ("network-status-version", True, True, True),
-  ("vote-status", True, True, True),
-  ("consensus-methods", True, False, False),
-  ("consensus-method", False, True, False),
-  ("published", True, False, True),
-  ("valid-after", True, True, True),
-  ("fresh-until", True, True, True),
-  ("valid-until", True, True, True),
-  ("voting-delay", True, True, True),
-  ("client-versions", True, True, False),
-  ("server-versions", True, True, False),
-  ("known-flags", True, True, True),
-  ("flag-thresholds", True, False, False),
-  ("params", True, True, False),
+  ('network-status-version', True, True, True),
+  ('vote-status', True, True, True),
+  ('consensus-methods', True, False, False),
+  ('consensus-method', False, True, False),
+  ('published', True, False, True),
+  ('valid-after', True, True, True),
+  ('fresh-until', True, True, True),
+  ('valid-until', True, True, True),
+  ('voting-delay', True, True, True),
+  ('client-versions', True, True, False),
+  ('server-versions', True, True, False),
+  ('known-flags', True, True, True),
+  ('flag-thresholds', True, False, False),
+  ('params', True, True, False),
 )
 
 FOOTER_STATUS_DOCUMENT_FIELDS = (
-  ("directory-footer", True, True, False),
-  ("bandwidth-weights", False, True, False),
-  ("directory-signature", True, True, True),
+  ('directory-footer', True, True, False),
+  ('bandwidth-weights', False, True, False),
+  ('directory-signature', True, True, True),
 )
 
 HEADER_FIELDS = [attr[0] for attr in HEADER_STATUS_DOCUMENT_FIELDS]
 FOOTER_FIELDS = [attr[0] for attr in FOOTER_STATUS_DOCUMENT_FIELDS]
 
-AUTH_START = "dir-source"
-ROUTERS_START = "r"
-FOOTER_START = "directory-footer"
-V2_FOOTER_START = "directory-signature"
+AUTH_START = 'dir-source'
+ROUTERS_START = 'r'
+FOOTER_START = 'directory-footer'
+V2_FOOTER_START = 'directory-signature'
 
 DEFAULT_PARAMS = {
-  "bwweightscale": 10000,
-  "cbtdisabled": 0,
-  "cbtnummodes": 3,
-  "cbtrecentcount": 20,
-  "cbtmaxtimeouts": 18,
-  "cbtmincircs": 100,
-  "cbtquantile": 80,
-  "cbtclosequantile": 95,
-  "cbttestfreq": 60,
-  "cbtmintimeout": 2000,
-  "cbtinitialtimeout": 60000,
-  "Support022HiddenServices": 1,
-  "usecreatefast": 1,
+  'bwweightscale': 10000,
+  'cbtdisabled': 0,
+  'cbtnummodes': 3,
+  'cbtrecentcount': 20,
+  'cbtmaxtimeouts': 18,
+  'cbtmincircs': 100,
+  'cbtquantile': 80,
+  'cbtclosequantile': 95,
+  'cbttestfreq': 60,
+  'cbtmintimeout': 2000,
+  'cbtinitialtimeout': 60000,
+  'Support022HiddenServices': 1,
+  'usecreatefast': 1,
 }
 
 # KeyCertificate fields, tuple is of the form...
@@ -203,7 +203,7 @@ def _parse_file(document_file, document_type = None, validate = True, is_microde
   routers_end = document_file.tell()
 
   footer = document_file.readlines()
-  document_content = bytes.join(b"", header + footer)
+  document_content = bytes.join(b'', header + footer)
 
   if document_handler == DocumentHandler.BARE_DOCUMENT:
     yield document_type(document_content, validate, **kwargs)
@@ -222,7 +222,7 @@ def _parse_file(document_file, document_type = None, validate = True, is_microde
     for desc in desc_iterator:
       yield desc
   else:
-    raise ValueError("Unrecognized document_handler: %s" % document_handler)
+    raise ValueError('Unrecognized document_handler: %s' % document_handler)
 
 
 def _parse_file_key_certs(certificate_file, validate = True):
@@ -243,14 +243,14 @@ def _parse_file_key_certs(certificate_file, validate = True):
   """
 
   while True:
-    keycert_content = _read_until_keywords("dir-key-certification", certificate_file)
+    keycert_content = _read_until_keywords('dir-key-certification', certificate_file)
 
     # we've reached the 'router-signature', now include the pgp style block
     block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0]
     keycert_content += _read_until_keywords(block_end_prefix, certificate_file, True)
 
     if keycert_content:
-      yield stem.descriptor.networkstatus.KeyCertificate(bytes.join(b"", keycert_content), validate = validate)
+      yield stem.descriptor.networkstatus.KeyCertificate(bytes.join(b'', keycert_content), validate = validate)
     else:
       break  # done parsing file
 
@@ -322,7 +322,7 @@ class NetworkStatusDocumentV2(NetworkStatusDocument):
     # deprecated descriptor type - patches welcome if you want those checks.
 
     document_file = io.BytesIO(raw_content)
-    document_content = bytes.join(b"", _read_until_keywords((ROUTERS_START, V2_FOOTER_START), document_file))
+    document_content = bytes.join(b'', _read_until_keywords((ROUTERS_START, V2_FOOTER_START), document_file))
 
     router_iter = stem.descriptor.router_status_entry._parse_file(
       document_file,
@@ -335,7 +335,7 @@ class NetworkStatusDocumentV2(NetworkStatusDocument):
 
     self.routers = dict((desc.fingerprint, desc) for desc in router_iter)
 
-    document_content += b"\n" + document_file.read()
+    document_content += b'\n' + document_file.read()
     document_content = stem.util.str_tools._to_unicode(document_content)
 
     entries = _get_descriptor_components(document_content, validate)
@@ -349,23 +349,23 @@ class NetworkStatusDocumentV2(NetworkStatusDocument):
     for keyword, values in entries.items():
       value, block_contents = values[0]
 
-      line = "%s %s" % (keyword, value)  # original line
+      line = '%s %s' % (keyword, value)  # original line
 
       if block_contents:
-        line += "\n%s" % block_contents
+        line += '\n%s' % block_contents
 
-      if keyword == "network-status-version":
+      if keyword == 'network-status-version':
         if not value.isdigit():
           if not validate:
             continue
 
-          raise ValueError("Network status document has a non-numeric version: %s" % line)
+          raise ValueError('Network status document has a non-numeric version: %s' % line)
 
         self.version = int(value)
 
         if validate and self.version != 2:
           raise ValueError("Expected a version 2 network status document, got version '%s' instead" % self.version)
-      elif keyword == "dir-source":
+      elif keyword == 'dir-source':
         dir_source_comp = value.split()
 
         if len(dir_source_comp) < 3:
@@ -388,42 +388,42 @@ class NetworkStatusDocumentV2(NetworkStatusDocument):
         self.hostname = dir_source_comp[0]
         self.address = dir_source_comp[1]
         self.dir_port = None if dir_source_comp[2] == '0' else int(dir_source_comp[2])
-      elif keyword == "fingerprint":
+      elif keyword == 'fingerprint':
         if validate and not stem.util.tor_tools.is_valid_fingerprint(value):
           raise ValueError("Authority's fingerprint in a v2 network status document is malformed: %s" % line)
 
         self.fingerprint = value
-      elif keyword == "contact":
+      elif keyword == 'contact':
         self.contact = value
-      elif keyword == "dir-signing-key":
+      elif keyword == 'dir-signing-key':
         self.signing_key = block_contents
-      elif keyword in ("client-versions", "server-versions"):
+      elif keyword in ('client-versions', 'server-versions'):
         # v2 documents existed while there were tor versions using the 'old'
         # style, hence we aren't attempting to parse them
 
-        for version_str in value.split(","):
+        for version_str in value.split(','):
           if keyword == 'client-versions':
             self.client_versions.append(version_str)
           elif keyword == 'server-versions':
             self.server_versions.append(version_str)
-      elif keyword == "published":
+      elif keyword == 'published':
         try:
-          self.published = datetime.datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
+          self.published = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
         except ValueError:
           if validate:
             raise ValueError("Version 2 network status document's 'published' time wasn't parsable: %s" % value)
-      elif keyword == "dir-options":
+      elif keyword == 'dir-options':
         self.options = value.split()
-      elif keyword == "directory-signature":
+      elif keyword == 'directory-signature':
         self.signing_authority = value
         self.signature = block_contents
       else:
         self._unrecognized_lines.append(line)
 
-    # 'client-versions' and 'server-versions' are only required if "Versions"
+    # 'client-versions' and 'server-versions' are only required if 'Versions'
     # is among the options
 
-    if validate and "Versions" in self.options:
+    if validate and 'Versions' in self.options:
       if not ('client-versions' in entries and 'server-versions' in entries):
         raise ValueError("Version 2 network status documents must have a 'client-versions' and 'server-versions' when 'Versions' is listed among its dir-options:\n%s" % str(self))
 
@@ -506,7 +506,7 @@ class NetworkStatusDocumentV3(NetworkStatusDocument):
 
     # merge header attributes into us
     for attr, value in vars(self._header).items():
-      if attr != "_unrecognized_lines":
+      if attr != '_unrecognized_lines':
         setattr(self, attr, value)
       else:
         self._unrecognized_lines += value
@@ -521,7 +521,7 @@ class NetworkStatusDocumentV3(NetworkStatusDocument):
     ))
 
     if validate and self._header.is_vote and len(self.directory_authorities) != 1:
-      raise ValueError("Votes should only have an authority entry for the one that issued it, got %i: %s" % (len(self.directory_authorities), self.directory_authorities))
+      raise ValueError('Votes should only have an authority entry for the one that issued it, got %i: %s' % (len(self.directory_authorities), self.directory_authorities))
 
     if not self._header.is_microdescriptor:
       router_type = stem.descriptor.router_status_entry.RouterStatusEntryV3
@@ -543,7 +543,7 @@ class NetworkStatusDocumentV3(NetworkStatusDocument):
 
     # merge header attributes into us
     for attr, value in vars(self._footer).items():
-      if attr != "_unrecognized_lines":
+      if attr != '_unrecognized_lines':
         setattr(self, attr, value)
       else:
         self._unrecognized_lines += value
@@ -603,7 +603,7 @@ class _DocumentHeader(object):
 
     self._unrecognized_lines = []
 
-    content = bytes.join(b"", _read_until_keywords((AUTH_START, ROUTERS_START, FOOTER_START), document_file))
+    content = bytes.join(b'', _read_until_keywords((AUTH_START, ROUTERS_START, FOOTER_START), document_file))
     content = stem.util.str_tools._to_unicode(content)
     entries = _get_descriptor_components(content, validate)
     self._parse(entries, validate)
@@ -626,7 +626,7 @@ class _DocumentHeader(object):
   def _parse(self, entries, validate):
     for keyword, values in entries.items():
       value, _ = values[0]
-      line = "%s %s" % (keyword, value)
+      line = '%s %s' % (keyword, value)
 
       # all known header fields can only appear once except
       if validate and len(values) > 1 and keyword in HEADER_FIELDS:
@@ -644,7 +644,7 @@ class _DocumentHeader(object):
           if not validate:
             continue
 
-          raise ValueError("Network status document has a non-numeric version: %s" % line)
+          raise ValueError('Network status document has a non-numeric version: %s' % line)
 
         self.version = int(version)
         self.version_flavor = flavor
@@ -671,7 +671,7 @@ class _DocumentHeader(object):
         # "consensus-methods" IntegerList
 
         consensus_methods = []
-        for entry in value.split(" "):
+        for entry in value.split(' '):
           if entry.isdigit():
             consensus_methods.append(int(entry))
           elif validate:
@@ -680,7 +680,7 @@ class _DocumentHeader(object):
         self.consensus_methods = consensus_methods
 
         if validate and not (1 in self.consensus_methods):
-          raise ValueError("Network status votes must include consensus-method version 1")
+          raise ValueError('Network status votes must include consensus-method version 1')
       elif keyword == 'consensus-method':
         # "consensus-method" Integer
 
@@ -690,7 +690,7 @@ class _DocumentHeader(object):
           raise ValueError("A network status document's consensus-method must be an integer, but was '%s'" % value)
       elif keyword in ('published', 'valid-after', 'fresh-until', 'valid-until'):
         try:
-          date_value = datetime.datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
+          date_value = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
 
           if keyword == 'published':
             self.published = date_value
@@ -703,7 +703,7 @@ class _DocumentHeader(object):
         except ValueError:
           if validate:
             raise ValueError("Network status document's '%s' time wasn't parsable: %s" % (keyword, value))
-      elif keyword == "voting-delay":
+      elif keyword == 'voting-delay':
         # "voting-delay" VoteSeconds DistSeconds
 
         value_comp = value.split(' ')
@@ -713,8 +713,8 @@ class _DocumentHeader(object):
           self.dist_delay = int(value_comp[1])
         elif validate:
           raise ValueError("A network status document's 'voting-delay' line must be a pair of integer values, but was '%s'" % value)
-      elif keyword in ("client-versions", "server-versions"):
-        for entry in value.split(","):
+      elif keyword in ('client-versions', 'server-versions'):
+        for entry in value.split(','):
           try:
             version_value = stem.version._get_version(entry)
 
@@ -725,33 +725,33 @@ class _DocumentHeader(object):
           except ValueError:
             if validate:
               raise ValueError("Network status document's '%s' line had '%s', which isn't a parsable tor version: %s" % (keyword, entry, line))
-      elif keyword == "known-flags":
+      elif keyword == 'known-flags':
         # "known-flags" FlagList
 
         # simply fetches the entries, excluding empty strings
-        self.known_flags = [entry for entry in value.split(" ") if entry]
-      elif keyword == "flag-thresholds":
+        self.known_flags = [entry for entry in value.split(' ') if entry]
+      elif keyword == 'flag-thresholds':
         # "flag-thresholds" SP THRESHOLDS
 
         value = value.strip()
 
         if value:
-          for entry in value.split(" "):
+          for entry in value.split(' '):
             if not '=' in entry:
               if not validate:
                 continue
 
               raise ValueError("Network status document's '%s' line is expected to be space separated key=value mappings, got: %s" % (keyword, line))
 
-            entry_key, entry_value = entry.split("=", 1)
+            entry_key, entry_value = entry.split('=', 1)
 
             try:
-              if entry_value.endswith("%"):
+              if entry_value.endswith('%'):
                 # opting for string manipulation rather than just
                 # 'float(entry_value) / 100' because floating point arithmetic
                 # will lose precision
 
-                self.flag_thresholds[entry_key] = float("0." + entry_value[:-1].replace('.', '', 1))
+                self.flag_thresholds[entry_key] = float('0.' + entry_value[:-1].replace('.', '', 1))
               elif '.' in entry_value:
                 self.flag_thresholds[entry_key] = float(entry_value)
               else:
@@ -759,7 +759,7 @@ class _DocumentHeader(object):
             except ValueError:
               if validate:
                 raise ValueError("Network status document's '%s' line is expected to have float values, got: %s" % (keyword, line))
-      elif keyword == "params":
+      elif keyword == 'params':
         # "params" [Parameters]
         # Parameter ::= Keyword '=' Int32
         # Int32 ::= A decimal integer between -2147483648 and 2147483647.
@@ -772,7 +772,7 @@ class _DocumentHeader(object):
 
         # skip if this is a blank line
 
-        if value == "":
+        if value == '':
           continue
 
         self.params.update(_parse_int_mappings(keyword, value, validate))
@@ -791,41 +791,41 @@ class _DocumentHeader(object):
       # all parameters are constrained to int32 range
       minimum, maximum = -2147483648, 2147483647
 
-      if key == "circwindow":
+      if key == 'circwindow':
         minimum, maximum = 100, 1000
-      elif key == "CircuitPriorityHalflifeMsec":
+      elif key == 'CircuitPriorityHalflifeMsec':
         minimum = -1
-      elif key in ("perconnbwrate", "perconnbwburst"):
+      elif key in ('perconnbwrate', 'perconnbwburst'):
         minimum = 1
-      elif key == "refuseunknownexits":
+      elif key == 'refuseunknownexits':
         minimum, maximum = 0, 1
-      elif key == "bwweightscale":
+      elif key == 'bwweightscale':
         minimum = 1
-      elif key == "cbtdisabled":
+      elif key == 'cbtdisabled':
         minimum, maximum = 0, 1
-      elif key == "cbtnummodes":
+      elif key == 'cbtnummodes':
         minimum, maximum = 1, 20
-      elif key == "cbtrecentcount":
+      elif key == 'cbtrecentcount':
         minimum, maximum = 3, 1000
-      elif key == "cbtmaxtimeouts":
+      elif key == 'cbtmaxtimeouts':
         minimum, maximum = 3, 10000
-      elif key == "cbtmincircs":
+      elif key == 'cbtmincircs':
         minimum, maximum = 1, 10000
-      elif key == "cbtquantile":
+      elif key == 'cbtquantile':
         minimum, maximum = 10, 99
-      elif key == "cbtclosequantile":
-        minimum, maximum = self.params.get("cbtquantile", minimum), 99
-      elif key == "cbttestfreq":
+      elif key == 'cbtclosequantile':
+        minimum, maximum = self.params.get('cbtquantile', minimum), 99
+      elif key == 'cbttestfreq':
         minimum = 1
-      elif key == "cbtmintimeout":
+      elif key == 'cbtmintimeout':
         minimum = 500
-      elif key == "cbtinitialtimeout":
-        minimum = self.params.get("cbtmintimeout", minimum)
-      elif key == "UseOptimisticData":
+      elif key == 'cbtinitialtimeout':
+        minimum = self.params.get('cbtmintimeout', minimum)
+      elif key == 'UseOptimisticData':
         minimum, maximum = 0, 1
-      elif key == "Support022HiddenServices":
+      elif key == 'Support022HiddenServices':
         minimum, maximum = 0, 1
-      elif key == "usecreatefast":
+      elif key == 'usecreatefast':
         minimum, maximum = 0, 1
 
       if value < minimum or value > maximum:
@@ -864,7 +864,7 @@ class _DocumentFooter(object):
   def _parse(self, entries, validate, header):
     for keyword, values in entries.items():
       value, block_contents = values[0]
-      line = "%s %s" % (keyword, value)
+      line = '%s %s' % (keyword, value)
 
       # all known footer fields can only appear once except...
       # * 'directory-signature' in a consensus
@@ -873,26 +873,26 @@ class _DocumentFooter(object):
         if not (keyword == 'directory-signature' and header.is_consensus):
           raise ValueError("Network status documents can only have a single '%s' line, got %i" % (keyword, len(values)))
 
-      if keyword == "directory-footer":
+      if keyword == 'directory-footer':
         # nothing to parse, simply checking that we don't have a value
 
         if validate and value:
           raise ValueError("A network status document's 'directory-footer' line shouldn't have any content, got '%s'" % line)
-      elif keyword == "bandwidth-weights":
+      elif keyword == 'bandwidth-weights':
         self.bandwidth_weights = _parse_int_mappings(keyword, value, validate)
-      elif keyword == "directory-signature":
+      elif keyword == 'directory-signature':
         for sig_value, block_contents in values:
-          if not sig_value.count(" ") in (1, 2) or not block_contents:
+          if not sig_value.count(' ') in (1, 2) or not block_contents:
             if not validate:
               continue
 
             raise ValueError("Authority signatures in a network status document are expected to be of the form 'directory-signature [METHOD] FINGERPRINT KEY_DIGEST\\nSIGNATURE', got:\n%s\n%s" % (sig_value, block_contents))
 
-          if sig_value.count(" ") == 1:
+          if sig_value.count(' ') == 1:
             method = 'sha1'  # default if none was provided
-            fingerprint, key_digest = sig_value.split(" ", 1)
+            fingerprint, key_digest = sig_value.split(' ', 1)
           else:
-            method, fingerprint, key_digest = sig_value.split(" ", 2)
+            method, fingerprint, key_digest = sig_value.split(' ', 2)
 
           self.signatures.append(DocumentSignature(method, fingerprint, key_digest, block_contents, validate))
 
@@ -924,7 +924,7 @@ def _check_for_missing_and_disallowed_fields(header, entries, fields):
         disallowed_fields.append(field)
 
   if missing_fields:
-    raise ValueError("Network status document is missing mandatory field: %s" % ', '.join(missing_fields))
+    raise ValueError('Network status document is missing mandatory field: %s' % ', '.join(missing_fields))
 
   if disallowed_fields:
     raise ValueError("Network status document has fields that shouldn't appear in this document type or version: %s" % ', '.join(disallowed_fields))
@@ -966,12 +966,12 @@ def _parse_int_mappings(keyword, value, validate):
   # - keys are sorted in lexical order
 
   results, seen_keys = {}, []
-  for entry in value.split(" "):
+  for entry in value.split(' '):
     try:
       if not '=' in entry:
         raise ValueError("must only have 'key=value' entries")
 
-      entry_key, entry_value = entry.split("=", 1)
+      entry_key, entry_value = entry.split('=', 1)
 
       try:
         # the int() function accepts things like '+123', but we don't want to
@@ -986,7 +986,7 @@ def _parse_int_mappings(keyword, value, validate):
         # parameters should be in ascending order by their key
         for prior_key in seen_keys:
           if prior_key > entry_key:
-            raise ValueError("parameters must be sorted by their key")
+            raise ValueError('parameters must be sorted by their key')
 
       results[entry_key] = entry_value
       seen_keys.append(entry_key)
@@ -1093,29 +1093,29 @@ class DirectoryAuthority(Descriptor):
     # check that we have mandatory fields
 
     if validate:
-      is_legacy, dir_source_entry = False, entries.get("dir-source")
+      is_legacy, dir_source_entry = False, entries.get('dir-source')
 
       if dir_source_entry:
-        is_legacy = dir_source_entry[0][0].split()[0].endswith("-legacy")
+        is_legacy = dir_source_entry[0][0].split()[0].endswith('-legacy')
 
-      required_fields, excluded_fields = ["dir-source"], []
+      required_fields, excluded_fields = ['dir-source'], []
 
       if not is_legacy:
-        required_fields += ["contact"]
+        required_fields += ['contact']
 
       if is_vote:
         if not key_cert_content:
-          raise ValueError("Authority votes must have a key certificate:\n%s" % content)
+          raise ValueError('Authority votes must have a key certificate:\n%s' % content)
 
-        excluded_fields += ["vote-digest"]
+        excluded_fields += ['vote-digest']
       elif not is_vote:
         if key_cert_content:
           raise ValueError("Authority consensus entries shouldn't have a key certificate:\n%s" % content)
 
         if not is_legacy:
-          required_fields += ["vote-digest"]
+          required_fields += ['vote-digest']
 
-        excluded_fields += ["legacy-dir-key"]
+        excluded_fields += ['legacy-dir-key']
 
       for keyword in required_fields:
         if not keyword in entries:
@@ -1123,12 +1123,12 @@ class DirectoryAuthority(Descriptor):
 
       for keyword in entries:
         if keyword in excluded_fields:
-          type_label = "votes" if is_vote else "consensus entries"
+          type_label = 'votes' if is_vote else 'consensus entries'
           raise ValueError("Authority %s shouldn't have a '%s' line:\n%s" % (type_label, keyword, content))
 
     for keyword, values in entries.items():
       value, _ = values[0]
-      line = "%s %s" % (keyword, value)
+      line = '%s %s' % (keyword, value)
 
       # all known attributes can only appear at most once
       if validate and len(values) > 1 and keyword in ('dir-source', 'contact', 'legacy-dir-key', 'vote-digest'):
@@ -1137,7 +1137,7 @@ class DirectoryAuthority(Descriptor):
       if keyword == 'dir-source':
         # "dir-source" nickname identity address IP dirport orport
 
-        dir_source_comp = value.split(" ")
+        dir_source_comp = value.split(' ')
 
         if len(dir_source_comp) < 6:
           if not validate:
@@ -1168,7 +1168,7 @@ class DirectoryAuthority(Descriptor):
         self.address = dir_source_comp[3]
         self.dir_port = None if dir_source_comp[4] == '0' else int(dir_source_comp[4])
         self.or_port = int(dir_source_comp[5])
-        self.is_legacy = self.nickname.endswith("-legacy")
+        self.is_legacy = self.nickname.endswith('-legacy')
       elif keyword == 'contact':
         # "contact" string
 
@@ -1177,7 +1177,7 @@ class DirectoryAuthority(Descriptor):
         # "legacy-dir-key" FINGERPRINT
 
         if validate and not stem.util.tor_tools.is_valid_fingerprint(value):
-          raise ValueError("Authority has a malformed legacy directory key: %s" % line)
+          raise ValueError('Authority has a malformed legacy directory key: %s' % line)
 
         self.legacy_dir_key = value
       elif keyword == 'vote-digest':
@@ -1185,7 +1185,7 @@ class DirectoryAuthority(Descriptor):
 
         # technically not a fingerprint, but has the same characteristics
         if validate and not stem.util.tor_tools.is_valid_fingerprint(value):
-          raise ValueError("Authority has a malformed vote digest: %s" % line)
+          raise ValueError('Authority has a malformed vote digest: %s' % line)
 
         self.vote_digest = value
       else:
@@ -1288,7 +1288,7 @@ class KeyCertificate(Descriptor):
 
     for keyword, values in entries.items():
       value, block_contents = values[0]
-      line = "%s %s" % (keyword, value)
+      line = '%s %s' % (keyword, value)
 
       if keyword == 'dir-key-certificate-version':
         # "dir-key-certificate-version" version
@@ -1297,7 +1297,7 @@ class KeyCertificate(Descriptor):
           if not validate:
             continue
 
-          raise ValueError("Key certificate has a non-integer version: %s" % line)
+          raise ValueError('Key certificate has a non-integer version: %s' % line)
 
         self.version = int(value)
 
@@ -1336,7 +1336,7 @@ class KeyCertificate(Descriptor):
         # "dir-key-expires" YYYY-MM-DD HH:MM:SS
 
         try:
-          date_value = datetime.datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
+          date_value = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
 
           if keyword == 'dir-key-published':
             self.published = date_value
@@ -1409,10 +1409,10 @@ class DocumentSignature(object):
 
     if validate:
       if not stem.util.tor_tools.is_valid_fingerprint(identity):
-        raise ValueError("Malformed fingerprint (%s) in the document signature" % identity)
+        raise ValueError('Malformed fingerprint (%s) in the document signature' % identity)
 
       if not stem.util.tor_tools.is_valid_fingerprint(key_digest):
-        raise ValueError("Malformed key digest (%s) in the document signature" % key_digest)
+        raise ValueError('Malformed key digest (%s) in the document signature' % key_digest)
 
     self.method = method
     self.identity = identity
@@ -1423,7 +1423,7 @@ class DocumentSignature(object):
     if not isinstance(other, DocumentSignature):
       return False
 
-    for attr in ("method", "identity", "key_digest", "signature"):
+    for attr in ('method', 'identity', 'key_digest', 'signature'):
       if getattr(self, attr) != getattr(other, attr):
         return method(getattr(self, attr), getattr(other, attr))
 
@@ -1457,11 +1457,11 @@ class BridgeNetworkStatusDocument(NetworkStatusDocument):
     document_file = io.BytesIO(raw_content)
     published_line = stem.util.str_tools._to_unicode(document_file.readline())
 
-    if published_line.startswith("published "):
-      published_line = published_line.split(" ", 1)[1].strip()
+    if published_line.startswith('published '):
+      published_line = published_line.split(' ', 1)[1].strip()
 
       try:
-        self.published = datetime.datetime.strptime(published_line, "%Y-%m-%d %H:%M:%S")
+        self.published = datetime.datetime.strptime(published_line, '%Y-%m-%d %H:%M:%S')
       except ValueError:
         if validate:
           raise ValueError("Bridge network status document's 'published' time wasn't parsable: %s" % published_line)
diff --git a/stem/descriptor/reader.py b/stem/descriptor/reader.py
index dc4db08..3fb4166 100644
--- a/stem/descriptor/reader.py
+++ b/stem/descriptor/reader.py
@@ -10,8 +10,8 @@ destinations. For example...
 ::
 
   my_descriptors = [
-    "/tmp/server-descriptors-2012-03.tar.bz2",
-    "/tmp/archived_descriptors/",
+    '/tmp/server-descriptors-2012-03.tar.bz2',
+    '/tmp/archived_descriptors/',
   ]
 
   # prints the contents of all the descriptor files
@@ -33,10 +33,10 @@ and picks up where it left off if run again...
 
 ::
 
-  reader = DescriptorReader(["/tmp/descriptor_data"])
+  reader = DescriptorReader(['/tmp/descriptor_data'])
 
   try:
-    processed_files = load_processed_files("/tmp/used_descriptors")
+    processed_files = load_processed_files('/tmp/used_descriptors')
     reader.set_processed_files(processed_files)
   except: pass # could not load, maybe this is the first run
 
@@ -50,7 +50,7 @@ and picks up where it left off if run again...
 
     time.sleep(1)
 
-  save_processed_files("/tmp/used_descriptors", reader.get_processed_files())
+  save_processed_files('/tmp/used_descriptors', reader.get_processed_files())
 
 **Module Overview:**
 
@@ -87,7 +87,7 @@ import stem.descriptor
 import stem.prereq
 
 # flag to indicate when the reader thread is out of descriptor files to read
-FINISHED = "DONE"
+FINISHED = 'DONE'
 
 
 class FileSkipped(Exception):
@@ -104,7 +104,7 @@ class AlreadyRead(FileSkipped):
   """
 
   def __init__(self, last_modified, last_modified_when_read):
-    super(AlreadyRead, self).__init__("File has already been read since it was last modified. modification time: %s, last read: %s" % (last_modified, last_modified_when_read))
+    super(AlreadyRead, self).__init__('File has already been read since it was last modified. modification time: %s, last read: %s' % (last_modified, last_modified_when_read))
     self.last_modified = last_modified
     self.last_modified_when_read = last_modified_when_read
 
@@ -130,7 +130,7 @@ class UnrecognizedType(FileSkipped):
   """
 
   def __init__(self, mime_type):
-    super(UnrecognizedType, self).__init__("Unrecognized mime type: %s (%s)" % mime_type)
+    super(UnrecognizedType, self).__init__('Unrecognized mime type: %s (%s)' % mime_type)
     self.mime_type = mime_type
 
 
@@ -148,10 +148,10 @@ class ReadFailed(FileSkipped):
 
 
 class FileMissing(ReadFailed):
-  "File does not exist."
+  'File does not exist.'
 
   def __init__(self):
-    super(FileMissing, self).__init__("File does not exist")
+    super(FileMissing, self).__init__('File does not exist')
 
 
 def load_processed_files(path):
@@ -179,10 +179,10 @@ def load_processed_files(path):
       if not line:
         continue  # skip blank lines
 
-      if not " " in line:
-        raise TypeError("Malformed line: %s" % line)
+      if not ' ' in line:
+        raise TypeError('Malformed line: %s' % line)
 
-      path, timestamp = line.rsplit(" ", 1)
+      path, timestamp = line.rsplit(' ', 1)
 
       if not os.path.isabs(path):
         raise TypeError("'%s' is not an absolute path" % path)
@@ -219,12 +219,12 @@ def save_processed_files(path, processed_files):
   except OSError as exc:
     raise IOError(exc)
 
-  with open(path, "w") as output_file:
+  with open(path, 'w') as output_file:
     for path, timestamp in processed_files.items():
       if not os.path.isabs(path):
-        raise TypeError("Only absolute paths are acceptable: %s" % path)
+        raise TypeError('Only absolute paths are acceptable: %s' % path)
 
-      output_file.write("%s %i\n" % (path, timestamp))
+      output_file.write('%s %i\n' % (path, timestamp))
 
 
 class DescriptorReader(object):
@@ -378,10 +378,10 @@ class DescriptorReader(object):
 
     with self._reader_thread_lock:
       if self._reader_thread:
-        raise ValueError("Already running, you need to call stop() first")
+        raise ValueError('Already running, you need to call stop() first')
       else:
         self._is_stopped.clear()
-        self._reader_thread = threading.Thread(target = self._read_descriptor_files, name="Descriptor Reader")
+        self._reader_thread = threading.Thread(target = self._read_descriptor_files, name='Descriptor Reader')
         self._reader_thread.setDaemon(True)
         self._reader_thread.start()
 
diff --git a/stem/descriptor/remote.py b/stem/descriptor/remote.py
index 187ed84..da58f2b 100644
--- a/stem/descriptor/remote.py
+++ b/stem/descriptor/remote.py
@@ -19,17 +19,17 @@ content. For example...
 
   query = downloader.get_server_descriptors()
 
-  print "Exit Relays:"
+  print 'Exit Relays:'
 
   try:
     for desc in query.run():
       if desc.exit_policy.is_exiting_allowed():
-        print "  %s (%s)" % (desc.nickname, desc.fingerprint)
+        print '  %s (%s)' % (desc.nickname, desc.fingerprint)
 
     print
-    print "Query took %0.2f seconds" % query.runtime
+    print 'Query took %0.2f seconds' % query.runtime
   except Exception as exc:
-    print "Unable to retrieve the server descriptors: %s" % exc
+    print 'Unable to retrieve the server descriptors: %s' % exc
 
 If you don't care about errors then you can also simply iterate over the query
 itself...
@@ -38,7 +38,7 @@ itself...
 
   for desc in downloader.get_server_descriptors():
     if desc.exit_policy.is_exiting_allowed():
-      print "  %s (%s)" % (desc.nickname, desc.fingerprint)
+      print '  %s (%s)' % (desc.nickname, desc.fingerprint)
 
 ::
 
@@ -137,19 +137,19 @@ class Query(object):
       timeout = 30,
     )
 
-    print "Current relays:"
+    print 'Current relays:'
 
     if not query.error:
       for desc in query:
         print desc.fingerprint
     else:
-      print "Unable to retrieve the server descriptors: %s" % query.error
+      print 'Unable to retrieve the server descriptors: %s' % query.error
 
   ... while iterating fails silently...
 
   ::
 
-    print "Current relays:"
+    print 'Current relays:'
 
     for desc in Query('/tor/server/all.z', 'server-descriptor 1.0'):
       print desc.fingerprint
@@ -257,7 +257,7 @@ class Query(object):
     with self._downloader_thread_lock:
       if self._downloader_thread is None:
         self._downloader_thread = threading.Thread(
-          name = "Descriptor Query",
+          name = 'Descriptor Query',
           target = self._download_descriptors,
           args = (self.retries,)
         )
@@ -345,7 +345,7 @@ class Query(object):
     else:
       address, dirport = random.choice(self.endpoints)
 
-    return "http://%s:%i/%s"; % (address, dirport, self.resource.lstrip('/'))
+    return 'http://%s:%i/%s' % (address, dirport, self.resource.lstrip('/'))
 
   def _download_descriptors(self, retries):
     try:
@@ -397,9 +397,9 @@ class DescriptorDownloader(object):
       try:
         start_time = time.time()
         self.use_directory_mirrors()
-        log.debug("Retrieved directory mirrors (took %0.2fs)" % (time.time() - start_time))
+        log.debug('Retrieved directory mirrors (took %0.2fs)' % (time.time() - start_time))
       except Exception as exc:
-        log.debug("Unable to retrieve directory mirrors: %s" % exc)
+        log.debug('Unable to retrieve directory mirrors: %s' % exc)
 
   def use_directory_mirrors(self):
     """
@@ -451,7 +451,7 @@ class DescriptorDownloader(object):
 
     if fingerprints:
       if len(fingerprints) > MAX_FINGERPRINTS:
-        raise ValueError("Unable to request more than %i descriptors at a time by their fingerprints" % MAX_FINGERPRINTS)
+        raise ValueError('Unable to request more than %i descriptors at a time by their fingerprints' % MAX_FINGERPRINTS)
 
       resource = '/tor/server/fp/%s.z' % '+'.join(fingerprints)
 
@@ -481,7 +481,7 @@ class DescriptorDownloader(object):
 
     if fingerprints:
       if len(fingerprints) > MAX_FINGERPRINTS:
-        raise ValueError("Unable to request more than %i descriptors at a time by their fingerprints" % MAX_FINGERPRINTS)
+        raise ValueError('Unable to request more than %i descriptors at a time by their fingerprints' % MAX_FINGERPRINTS)
 
       resource = '/tor/extra/fp/%s.z' % '+'.join(fingerprints)
 
@@ -510,7 +510,7 @@ class DescriptorDownloader(object):
       hashes = [hashes]
 
     if len(hashes) > MAX_MICRODESCRIPTOR_HASHES:
-      raise ValueError("Unable to request more than %i microdescriptors at a time by their hashes" % MAX_MICRODESCRIPTOR_HASHES)
+      raise ValueError('Unable to request more than %i microdescriptors at a time by their hashes' % MAX_MICRODESCRIPTOR_HASHES)
 
     return self.query('/tor/micro/d/%s.z' % '-'.join(hashes), **query_args)
 
@@ -582,7 +582,7 @@ class DescriptorDownloader(object):
 
     if authority_v3idents:
       if len(authority_v3idents) > MAX_FINGERPRINTS:
-        raise ValueError("Unable to request more than %i key certificates at a time by their identity fingerprints" % MAX_FINGERPRINTS)
+        raise ValueError('Unable to request more than %i key certificates at a time by their identity fingerprints' % MAX_FINGERPRINTS)
 
       resource = '/tor/keys/fp/%s.z' % '+'.join(authority_v3idents)
 
diff --git a/stem/descriptor/router_status_entry.py b/stem/descriptor/router_status_entry.py
index 05810ac..190a4a3 100644
--- a/stem/descriptor/router_status_entry.py
+++ b/stem/descriptor/router_status_entry.py
@@ -34,7 +34,7 @@ from stem.descriptor import (
 )
 
 
-def _parse_file(document_file, validate, entry_class, entry_keyword = "r", start_position = None, end_position = None, section_end_keywords = (), extra_args = ()):
+def _parse_file(document_file, validate, entry_class, entry_keyword = 'r', start_position = None, end_position = None, section_end_keywords = (), extra_args = ()):
   """
   Reads a range of the document_file containing some number of entry_class
   instances. We deliminate the entry_class entries by the keyword on their
@@ -89,7 +89,7 @@ def _parse_file(document_file, validate, entry_class, entry_keyword = "r", start
       include_ending_keyword = True
     )
 
-    desc_content = bytes.join(b"", desc_lines)
+    desc_content = bytes.join(b'', desc_lines)
 
     if desc_content:
       yield entry_class(desc_content, validate, *extra_args)
@@ -178,7 +178,7 @@ class RouterStatusEntry(Descriptor):
       elif keyword == 'v':
         _parse_v_line(self, value, validate)
       else:
-        self._unrecognized_lines.append("%s %s" % (keyword, value))
+        self._unrecognized_lines.append('%s %s' % (keyword, value))
 
   def _check_constraints(self, entries):
     """
@@ -207,9 +207,9 @@ class RouterStatusEntry(Descriptor):
     """
 
     if is_plural:
-      return "Router status entries"
+      return 'Router status entries'
     else:
-      return "Router status entry"
+      return 'Router status entry'
 
   def _required_fields(self):
     """
@@ -277,9 +277,9 @@ class RouterStatusEntryV2(RouterStatusEntry):
 
   def _name(self, is_plural = False):
     if is_plural:
-      return "Router status entries (v2)"
+      return 'Router status entries (v2)'
     else:
-      return "Router status entry (v2)"
+      return 'Router status entry (v2)'
 
   def _required_fields(self):
     return ('r')
@@ -371,9 +371,9 @@ class RouterStatusEntryV3(RouterStatusEntry):
 
   def _name(self, is_plural = False):
     if is_plural:
-      return "Router status entries (v3)"
+      return 'Router status entries (v3)'
     else:
-      return "Router status entry (v3)"
+      return 'Router status entry (v3)'
 
   def _required_fields(self):
     return ('r', 's')
@@ -446,9 +446,9 @@ class RouterStatusEntryMicroV3(RouterStatusEntry):
 
   def _name(self, is_plural = False):
     if is_plural:
-      return "Router status entries (micro v3)"
+      return 'Router status entries (micro v3)'
     else:
-      return "Router status entry (micro v3)"
+      return 'Router status entry (micro v3)'
 
   def _required_fields(self):
     return ('r', 's', 'm')
@@ -485,7 +485,7 @@ def _parse_r_line(desc, value, validate, include_digest = True):
   #   "r" nickname identity publication IP ORPort DirPort
   #   example: r Konata ARIJF2zbqirB9IwsW0mQznccWww 2012-09-24 13:40:40 69.64.48.168 9001 9030
 
-  r_comp = value.split(" ")
+  r_comp = value.split(' ')
 
   # inject a None for the digest to normalize the field positioning
   if not include_digest:
@@ -504,9 +504,9 @@ def _parse_r_line(desc, value, validate, include_digest = True):
     elif not stem.util.connection.is_valid_ipv4_address(r_comp[5]):
       raise ValueError("%s address isn't a valid IPv4 address: %s" % (desc._name(), r_comp[5]))
     elif not stem.util.connection.is_valid_port(r_comp[6]):
-      raise ValueError("%s ORPort is invalid: %s" % (desc._name(), r_comp[6]))
+      raise ValueError('%s ORPort is invalid: %s' % (desc._name(), r_comp[6]))
     elif not stem.util.connection.is_valid_port(r_comp[7], allow_zero = True):
-      raise ValueError("%s DirPort is invalid: %s" % (desc._name(), r_comp[7]))
+      raise ValueError('%s DirPort is invalid: %s' % (desc._name(), r_comp[7]))
   elif not (r_comp[6].isdigit() and r_comp[7].isdigit()):
     return
 
@@ -521,8 +521,8 @@ def _parse_r_line(desc, value, validate, include_digest = True):
   desc.dir_port = None if r_comp[7] == '0' else int(r_comp[7])
 
   try:
-    published = "%s %s" % (r_comp[3], r_comp[4])
-    desc.published = datetime.datetime.strptime(published, "%Y-%m-%d %H:%M:%S")
+    published = '%s %s' % (r_comp[3], r_comp[4])
+    desc.published = datetime.datetime.strptime(published, '%Y-%m-%d %H:%M:%S')
   except ValueError:
     if validate:
       raise ValueError("Publication time time wasn't parsable: r %s" % value)
@@ -539,7 +539,7 @@ def _parse_a_line(desc, value, validate):
     raise ValueError("%s 'a' line must be of the form '[address]:[ports]': a %s" % (desc._name(), value))
 
   address, port = value.rsplit(':', 1)
-  is_ipv6 = address.startswith("[") and address.endswith("]")
+  is_ipv6 = address.startswith('[') and address.endswith(']')
 
   if is_ipv6:
     address = address[1:-1]  # remove brackets
@@ -561,13 +561,13 @@ def _parse_s_line(desc, value, validate):
   # "s" Flags
   # example: s Named Running Stable Valid
 
-  flags = [] if value == "" else value.split(" ")
+  flags = [] if value == '' else value.split(' ')
   desc.flags = flags
 
   if validate:
     for flag in flags:
       if flags.count(flag) > 1:
-        raise ValueError("%s had duplicate flags: s %s" % (desc._name(), value))
+        raise ValueError('%s had duplicate flags: s %s' % (desc._name(), value))
       elif flag == "":
         raise ValueError("%s had extra whitespace on its 's' line: s %s" % (desc._name(), value))
 
@@ -582,26 +582,26 @@ def _parse_v_line(desc, value, validate):
 
   desc.version_line = value
 
-  if value.startswith("Tor "):
+  if value.startswith('Tor '):
     try:
       desc.version = stem.version._get_version(value[4:])
     except ValueError as exc:
       if validate:
-        raise ValueError("%s has a malformed tor version (%s): v %s" % (desc._name(), exc, value))
+        raise ValueError('%s has a malformed tor version (%s): v %s' % (desc._name(), exc, value))
 
 
 def _parse_w_line(desc, value, validate):
   # "w" "Bandwidth=" INT ["Measured=" INT] ["Unmeasured=1"]
   # example: w Bandwidth=7980
 
-  w_comp = value.split(" ")
+  w_comp = value.split(' ')
 
   if len(w_comp) < 1:
     if not validate:
       return
 
     raise ValueError("%s 'w' line is blank: w %s" % (desc._name(), value))
-  elif not w_comp[0].startswith("Bandwidth="):
+  elif not w_comp[0].startswith('Bandwidth='):
     if not validate:
       return
 
@@ -613,7 +613,7 @@ def _parse_w_line(desc, value, validate):
     else:
       w_key, w_value = w_entry, None
 
-    if w_key == "Bandwidth":
+    if w_key == 'Bandwidth':
       if not (w_value and w_value.isdigit()):
         if not validate:
           return
@@ -621,7 +621,7 @@ def _parse_w_line(desc, value, validate):
         raise ValueError("%s 'Bandwidth=' entry needs to have a numeric value: w %s" % (desc._name(), value))
 
       desc.bandwidth = int(w_value)
-    elif w_key == "Measured":
+    elif w_key == 'Measured':
       if not (w_value and w_value.isdigit()):
         if not validate:
           return
@@ -629,8 +629,8 @@ def _parse_w_line(desc, value, validate):
         raise ValueError("%s 'Measured=' entry needs to have a numeric value: w %s" % (desc._name(), value))
 
       desc.measured = int(w_value)
-    elif w_key == "Unmeasured":
-      if validate and w_value != "1":
+    elif w_key == 'Unmeasured':
+      if validate and w_value != '1':
         raise ValueError("%s 'Unmeasured=' should only have the value of '1': w %s" % (desc._name(), value))
 
       desc.is_unmeasured = True
@@ -649,20 +649,20 @@ def _parse_p_line(desc, value, validate):
     if not validate:
       return
 
-    raise ValueError("%s exit policy is malformed (%s): p %s" % (desc._name(), exc, value))
+    raise ValueError('%s exit policy is malformed (%s): p %s' % (desc._name(), exc, value))
 
 
 def _parse_m_line(desc, value, validate):
   # "m" methods 1*(algorithm "=" digest)
   # example: m 8,9,10,11,12 sha256=g1vx9si329muxV3tquWIXXySNOIwRGMeAESKs/v4DWs
 
-  m_comp = value.split(" ")
+  m_comp = value.split(' ')
 
   if not (desc.document and desc.document.is_vote):
     if not validate:
       return
 
-    vote_status = "vote" if desc.document else "<undefined document>"
+    vote_status = 'vote' if desc.document else '<undefined document>'
     raise ValueError("%s 'm' line should only appear in votes (appeared in a %s): m %s" % (desc._name(), vote_status, value))
   elif len(m_comp) < 1:
     if not validate:
@@ -671,12 +671,12 @@ def _parse_m_line(desc, value, validate):
     raise ValueError("%s 'm' line needs to start with a series of methods: m %s" % (desc._name(), value))
 
   try:
-    methods = [int(entry) for entry in m_comp[0].split(",")]
+    methods = [int(entry) for entry in m_comp[0].split(',')]
   except ValueError:
     if not validate:
       return
 
-    raise ValueError("%s microdescriptor methods should be a series of comma separated integers: m %s" % (desc._name(), value))
+    raise ValueError('%s microdescriptor methods should be a series of comma separated integers: m %s' % (desc._name(), value))
 
   hashes = {}
 
@@ -713,9 +713,9 @@ def _base64_to_hex(identity, validate, check_if_fingerprint = True):
 
   # trailing equal signs were stripped from the identity
   missing_padding = len(identity) % 4
-  identity += "=" * missing_padding
+  identity += '=' * missing_padding
 
-  fingerprint = ""
+  fingerprint = ''
 
   try:
     identity_decoded = base64.b64decode(stem.util.str_tools._to_bytes(identity))
diff --git a/stem/descriptor/server_descriptor.py b/stem/descriptor/server_descriptor.py
index a88594b..58598b2 100644
--- a/stem/descriptor/server_descriptor.py
+++ b/stem/descriptor/server_descriptor.py
@@ -60,35 +60,35 @@ except ImportError:
 
 # relay descriptors must have exactly one of the following
 REQUIRED_FIELDS = (
-  "router",
-  "bandwidth",
-  "published",
-  "onion-key",
-  "signing-key",
-  "router-signature",
+  'router',
+  'bandwidth',
+  'published',
+  'onion-key',
+  'signing-key',
+  'router-signature',
 )
 
 # optional entries that can appear at most once
 SINGLE_FIELDS = (
-  "platform",
-  "fingerprint",
-  "hibernating",
-  "uptime",
-  "contact",
-  "read-history",
-  "write-history",
-  "eventdns",
-  "family",
-  "caches-extra-info",
-  "extra-info-digest",
-  "hidden-service-dir",
-  "protocols",
-  "allow-single-hop-exits",
-  "ntor-onion-key",
+  'platform',
+  'fingerprint',
+  'hibernating',
+  'uptime',
+  'contact',
+  'read-history',
+  'write-history',
+  'eventdns',
+  'family',
+  'caches-extra-info',
+  'extra-info-digest',
+  'hidden-service-dir',
+  'protocols',
+  'allow-single-hop-exits',
+  'ntor-onion-key',
 )
 
-DEFAULT_IPV6_EXIT_POLICY = stem.exit_policy.MicroExitPolicy("reject 1-65535")
-REJECT_ALL_POLICY = stem.exit_policy.ExitPolicy("reject *:*")
+DEFAULT_IPV6_EXIT_POLICY = stem.exit_policy.MicroExitPolicy('reject 1-65535')
+REJECT_ALL_POLICY = stem.exit_policy.ExitPolicy('reject *:*')
 
 
 def _parse_file(descriptor_file, is_bridge = False, validate = True, **kwargs):
@@ -126,8 +126,8 @@ def _parse_file(descriptor_file, is_bridge = False, validate = True, **kwargs):
   # Metrics descriptor files are the same, but lack any annotations. The
   # following simply does the following...
   #
-  #   - parse as annotations until we get to "router"
-  #   - parse as descriptor content until we get to "router-signature" followed
+  #   - parse as annotations until we get to 'router'
+  #   - parse as descriptor content until we get to 'router-signature' followed
   #     by the end of the signature block
   #   - construct a descriptor and provide it back to the caller
   #
@@ -135,8 +135,8 @@ def _parse_file(descriptor_file, is_bridge = False, validate = True, **kwargs):
   # to the caller).
 
   while True:
-    annotations = _read_until_keywords("router", descriptor_file)
-    descriptor_content = _read_until_keywords("router-signature", descriptor_file)
+    annotations = _read_until_keywords('router', descriptor_file)
+    descriptor_content = _read_until_keywords('router-signature', descriptor_file)
 
     # we've reached the 'router-signature', now include the pgp style block
     block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0]
@@ -146,7 +146,7 @@ def _parse_file(descriptor_file, is_bridge = False, validate = True, **kwargs):
       # strip newlines from annotations
       annotations = map(bytes.strip, annotations)
 
-      descriptor_text = bytes.join(b"", descriptor_content)
+      descriptor_text = bytes.join(b'', descriptor_content)
 
       if is_bridge:
         yield BridgeDescriptor(descriptor_text, validate, annotations, **kwargs)
@@ -214,7 +214,7 @@ class ServerDescriptor(Descriptor):
   def __init__(self, raw_contents, validate = True, annotations = None):
     """
     Server descriptor constructor, created from an individual relay's
-    descriptor content (as provided by "GETINFO desc/*", cached descriptors,
+    descriptor content (as provided by 'GETINFO desc/*', cached descriptors,
     and metrics).
 
     By default this validates the descriptor's content as it's parsed. This
@@ -234,8 +234,8 @@ class ServerDescriptor(Descriptor):
     # Only a few things can be arbitrary bytes according to the dir-spec, so
     # parsing them separately.
 
-    self.platform = _get_bytes_field("platform", raw_contents)
-    self.contact = _get_bytes_field("contact", raw_contents)
+    self.platform = _get_bytes_field('platform', raw_contents)
+    self.contact = _get_bytes_field('contact', raw_contents)
 
     raw_contents = stem.util.str_tools._to_unicode(raw_contents)
 
@@ -289,7 +289,7 @@ class ServerDescriptor(Descriptor):
     # influences the resulting exit policy, but for everything else the order
     # does not matter so breaking it into key / value pairs.
 
-    entries, policy = _get_descriptor_components(raw_contents, validate, ("accept", "reject"))
+    entries, policy = _get_descriptor_components(raw_contents, validate, ('accept', 'reject'))
 
     if policy == [u'reject *:*']:
       self.exit_policy = REJECT_ALL_POLICY
@@ -309,7 +309,7 @@ class ServerDescriptor(Descriptor):
     :returns: **unicode** with the upper-case hex digest value for this server descriptor
     """
 
-    raise NotImplementedError("Unsupported Operation: this should be implemented by the ServerDescriptor subclass")
+    raise NotImplementedError('Unsupported Operation: this should be implemented by the ServerDescriptor subclass')
 
   def get_unrecognized_lines(self):
     return list(self._unrecognized_lines)
@@ -331,8 +331,8 @@ class ServerDescriptor(Descriptor):
     annotation_dict = {}
 
     for line in self._annotation_lines:
-      if b" " in line:
-        key, value = line.split(b" ", 1)
+      if b' ' in line:
+        key, value = line.split(b' ', 1)
         annotation_dict[key] = value
       else:
         annotation_dict[line] = None
@@ -366,12 +366,12 @@ class ServerDescriptor(Descriptor):
       # most just work with the first (and only) value
       value, block_contents = values[0]
 
-      line = "%s %s" % (keyword, value)  # original line
+      line = '%s %s' % (keyword, value)  # original line
 
       if block_contents:
-        line += "\n%s" % block_contents
+        line += '\n%s' % block_contents
 
-      if keyword == "router":
+      if keyword == 'router':
         # "router" nickname address ORPort SocksPort DirPort
         router_comp = value.split()
 
@@ -379,7 +379,7 @@ class ServerDescriptor(Descriptor):
           if not validate:
             continue
 
-          raise ValueError("Router line must have five values: %s" % line)
+          raise ValueError('Router line must have five values: %s' % line)
 
         if validate:
           if not stem.util.tor_tools.is_valid_nickname(router_comp[0]):
@@ -400,7 +400,7 @@ class ServerDescriptor(Descriptor):
         self.or_port = int(router_comp[2])
         self.socks_port = None if router_comp[3] == '0' else int(router_comp[3])
         self.dir_port = None if router_comp[4] == '0' else int(router_comp[4])
-      elif keyword == "bandwidth":
+      elif keyword == 'bandwidth':
         # "bandwidth" bandwidth-avg bandwidth-burst bandwidth-observed
         bandwidth_comp = value.split()
 
@@ -408,7 +408,7 @@ class ServerDescriptor(Descriptor):
           if not validate:
             continue
 
-          raise ValueError("Bandwidth line must have three values: %s" % line)
+          raise ValueError('Bandwidth line must have three values: %s' % line)
         elif not bandwidth_comp[0].isdigit():
           if not validate:
             continue
@@ -428,7 +428,7 @@ class ServerDescriptor(Descriptor):
         self.average_bandwidth = int(bandwidth_comp[0])
         self.burst_bandwidth = int(bandwidth_comp[1])
         self.observed_bandwidth = int(bandwidth_comp[2])
-      elif keyword == "platform":
+      elif keyword == 'platform':
         # "platform" string
 
         # The platform attribute was set earlier. This line can contain any
@@ -440,7 +440,7 @@ class ServerDescriptor(Descriptor):
         # There's no guarantee that we'll be able to pick these out the
         # version, but might as well try to save our caller the effort.
 
-        platform_match = re.match("^(?:node-)?Tor (\S*).* on (.*)$", value)
+        platform_match = re.match('^(?:node-)?Tor (\S*).* on (.*)$', value)
 
         if platform_match:
           version_str, self.operating_system = platform_match.groups()
@@ -449,54 +449,54 @@ class ServerDescriptor(Descriptor):
             self.tor_version = stem.version._get_version(version_str)
           except ValueError:
             pass
-      elif keyword == "published":
+      elif keyword == 'published':
         # "published" YYYY-MM-DD HH:MM:SS
 
         try:
-          self.published = datetime.datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
+          self.published = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
         except ValueError:
           if validate:
             raise ValueError("Published line's time wasn't parsable: %s" % line)
-      elif keyword == "fingerprint":
+      elif keyword == 'fingerprint':
         # This is forty hex digits split into space separated groups of four.
         # Checking that we match this pattern.
 
-        fingerprint = value.replace(" ", "")
+        fingerprint = value.replace(' ', '')
 
         if validate:
-          for grouping in value.split(" "):
+          for grouping in value.split(' '):
             if len(grouping) != 4:
-              raise ValueError("Fingerprint line should have groupings of four hex digits: %s" % value)
+              raise ValueError('Fingerprint line should have groupings of four hex digits: %s' % value)
 
           if not stem.util.tor_tools.is_valid_fingerprint(fingerprint):
-            raise ValueError("Tor relay fingerprints consist of forty hex digits: %s" % value)
+            raise ValueError('Tor relay fingerprints consist of forty hex digits: %s' % value)
 
         self.fingerprint = fingerprint
-      elif keyword == "hibernating":
+      elif keyword == 'hibernating':
         # "hibernating" 0|1 (in practice only set if one)
 
-        if validate and not value in ("0", "1"):
-          raise ValueError("Hibernating line had an invalid value, must be zero or one: %s" % value)
+        if validate and not value in ('0', '1'):
+          raise ValueError('Hibernating line had an invalid value, must be zero or one: %s' % value)
 
-        self.hibernating = value == "1"
-      elif keyword == "allow-single-hop-exits":
+        self.hibernating = value == '1'
+      elif keyword == 'allow-single-hop-exits':
         self.allow_single_hop_exits = True
-      elif keyword == "caches-extra-info":
+      elif keyword == 'caches-extra-info':
         self.extra_info_cache = True
-      elif keyword == "extra-info-digest":
+      elif keyword == 'extra-info-digest':
         # this is forty hex digits which just so happens to be the same a
         # fingerprint
 
         if validate and not stem.util.tor_tools.is_valid_fingerprint(value):
-          raise ValueError("Extra-info digests should consist of forty hex digits: %s" % value)
+          raise ValueError('Extra-info digests should consist of forty hex digits: %s' % value)
 
         self.extra_info_digest = value
-      elif keyword == "hidden-service-dir":
+      elif keyword == 'hidden-service-dir':
         if value:
-          self.hidden_service_dir = value.split(" ")
+          self.hidden_service_dir = value.split(' ')
         else:
-          self.hidden_service_dir = ["2"]
-      elif keyword == "uptime":
+          self.hidden_service_dir = ['2']
+      elif keyword == 'uptime':
         # We need to be tolerant of negative uptimes to accommodate a past tor
         # bug...
         #
@@ -514,38 +514,38 @@ class ServerDescriptor(Descriptor):
           if not validate:
             continue
 
-          raise ValueError("Uptime line must have an integer value: %s" % value)
-      elif keyword == "contact":
+          raise ValueError('Uptime line must have an integer value: %s' % value)
+      elif keyword == 'contact':
         pass  # parsed as a bytes field earlier
-      elif keyword == "protocols":
-        protocols_match = re.match("^Link (.*) Circuit (.*)$", value)
+      elif keyword == 'protocols':
+        protocols_match = re.match('^Link (.*) Circuit (.*)$', value)
 
         if protocols_match:
           link_versions, circuit_versions = protocols_match.groups()
-          self.link_protocols = link_versions.split(" ")
-          self.circuit_protocols = circuit_versions.split(" ")
+          self.link_protocols = link_versions.split(' ')
+          self.circuit_protocols = circuit_versions.split(' ')
         elif validate:
-          raise ValueError("Protocols line did not match the expected pattern: %s" % line)
-      elif keyword == "family":
-        self.family = set(value.split(" "))
-      elif keyword == "eventdns":
-        self.eventdns = value == "1"
-      elif keyword == "ipv6-policy":
+          raise ValueError('Protocols line did not match the expected pattern: %s' % line)
+      elif keyword == 'family':
+        self.family = set(value.split(' '))
+      elif keyword == 'eventdns':
+        self.eventdns = value == '1'
+      elif keyword == 'ipv6-policy':
         self.exit_policy_v6 = stem.exit_policy.MicroExitPolicy(value)
-      elif keyword == "or-address":
+      elif keyword == 'or-address':
         or_address_entries = [value for (value, _) in values]
 
         for entry in or_address_entries:
-          line = "%s %s" % (keyword, entry)
+          line = '%s %s' % (keyword, entry)
 
-          if not ":" in entry:
+          if not ':' in entry:
             if not validate:
               continue
             else:
-              raise ValueError("or-address line missing a colon: %s" % line)
+              raise ValueError('or-address line missing a colon: %s' % line)
 
           address, port = entry.rsplit(':', 1)
-          is_ipv6 = address.startswith("[") and address.endswith("]")
+          is_ipv6 = address.startswith('[') and address.endswith(']')
 
           if is_ipv6:
             address = address[1:-1]  # remove brackets
@@ -555,26 +555,26 @@ class ServerDescriptor(Descriptor):
             if not validate:
               continue
             else:
-              raise ValueError("or-address line has a malformed address: %s" % line)
+              raise ValueError('or-address line has a malformed address: %s' % line)
 
           if stem.util.connection.is_valid_port(port):
             self.or_addresses.append((address, int(port), is_ipv6))
           elif validate:
-            raise ValueError("or-address line has a malformed port: %s" % line)
-      elif keyword in ("read-history", "write-history"):
+            raise ValueError('or-address line has a malformed port: %s' % line)
+      elif keyword in ('read-history', 'write-history'):
         try:
           timestamp, interval, remainder = \
             stem.descriptor.extrainfo_descriptor._parse_timestamp_and_interval(keyword, value)
 
           try:
             if remainder:
-              history_values = [int(entry) for entry in remainder.split(",")]
+              history_values = [int(entry) for entry in remainder.split(',')]
             else:
               history_values = []
           except ValueError:
-            raise ValueError("%s line has non-numeric values: %s" % (keyword, line))
+            raise ValueError('%s line has non-numeric values: %s' % (keyword, line))
 
-          if keyword == "read-history":
+          if keyword == 'read-history':
             self.read_history_end = timestamp
             self.read_history_interval = interval
             self.read_history_values = history_values
@@ -592,7 +592,7 @@ class ServerDescriptor(Descriptor):
     # this bug then fail validation
 
     if validate and self.uptime and self.tor_version:
-      if self.uptime < 0 and self.tor_version >= stem.version.Version("0.1.2.7"):
+      if self.uptime < 0 and self.tor_version >= stem.version.Version('0.1.2.7'):
         raise ValueError("Descriptor for version '%s' had a negative uptime value: %i" % (self.tor_version, self.uptime))
 
   def _check_constraints(self, entries):
@@ -634,10 +634,10 @@ class ServerDescriptor(Descriptor):
     return REQUIRED_FIELDS + SINGLE_FIELDS
 
   def _first_keyword(self):
-    return "router"
+    return 'router'
 
   def _last_keyword(self):
-    return "router-signature"
+    return 'router-signature'
 
 
 class RelayDescriptor(ServerDescriptor):
@@ -679,8 +679,8 @@ class RelayDescriptor(ServerDescriptor):
     # descriptor except the router-signature.
 
     raw_descriptor = self.get_bytes()
-    start_token = b"router "
-    sig_token = b"\nrouter-signature\n"
+    start_token = b'router '
+    sig_token = b'\nrouter-signature\n'
     start = raw_descriptor.find(start_token)
     sig_start = raw_descriptor.find(sig_token)
     end = sig_start + len(sig_token)
@@ -690,7 +690,7 @@ class RelayDescriptor(ServerDescriptor):
       digest_hash = hashlib.sha1(stem.util.str_tools._to_bytes(for_digest))
       return stem.util.str_tools._to_unicode(digest_hash.hexdigest().upper())
     else:
-      raise ValueError("unable to calculate digest for descriptor")
+      raise ValueError('unable to calculate digest for descriptor')
 
   def _validate_content(self):
     """
@@ -709,8 +709,8 @@ class RelayDescriptor(ServerDescriptor):
       key_der_as_hash = hashlib.sha1(stem.util.str_tools._to_bytes(key_as_bytes)).hexdigest()
 
       if key_der_as_hash != self.fingerprint.lower():
-        log.warn("Signing key hash: %s != fingerprint: %s" % (key_der_as_hash, self.fingerprint.lower()))
-        raise ValueError("Fingerprint does not match hash")
+        log.warn('Signing key hash: %s != fingerprint: %s' % (key_der_as_hash, self.fingerprint.lower()))
+        raise ValueError('Fingerprint does not match hash')
 
     self._verify_digest(key_as_bytes)
 
@@ -762,9 +762,9 @@ class RelayDescriptor(ServerDescriptor):
 
     try:
       if decrypted_bytes.index(b'\x00\x01') != 0:
-        raise ValueError("Verification failed, identifier missing")
+        raise ValueError('Verification failed, identifier missing')
     except ValueError:
-      raise ValueError("Verification failed, malformed data")
+      raise ValueError('Verification failed, malformed data')
 
     try:
       identifier_offset = 2
@@ -772,7 +772,7 @@ class RelayDescriptor(ServerDescriptor):
       # find the separator
       seperator_index = decrypted_bytes.index(b'\x00', identifier_offset)
     except ValueError:
-      raise ValueError("Verification failed, seperator not found")
+      raise ValueError('Verification failed, seperator not found')
 
     digest_hex = codecs.encode(decrypted_bytes[seperator_index + 1:], 'hex_codec')
     digest = stem.util.str_tools._to_unicode(digest_hex.upper())
@@ -780,7 +780,7 @@ class RelayDescriptor(ServerDescriptor):
     local_digest = self.digest()
 
     if digest != local_digest:
-      raise ValueError("Decrypted digest does not match local digest (calculated: %s, local: %s)" % (digest, local_digest))
+      raise ValueError('Decrypted digest does not match local digest (calculated: %s, local: %s)' % (digest, local_digest))
 
   def _parse(self, entries, validate):
     entries = dict(entries)  # shallow copy since we're destructive
@@ -789,29 +789,29 @@ class RelayDescriptor(ServerDescriptor):
 
     for keyword, values in entries.items():
       value, block_contents = values[0]
-      line = "%s %s" % (keyword, value)
+      line = '%s %s' % (keyword, value)
 
-      if keyword == "onion-key":
+      if keyword == 'onion-key':
         if validate and not block_contents:
-          raise ValueError("Onion key line must be followed by a public key: %s" % line)
+          raise ValueError('Onion key line must be followed by a public key: %s' % line)
 
         self.onion_key = block_contents
-        del entries["onion-key"]
-      elif keyword == "ntor-onion-key":
+        del entries['onion-key']
+      elif keyword == 'ntor-onion-key':
         self.ntor_onion_key = value
-        del entries["ntor-onion-key"]
-      elif keyword == "signing-key":
+        del entries['ntor-onion-key']
+      elif keyword == 'signing-key':
         if validate and not block_contents:
-          raise ValueError("Signing key line must be followed by a public key: %s" % line)
+          raise ValueError('Signing key line must be followed by a public key: %s' % line)
 
         self.signing_key = block_contents
-        del entries["signing-key"]
-      elif keyword == "router-signature":
+        del entries['signing-key']
+      elif keyword == 'router-signature':
         if validate and not block_contents:
-          raise ValueError("Router signature line must be followed by a signature block: %s" % line)
+          raise ValueError('Router signature line must be followed by a signature block: %s' % line)
 
         self.signature = block_contents
-        del entries["router-signature"]
+        del entries['router-signature']
 
     ServerDescriptor._parse(self, entries, validate)
 
@@ -868,14 +868,14 @@ class BridgeDescriptor(ServerDescriptor):
     # handles fields only in bridge descriptors
     for keyword, values in entries.items():
       value, block_contents = values[0]
-      line = "%s %s" % (keyword, value)
+      line = '%s %s' % (keyword, value)
 
-      if keyword == "router-digest":
+      if keyword == 'router-digest':
         if validate and not stem.util.tor_tools.is_hex_digits(value, 40):
-          raise ValueError("Router digest line had an invalid sha1 digest: %s" % line)
+          raise ValueError('Router digest line had an invalid sha1 digest: %s' % line)
 
         self._digest = stem.util.str_tools._to_unicode(value)
-        del entries["router-digest"]
+        del entries['router-digest']
 
     ServerDescriptor._parse(self, entries, validate)
 
@@ -903,27 +903,27 @@ class BridgeDescriptor(ServerDescriptor):
 
     issues = []
 
-    if not self.address.startswith("10."):
+    if not self.address.startswith('10.'):
       issues.append("Router line's address should be scrubbed to be '10.x.x.x': %s" % self.address)
 
     if self.contact and self.contact != "somebody":
       issues.append("Contact line should be scrubbed to be 'somebody', but instead had '%s'" % self.contact)
 
     for address, _, is_ipv6 in self.or_addresses:
-      if not is_ipv6 and not address.startswith("10."):
+      if not is_ipv6 and not address.startswith('10.'):
         issues.append("or-address line's address should be scrubbed to be '10.x.x.x': %s" % address)
-      elif is_ipv6 and not address.startswith("fd9f:2e19:3bcf::"):
+      elif is_ipv6 and not address.startswith('fd9f:2e19:3bcf::'):
         # TODO: this check isn't quite right because we aren't checking that
         # the next grouping of hex digits contains 1-2 digits
         issues.append("or-address line's address should be scrubbed to be 'fd9f:2e19:3bcf::xx:xxxx': %s" % address)
 
     for line in self.get_unrecognized_lines():
-      if line.startswith("onion-key "):
-        issues.append("Bridge descriptors should have their onion-key scrubbed: %s" % line)
-      elif line.startswith("signing-key "):
-        issues.append("Bridge descriptors should have their signing-key scrubbed: %s" % line)
-      elif line.startswith("router-signature "):
-        issues.append("Bridge descriptors should have their signature scrubbed: %s" % line)
+      if line.startswith('onion-key '):
+        issues.append('Bridge descriptors should have their onion-key scrubbed: %s' % line)
+      elif line.startswith('signing-key '):
+        issues.append('Bridge descriptors should have their signing-key scrubbed: %s' % line)
+      elif line.startswith('router-signature '):
+        issues.append('Bridge descriptors should have their signature scrubbed: %s' % line)
 
     return issues
 
@@ -932,13 +932,13 @@ class BridgeDescriptor(ServerDescriptor):
     # excluded according to the format page
 
     excluded_fields = [
-      "onion-key",
-      "signing-key",
-      "router-signature",
+      'onion-key',
+      'signing-key',
+      'router-signature',
     ]
 
     included_fields = [
-      "router-digest",
+      'router-digest',
     ]
 
     return tuple(included_fields + [f for f in REQUIRED_FIELDS if not f in excluded_fields])
diff --git a/stem/descriptor/tordnsel.py b/stem/descriptor/tordnsel.py
index c629539..07e6af4 100644
--- a/stem/descriptor/tordnsel.py
+++ b/stem/descriptor/tordnsel.py
@@ -32,14 +32,14 @@ def _parse_file(tordnsel_file, validate = True, **kwargs):
   """
 
   # skip content prior to the first ExitNode
-  _read_until_keywords("ExitNode", tordnsel_file, skip = True)
+  _read_until_keywords('ExitNode', tordnsel_file, skip = True)
 
   while True:
-    contents = _read_until_keywords("ExitAddress", tordnsel_file)
-    contents += _read_until_keywords("ExitNode", tordnsel_file)
+    contents = _read_until_keywords('ExitAddress', tordnsel_file)
+    contents += _read_until_keywords('ExitNode', tordnsel_file)
 
     if contents:
-      yield TorDNSEL(bytes.join(b"", contents), validate, **kwargs)
+      yield TorDNSEL(bytes.join(b'', contents), validate, **kwargs)
     else:
       break  # done parsing file
 
@@ -76,40 +76,40 @@ class TorDNSEL(Descriptor):
       value, block_content = values[0]
 
       if validate and block_content:
-        raise ValueError("Unexpected block content: %s" % block_content)
+        raise ValueError('Unexpected block content: %s' % block_content)
 
-      if keyword == "ExitNode":
+      if keyword == 'ExitNode':
         if validate and not stem.util.tor_tools.is_valid_fingerprint(value):
-          raise ValueError("Tor relay fingerprints consist of forty hex digits: %s" % value)
+          raise ValueError('Tor relay fingerprints consist of forty hex digits: %s' % value)
 
         self.fingerprint = value
-      elif keyword == "Published":
+      elif keyword == 'Published':
         try:
-          self.published = datetime.datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
+          self.published = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
         except ValueError:
           if validate:
             raise ValueError("Published time wasn't parsable: %s" % value)
-      elif keyword == "LastStatus":
+      elif keyword == 'LastStatus':
         try:
-          self.last_status = datetime.datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
+          self.last_status = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
         except ValueError:
           if validate:
             raise ValueError("LastStatus time wasn't parsable: %s" % value)
-      elif keyword == "ExitAddress":
+      elif keyword == 'ExitAddress':
         for value, block_content in values:
-          address, date = value.split(" ", 1)
+          address, date = value.split(' ', 1)
 
           if validate:
             if not stem.util.connection.is_valid_ipv4_address(address):
               raise ValueError("ExitAddress isn't a valid IPv4 address: %s" % address)
             elif block_content:
-              raise ValueError("Unexpected block content: %s" % block_content)
+              raise ValueError('Unexpected block content: %s' % block_content)
 
           try:
-            date = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S")
+            date = datetime.datetime.strptime(date, '%Y-%m-%d %H:%M:%S')
             self.exit_addresses.append((address, date))
           except ValueError:
             if validate:
               raise ValueError("ExitAddress found time wasn't parsable: %s" % value)
       elif validate:
-        raise ValueError("Unrecognized keyword: %s" % keyword)
+        raise ValueError('Unrecognized keyword: %s' % keyword)
diff --git a/stem/exit_policy.py b/stem/exit_policy.py
index 78db793..7f1c052 100644
--- a/stem/exit_policy.py
+++ b/stem/exit_policy.py
@@ -8,18 +8,18 @@ exiting to a destination is permissible or not. For instance...
 ::
 
   >>> from stem.exit_policy import ExitPolicy, MicroExitPolicy
-  >>> policy = ExitPolicy("accept *:80", "accept *:443", "reject *:*")
+  >>> policy = ExitPolicy('accept *:80', 'accept *:443', 'reject *:*')
   >>> print policy
   accept *:80, accept *:443, reject *:*
   >>> print policy.summary()
   accept 80, 443
-  >>> policy.can_exit_to("75.119.206.243", 80)
+  >>> policy.can_exit_to('75.119.206.243', 80)
   True
 
-  >>> policy = MicroExitPolicy("accept 80,443")
+  >>> policy = MicroExitPolicy('accept 80,443')
   >>> print policy
   accept 80,443
-  >>> policy.can_exit_to("75.119.206.243", 80)
+  >>> policy.can_exit_to('75.119.206.243', 80)
   True
 
 ::
@@ -69,21 +69,21 @@ try:
 except ImportError:
   from stem.util.lru_cache import lru_cache
 
-AddressType = stem.util.enum.Enum(("WILDCARD", "Wildcard"), ("IPv4", "IPv4"), ("IPv6", "IPv6"))
+AddressType = stem.util.enum.Enum(('WILDCARD', 'Wildcard'), ('IPv4', 'IPv4'), ('IPv6', 'IPv6'))
 
 # Addresses aliased by the 'private' policy. From the tor man page...
 #
 # To specify all internal and link-local networks (including 0.0.0.0/8,
 # 169.254.0.0/16, 127.0.0.0/8, 192.168.0.0/16, 10.0.0.0/8, and 172.16.0.0/12),
-# you can use the "private" alias instead of an address.
+# you can use the 'private' alias instead of an address.
 
 PRIVATE_ADDRESSES = (
-  "0.0.0.0/8",
-  "169.254.0.0/16",
-  "127.0.0.0/8",
-  "192.168.0.0/16",
-  "10.0.0.0/8",
-  "172.16.0.0/12",
+  '0.0.0.0/8',
+  '169.254.0.0/16',
+  '127.0.0.0/8',
+  '192.168.0.0/16',
+  '10.0.0.0/8',
+  '172.16.0.0/12',
 )
 
 
@@ -148,7 +148,7 @@ class ExitPolicy(object):
     # sanity check the types
     for rule in rules:
       if not isinstance(rule, (bytes, unicode, ExitPolicyRule)):
-        raise TypeError("Exit policy rules can only contain strings or ExitPolicyRules, got a %s (%s)" % (type(rule), rules))
+        raise TypeError('Exit policy rules can only contain strings or ExitPolicyRules, got a %s (%s)' % (type(rule), rules))
 
     # Unparsed representation of the rules we were constructed with. Our
     # _get_rules() method consumes this to provide ExitPolicyRule instances.
@@ -282,7 +282,7 @@ class ExitPolicy(object):
           temp_range.append(port)
         else:
           if len(temp_range) > 1:
-            display_ranges.append("%i-%i" % (temp_range[0], temp_range[-1]))
+            display_ranges.append('%i-%i' % (temp_range[0], temp_range[-1]))
           else:
             display_ranges.append(str(temp_range[0]))
 
@@ -290,12 +290,12 @@ class ExitPolicy(object):
     else:
       # everything for the inverse
       is_whitelist = not is_whitelist
-      display_ranges = ["1-65535"]
+      display_ranges = ['1-65535']
 
     # constructs the summary string
-    label_prefix = "accept " if is_whitelist else "reject "
+    label_prefix = 'accept ' if is_whitelist else 'reject '
 
-    return (label_prefix + ", ".join(display_ranges)).strip()
+    return (label_prefix + ', '.join(display_ranges)).strip()
 
   def _get_rules(self):
     if self._rules is None:
@@ -339,9 +339,9 @@ class ExitPolicy(object):
 
       if rules and (rules[-1].is_address_wildcard() and rules[-1].is_port_wildcard()):
         if is_all_accept:
-          rules = [ExitPolicyRule("accept *:*")]
+          rules = [ExitPolicyRule('accept *:*')]
         elif is_all_reject:
-          rules = [ExitPolicyRule("reject *:*")]
+          rules = [ExitPolicyRule('reject *:*')]
 
       self._rules = rules
       self._input_rules = None
@@ -409,24 +409,24 @@ class MicroExitPolicy(ExitPolicy):
 
     self._policy = policy
 
-    if policy.startswith("accept"):
+    if policy.startswith('accept'):
       self.is_accept = True
-    elif policy.startswith("reject"):
+    elif policy.startswith('reject'):
       self.is_accept = False
     else:
       raise ValueError("A microdescriptor exit policy must start with either 'accept' or 'reject': %s" % policy)
 
     policy = policy[6:]
 
-    if not policy.startswith(" ") or (len(policy) - 1 != len(policy.lstrip())):
-      raise ValueError("A microdescriptor exit policy should have a space separating accept/reject from its port list: %s" % self._policy)
+    if not policy.startswith(' ') or (len(policy) - 1 != len(policy.lstrip())):
+      raise ValueError('A microdescriptor exit policy should have a space separating accept/reject from its port list: %s' % self._policy)
 
     policy = policy[1:]
 
     # convert our port list into MicroExitPolicyRule
     rules = []
 
-    for port_entry in policy.split(","):
+    for port_entry in policy.split(','):
       if '-' in port_entry:
         min_port, max_port = port_entry.split('-', 1)
       else:
@@ -462,7 +462,7 @@ class ExitPolicyRule(object):
 
   The format of these rules are formally described in the `dir-spec
   <https://gitweb.torproject.org/torspec.git/blob/HEAD:/dir-spec.txt>`_ as an
-  "exitpattern". Note that while these are similar to tor's man page entry for
+  'exitpattern'. Note that while these are similar to tor's man page entry for
   ExitPolicies, it's not the exact same. An exitpattern is better defined and
   stricter in what it'll accept. For instance, ports are not optional and it
   does not contain the 'private' alias.
@@ -485,21 +485,21 @@ class ExitPolicyRule(object):
     # policy ::= "accept" exitpattern | "reject" exitpattern
     # exitpattern ::= addrspec ":" portspec
 
-    if rule.startswith("accept"):
+    if rule.startswith('accept'):
       self.is_accept = True
-    elif rule.startswith("reject"):
+    elif rule.startswith('reject'):
       self.is_accept = False
     else:
       raise ValueError("An exit policy must start with either 'accept' or 'reject': %s" % rule)
 
     exitpattern = rule[6:]
 
-    if not exitpattern.startswith(" ") or (len(exitpattern) - 1 != len(exitpattern.lstrip())):
-      raise ValueError("An exit policy should have a space separating its accept/reject from the exit pattern: %s" % rule)
+    if not exitpattern.startswith(' ') or (len(exitpattern) - 1 != len(exitpattern.lstrip())):
+      raise ValueError('An exit policy should have a space separating its accept/reject from the exit pattern: %s' % rule)
 
     exitpattern = exitpattern[1:]
 
-    if not ":" in exitpattern:
+    if not ':' in exitpattern:
       raise ValueError("An exitpattern must be of the form 'addrspec:portspec': %s" % rule)
 
     self.address = None
@@ -508,13 +508,13 @@ class ExitPolicyRule(object):
     self.min_port = self.max_port = None
     self._hash = None
 
-    # Our mask in ip notation (ex. "255.255.255.0"). This is only set if we
+    # Our mask in ip notation (ex. '255.255.255.0'). This is only set if we
     # either have a custom mask that can't be represented by a number of bits,
     # or the user has called mask(), lazily loading this.
 
     self._mask = None
 
-    addrspec, portspec = exitpattern.rsplit(":", 1)
+    addrspec, portspec = exitpattern.rsplit(':', 1)
     self._apply_addrspec(rule, addrspec)
     self._apply_portspec(rule, portspec)
 
@@ -577,7 +577,7 @@ class ExitPolicyRule(object):
         if address_type == AddressType.IPv4:
           return False
 
-        address = address.lstrip("[").rstrip("]")
+        address = address.lstrip('[').rstrip(']')
       else:
         raise ValueError("'%s' isn't a valid IPv4 or IPv6 address" % address)
 
@@ -624,7 +624,7 @@ class ExitPolicyRule(object):
 
     :param bool cache: caches the result if **True**
 
-    :returns: str of our subnet mask for the address (ex. "255.255.255.0")
+    :returns: str of our subnet mask for the address (ex. '255.255.255.0')
     """
 
     # Lazy loading our mask because it very infrequently requested. There's
@@ -667,17 +667,17 @@ class ExitPolicyRule(object):
     to re-create this rule.
     """
 
-    label = "accept " if self.is_accept else "reject "
+    label = 'accept ' if self.is_accept else 'reject '
 
     if self.is_address_wildcard():
-      label += "*:"
+      label += '*:'
     else:
       address_type = self.get_address_type()
 
       if address_type == AddressType.IPv4:
         label += self.address
       else:
-        label += "[%s]" % self.address
+        label += '[%s]' % self.address
 
       # Including our mask label as follows...
       # - exclude our mask if it doesn't do anything
@@ -686,18 +686,18 @@ class ExitPolicyRule(object):
 
       if (address_type == AddressType.IPv4 and self._masked_bits == 32) or \
          (address_type == AddressType.IPv6 and self._masked_bits == 128):
-        label += ":"
+        label += ':'
       elif self._masked_bits is not None:
-        label += "/%i:" % self._masked_bits
+        label += '/%i:' % self._masked_bits
       else:
-        label += "/%s:" % self.get_mask()
+        label += '/%s:' % self.get_mask()
 
     if self.is_port_wildcard():
-      label += "*"
+      label += '*'
     elif self.min_port == self.max_port:
       label += str(self.min_port)
     else:
-      label += "%i-%i" % (self.min_port, self.max_port)
+      label += '%i-%i' % (self.min_port, self.max_port)
 
     return label
 
@@ -705,7 +705,7 @@ class ExitPolicyRule(object):
     if self._hash is None:
       my_hash = 0
 
-      for attr in ("is_accept", "address", "min_port", "max_port"):
+      for attr in ('is_accept', 'address', 'min_port', 'max_port'):
         my_hash *= 1024
 
         attr_value = getattr(self, attr)
@@ -736,12 +736,12 @@ class ExitPolicyRule(object):
     # Parses the addrspec...
     # addrspec ::= "*" | ip4spec | ip6spec
 
-    if "/" in addrspec:
-      self.address, addr_extra = addrspec.split("/", 1)
+    if '/' in addrspec:
+      self.address, addr_extra = addrspec.split('/', 1)
     else:
       self.address, addr_extra = addrspec, None
 
-    if addrspec == "*":
+    if addrspec == '*':
       self._address_type = _address_type_to_int(AddressType.WILDCARD)
       self.address = self._masked_bits = None
     elif stem.util.connection.is_valid_ipv4_address(self.address):
@@ -759,7 +759,7 @@ class ExitPolicyRule(object):
         try:
           self._masked_bits = stem.util.connection._get_masked_bits(addr_extra)
         except ValueError:
-          # mask can't be represented as a number of bits (ex. "255.255.0.255")
+          # mask can't be represented as a number of bits (ex. '255.255.0.255')
           self._mask = addr_extra
           self._masked_bits = None
       elif addr_extra.isdigit():
@@ -767,10 +767,10 @@ class ExitPolicyRule(object):
         self._masked_bits = int(addr_extra)
 
         if self._masked_bits < 0 or self._masked_bits > 32:
-          raise ValueError("IPv4 masks must be in the range of 0-32 bits")
+          raise ValueError('IPv4 masks must be in the range of 0-32 bits')
       else:
         raise ValueError("The '%s' isn't a mask nor number of bits: %s" % (addr_extra, rule))
-    elif self.address.startswith("[") and self.address.endswith("]") and \
+    elif self.address.startswith('[') and self.address.endswith(']') and \
       stem.util.connection.is_valid_ipv6_address(self.address[1:-1]):
       # ip6spec ::= ip6 | ip6 "/" num_ip6_bits
       # ip6 ::= an IPv6 address, surrounded by square brackets.
@@ -786,7 +786,7 @@ class ExitPolicyRule(object):
         self._masked_bits = int(addr_extra)
 
         if self._masked_bits < 0 or self._masked_bits > 128:
-          raise ValueError("IPv6 masks must be in the range of 0-128 bits")
+          raise ValueError('IPv6 masks must be in the range of 0-128 bits')
       else:
         raise ValueError("The '%s' isn't a number of bits: %s" % (addr_extra, rule))
     else:
@@ -800,7 +800,7 @@ class ExitPolicyRule(object):
     # Due to a tor bug the spec says that we should accept port of zero, but
     # connections to port zero are never permitted.
 
-    if portspec == "*":
+    if portspec == '*':
       self.min_port, self.max_port = 1, 65535
     elif portspec.isdigit():
       # provided with a single port
@@ -810,7 +810,7 @@ class ExitPolicyRule(object):
         raise ValueError("'%s' isn't within a valid port range: %s" % (portspec, rule))
     elif "-" in portspec:
       # provided with a port range
-      port_comp = portspec.split("-", 1)
+      port_comp = portspec.split('-', 1)
 
       if stem.util.connection.is_valid_port(port_comp, allow_zero = True):
         self.min_port = int(port_comp[0])
@@ -819,15 +819,15 @@ class ExitPolicyRule(object):
         if self.min_port > self.max_port:
           raise ValueError("Port range has a lower bound that's greater than its upper bound: %s" % rule)
       else:
-        raise ValueError("Malformed port range: %s" % rule)
+        raise ValueError('Malformed port range: %s' % rule)
     else:
       raise ValueError("Port value isn't a wildcard, integer, or range: %s" % rule)
 
   def __eq__(self, other):
     if isinstance(other, ExitPolicyRule):
       # Our string representation encompasses our effective policy. Technically
-      # this isn't quite right since our rule attribute may differ (ie, "accept
-      # 0.0.0.0/0" == "accept 0.0.0.0/0.0.0.0" will be True), but these
+      # this isn't quite right since our rule attribute may differ (ie, 'accept
+      # 0.0.0.0/0' == 'accept 0.0.0.0/0.0.0.0' will be True), but these
       # policies are effectively equivalent.
 
       return hash(self) == hash(other)
@@ -871,7 +871,7 @@ class MicroExitPolicyRule(ExitPolicyRule):
     if self._hash is None:
       my_hash = 0
 
-      for attr in ("is_accept", "min_port", "max_port"):
+      for attr in ('is_accept', 'min_port', 'max_port'):
         my_hash *= 1024
 
         attr_value = getattr(self, attr)
diff --git a/stem/interpretor/__init__.py b/stem/interpretor/__init__.py
index 5850364..d095cda 100644
--- a/stem/interpretor/__init__.py
+++ b/stem/interpretor/__init__.py
@@ -27,7 +27,7 @@ from stem.util.term import RESET, Attr, Color, format
 #
 #   http://bugs.python.org/issue12972
 
-PROMPT = format(">>> ", Color.GREEN, Attr.BOLD) + RESET * 10
+PROMPT = format('>>> ', Color.GREEN, Attr.BOLD) + RESET * 10
 
 STANDARD_OUTPUT = (Color.BLUE, )
 BOLD_OUTPUT = (Color.BLUE, Attr.BOLD)
diff --git a/stem/interpretor/commands.py b/stem/interpretor/commands.py
index ecea859..a8a5492 100644
--- a/stem/interpretor/commands.py
+++ b/stem/interpretor/commands.py
@@ -70,7 +70,7 @@ def _get_fingerprint(arg, controller):
       response = "There's multiple relays at %s, include a port to specify which.\n\n" % arg
 
       for i, or_port in enumerate(matches):
-        response += "  %i. %s:%s, fingerprint: %s\n" % (i + 1, address, or_port, matches[or_port])
+        response += '  %i. %s:%s, fingerprint: %s\n' % (i + 1, address, or_port, matches[or_port])
 
       raise ValueError(response)
   else:
diff --git a/stem/interpretor/help.py b/stem/interpretor/help.py
index caa64e0..b6b84fc 100644
--- a/stem/interpretor/help.py
+++ b/stem/interpretor/help.py
@@ -79,8 +79,8 @@ def _response(controller, arg, config):
         if ' -- ' in line:
           opt, summary = line.split(' -- ', 1)
 
-          output += format("%-33s" % opt, *BOLD_OUTPUT)
-          output += format(" - %s" % summary, *STANDARD_OUTPUT) + '\n'
+          output += format('%-33s' % opt, *BOLD_OUTPUT)
+          output += format(' - %s' % summary, *STANDARD_OUTPUT) + '\n'
   elif arg == 'GETCONF':
     results = controller.get_info('config/names', None)
 
diff --git a/stem/prereq.py b/stem/prereq.py
index 43d1dc2..2f649e2 100644
--- a/stem/prereq.py
+++ b/stem/prereq.py
@@ -43,7 +43,7 @@ def check_requirements():
   major_version, minor_version = sys.version_info[0:2]
 
   if major_version < 2 or (major_version == 2 and minor_version < 6):
-    raise ImportError("stem requires python version 2.6 or greater")
+    raise ImportError('stem requires python version 2.6 or greater')
 
 
 def is_python_27():
@@ -85,7 +85,7 @@ def is_crypto_available():
     from Crypto.Util.number import long_to_bytes
     return True
   except ImportError:
-    log.log_once("stem.prereq.is_crypto_available", log.INFO, CRYPTO_UNAVAILABLE)
+    log.log_once('stem.prereq.is_crypto_available', log.INFO, CRYPTO_UNAVAILABLE)
     return False
 
 
diff --git a/stem/process.py b/stem/process.py
index 7587372..1f5461d 100644
--- a/stem/process.py
+++ b/stem/process.py
@@ -27,11 +27,11 @@ import tempfile
 import stem.prereq
 import stem.util.system
 
-NO_TORRC = "<no torrc>"
+NO_TORRC = '<no torrc>'
 DEFAULT_INIT_TIMEOUT = 90
 
 
-def launch_tor(tor_cmd = "tor", args = None, torrc_path = None, completion_percent = 100, init_msg_handler = None, timeout = DEFAULT_INIT_TIMEOUT, take_ownership = False):
+def launch_tor(tor_cmd = 'tor', args = None, torrc_path = None, completion_percent = 100, init_msg_handler = None, timeout = DEFAULT_INIT_TIMEOUT, take_ownership = False):
   """
   Initializes a tor process. This blocks until initialization completes or we
   error out.
@@ -94,13 +94,13 @@ def launch_tor(tor_cmd = "tor", args = None, torrc_path = None, completion_perce
 
   if torrc_path:
     if torrc_path == NO_TORRC:
-      temp_file = tempfile.mkstemp(prefix = "empty-torrc-", text = True)[1]
-      runtime_args += ["-f", temp_file]
+      temp_file = tempfile.mkstemp(prefix = 'empty-torrc-', text = True)[1]
+      runtime_args += ['-f', temp_file]
     else:
-      runtime_args += ["-f", torrc_path]
+      runtime_args += ['-f', torrc_path]
 
   if take_ownership:
-    runtime_args += ["__OwningControllerProcess", str(os.getpid())]
+    runtime_args += ['__OwningControllerProcess', str(os.getpid())]
 
   tor_process = subprocess.Popen(runtime_args, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
 
@@ -115,14 +115,14 @@ def launch_tor(tor_cmd = "tor", args = None, torrc_path = None, completion_perce
 
       tor_process.kill()
 
-      raise OSError("reached a %i second timeout without success" % timeout)
+      raise OSError('reached a %i second timeout without success' % timeout)
 
     signal.signal(signal.SIGALRM, timeout_handler)
     signal.alarm(timeout)
 
-  bootstrap_line = re.compile("Bootstrapped ([0-9]+)%: ")
-  problem_line = re.compile("\[(warn|err)\] (.*)$")
-  last_problem = "Timed out"
+  bootstrap_line = re.compile('Bootstrapped ([0-9]+)%: ')
+  problem_line = re.compile('\[(warn|err)\] (.*)$')
+  last_problem = 'Timed out'
 
   while True:
     # Tor's stdout will be read as ASCII bytes. This is fine for python 2, but
@@ -132,7 +132,7 @@ def launch_tor(tor_cmd = "tor", args = None, torrc_path = None, completion_perce
     # It seems like python 2.x is perfectly happy for this to be unicode, so
     # normalizing to that.
 
-    init_line = tor_process.stdout.readline().decode("utf-8", "replace").strip()
+    init_line = tor_process.stdout.readline().decode('utf-8', 'replace').strip()
 
     # this will provide empty results if the process is terminated
     if not init_line:
@@ -143,7 +143,7 @@ def launch_tor(tor_cmd = "tor", args = None, torrc_path = None, completion_perce
 
       tor_process.kill()
 
-      raise OSError("Process terminated: %s" % last_problem)
+      raise OSError('Process terminated: %s' % last_problem)
 
     # provide the caller with the initialization message if they want it
 
@@ -168,14 +168,14 @@ def launch_tor(tor_cmd = "tor", args = None, torrc_path = None, completion_perce
     elif problem_match:
       runlevel, msg = problem_match.groups()
 
-      if not "see warnings above" in msg:
-        if ": " in msg:
-          msg = msg.split(": ")[-1].strip()
+      if not 'see warnings above' in msg:
+        if ': ' in msg:
+          msg = msg.split(': ')[-1].strip()
 
         last_problem = msg
 
 
-def launch_tor_with_config(config, tor_cmd = "tor", completion_percent = 100, init_msg_handler = None, timeout = DEFAULT_INIT_TIMEOUT, take_ownership = False):
+def launch_tor_with_config(config, tor_cmd = 'tor', completion_percent = 100, init_msg_handler = None, timeout = DEFAULT_INIT_TIMEOUT, take_ownership = False):
   """
   Initializes a tor process, like :func:`~stem.process.launch_tor`, but with a
   customized configuration. This writes a temporary torrc to disk, launches
@@ -195,7 +195,7 @@ def launch_tor_with_config(config, tor_cmd = "tor", completion_percent = 100, in
       },
     )
 
-  :param dict config: configuration options, such as '{"ControlPort": "9051"}',
+  :param dict config: configuration options, such as "{'ControlPort': '9051'}",
     values can either be a **str** or **list of str** if for multiple values
   :param str tor_cmd: command for starting tor
   :param int completion_percent: percent of bootstrap completion at which
@@ -233,16 +233,16 @@ def launch_tor_with_config(config, tor_cmd = "tor", completion_percent = 100, in
     if not has_stdout:
       config['Log'].append('NOTICE stdout')
 
-  torrc_path = tempfile.mkstemp(prefix = "torrc-", text = True)[1]
+  torrc_path = tempfile.mkstemp(prefix = 'torrc-', text = True)[1]
 
   try:
-    with open(torrc_path, "w") as torrc_file:
+    with open(torrc_path, 'w') as torrc_file:
       for key, values in config.items():
         if isinstance(values, str):
-          torrc_file.write("%s %s\n" % (key, values))
+          torrc_file.write('%s %s\n' % (key, values))
         else:
           for value in values:
-            torrc_file.write("%s %s\n" % (key, value))
+            torrc_file.write('%s %s\n' % (key, value))
 
     # prevents tor from erroring out due to a missing torrc if it gets a sighup
     args = ['__ReloadTorrcOnSIGHUP', '0']
diff --git a/stem/response/__init__.py b/stem/response/__init__.py
index 31f96e3..98684f7 100644
--- a/stem/response/__init__.py
+++ b/stem/response/__init__.py
@@ -31,15 +31,15 @@ Parses replies from the control socket.
 """
 
 __all__ = [
-  "events",
-  "getinfo",
-  "getconf",
-  "protocolinfo",
-  "authchallenge",
-  "convert",
-  "ControlMessage",
-  "ControlLine",
-  "SingleLineResponse",
+  'events',
+  'getinfo',
+  'getconf',
+  'protocolinfo',
+  'authchallenge',
+  'convert',
+  'ControlMessage',
+  'ControlLine',
+  'SingleLineResponse',
 ]
 
 import re
@@ -48,7 +48,7 @@ import threading
 
 import stem.socket
 
-KEY_ARG = re.compile("^(\S+)=")
+KEY_ARG = re.compile('^(\S+)=')
 
 # Escape sequences from the 'esc_for_log' function of tor's 'common/util.c'.
 # It's hard to tell what controller functions use this in practice, but direct
@@ -57,8 +57,8 @@ KEY_ARG = re.compile("^(\S+)=")
 # - logged messages about bugs
 # - the 'getinfo_helper_listeners' function of control.c
 
-CONTROL_ESCAPES = {r"\\": "\\", r"\"": "\"", r"\'": "'",
-                   r"\r": "\r", r"\n": "\n", r"\t": "\t"}
+CONTROL_ESCAPES = {r'\\': '\\', r'\"': '\"', r'\'': '\'',
+                   r'\r': '\r', r'\n': '\n', r'\t': '\t'}
 
 
 def convert(response_type, message, **kwargs):
@@ -107,22 +107,22 @@ def convert(response_type, message, **kwargs):
   import stem.response.mapaddress
 
   if not isinstance(message, ControlMessage):
-    raise TypeError("Only able to convert stem.response.ControlMessage instances")
+    raise TypeError('Only able to convert stem.response.ControlMessage instances')
 
   response_types = {
-    "EVENT": stem.response.events.Event,
-    "GETINFO": stem.response.getinfo.GetInfoResponse,
-    "GETCONF": stem.response.getconf.GetConfResponse,
-    "MAPADDRESS": stem.response.mapaddress.MapAddressResponse,
-    "SINGLELINE": SingleLineResponse,
-    "PROTOCOLINFO": stem.response.protocolinfo.ProtocolInfoResponse,
-    "AUTHCHALLENGE": stem.response.authchallenge.AuthChallengeResponse,
+    'EVENT': stem.response.events.Event,
+    'GETINFO': stem.response.getinfo.GetInfoResponse,
+    'GETCONF': stem.response.getconf.GetConfResponse,
+    'MAPADDRESS': stem.response.mapaddress.MapAddressResponse,
+    'SINGLELINE': SingleLineResponse,
+    'PROTOCOLINFO': stem.response.protocolinfo.ProtocolInfoResponse,
+    'AUTHCHALLENGE': stem.response.authchallenge.AuthChallengeResponse,
   }
 
   try:
     response_class = response_types[response_type]
   except TypeError:
-    raise TypeError("Unsupported response type: %s" % response_type)
+    raise TypeError('Unsupported response type: %s' % response_type)
 
   message.__class__ = response_class
   message._parse_message(**kwargs)
@@ -171,7 +171,7 @@ class ControlMessage(object):
     """
 
     for code, _, _ in self._parsed_content:
-      if code == "250":
+      if code == '250':
         return True
 
     return False
@@ -238,7 +238,7 @@ class ControlMessage(object):
     formatting.
     """
 
-    return "\n".join(list(self))
+    return '\n'.join(list(self))
 
   def __iter__(self):
     """
@@ -323,7 +323,7 @@ class ControlLine(str):
     :returns: **True** if we have additional content, **False** otherwise
     """
 
-    return self._remainder == ""
+    return self._remainder == ''
 
   def is_next_quoted(self, escaped = False):
     """
@@ -432,7 +432,7 @@ class ControlLine(str):
 
     with self._remainder_lock:
       if self.is_empty():
-        raise IndexError("no remaining content to parse")
+        raise IndexError('no remaining content to parse')
 
       key_match = KEY_ARG.match(self._remainder)
 
@@ -463,10 +463,10 @@ def _parse_entry(line, quoted, escaped):
     * **IndexError** if there's nothing to parse from the line
   """
 
-  if line == "":
-    raise IndexError("no remaining content to parse")
+  if line == '':
+    raise IndexError('no remaining content to parse')
 
-  next_entry, remainder = "", line
+  next_entry, remainder = '', line
 
   if quoted:
     # validate and parse the quoted value
@@ -478,10 +478,10 @@ def _parse_entry(line, quoted, escaped):
     next_entry, remainder = remainder[1:end_quote], remainder[end_quote + 1:]
   else:
     # non-quoted value, just need to check if there's more data afterward
-    if " " in remainder:
-      next_entry, remainder = remainder.split(" ", 1)
+    if ' ' in remainder:
+      next_entry, remainder = remainder.split(' ', 1)
     else:
-      next_entry, remainder = remainder, ""
+      next_entry, remainder = remainder, ''
 
   if escaped:
     next_entry = _unescape(next_entry)
@@ -502,13 +502,13 @@ def _get_quote_indices(line, escaped):
   indices, quote_index = [], -1
 
   for _ in range(2):
-    quote_index = line.find("\"", quote_index + 1)
+    quote_index = line.find('"', quote_index + 1)
 
     # if we have escapes then we need to skip any r'\"' entries
     if escaped:
       # skip check if index is -1 (no match) or 0 (first character)
-      while quote_index >= 1 and line[quote_index - 1] == "\\":
-        quote_index = line.find("\"", quote_index + 1)
+      while quote_index >= 1 and line[quote_index - 1] == '\\':
+        quote_index = line.find('"', quote_index + 1)
 
     indices.append(quote_index)
 
@@ -540,7 +540,7 @@ def _unescape(entry):
     prefix, entry = _pop_with_unescape(entry)
     result.append(prefix)
 
-  return "".join(result)
+  return ''.join(result)
 
 
 class SingleLineResponse(ControlMessage):
@@ -566,15 +566,16 @@ class SingleLineResponse(ControlMessage):
     """
 
     if strict:
-      return self.content()[0] == ("250", " ", "OK")
-    return self.content()[0][0] == "250"
+      return self.content()[0] == ('250', ' ', 'OK')
+
+    return self.content()[0][0] == '250'
 
   def _parse_message(self):
     content = self.content()
 
     if len(content) > 1:
-      raise stem.ProtocolError("Received multi-line response")
+      raise stem.ProtocolError('Received multi-line response')
     elif len(content) == 0:
-      raise stem.ProtocolError("Received empty response")
+      raise stem.ProtocolError('Received empty response')
     else:
       self.code, _, self.message = content[0]
diff --git a/stem/response/authchallenge.py b/stem/response/authchallenge.py
index 2f22c2b..2113ffd 100644
--- a/stem/response/authchallenge.py
+++ b/stem/response/authchallenge.py
@@ -27,30 +27,30 @@ class AuthChallengeResponse(stem.response.ControlMessage):
     if not self.is_ok():
       raise stem.ProtocolError("AUTHCHALLENGE response didn't have an OK status:\n%s" % self)
     elif len(self) > 1:
-      raise stem.ProtocolError("Received multiline AUTHCHALLENGE response:\n%s" % self)
+      raise stem.ProtocolError('Received multiline AUTHCHALLENGE response:\n%s' % self)
 
     line = self[0]
 
     # sanity check that we're a AUTHCHALLENGE response
-    if not line.pop() == "AUTHCHALLENGE":
-      raise stem.ProtocolError("Message is not an AUTHCHALLENGE response (%s)" % self)
+    if not line.pop() == 'AUTHCHALLENGE':
+      raise stem.ProtocolError('Message is not an AUTHCHALLENGE response (%s)' % self)
 
-    if line.is_next_mapping("SERVERHASH"):
+    if line.is_next_mapping('SERVERHASH'):
       value = line.pop_mapping()[1]
 
       if not stem.util.tor_tools.is_hex_digits(value, 64):
-        raise stem.ProtocolError("SERVERHASH has an invalid value: %s" % value)
+        raise stem.ProtocolError('SERVERHASH has an invalid value: %s' % value)
 
       self.server_hash = binascii.a2b_hex(stem.util.str_tools._to_bytes(value))
     else:
-      raise stem.ProtocolError("Missing SERVERHASH mapping: %s" % line)
+      raise stem.ProtocolError('Missing SERVERHASH mapping: %s' % line)
 
-    if line.is_next_mapping("SERVERNONCE"):
+    if line.is_next_mapping('SERVERNONCE'):
       value = line.pop_mapping()[1]
 
       if not stem.util.tor_tools.is_hex_digits(value, 64):
-        raise stem.ProtocolError("SERVERNONCE has an invalid value: %s" % value)
+        raise stem.ProtocolError('SERVERNONCE has an invalid value: %s' % value)
 
       self.server_nonce = binascii.a2b_hex(stem.util.str_tools._to_bytes(value))
     else:
-      raise stem.ProtocolError("Missing SERVERNONCE mapping: %s" % line)
+      raise stem.ProtocolError('Missing SERVERNONCE mapping: %s' % line)
diff --git a/stem/response/events.py b/stem/response/events.py
index 9f1b628..773769f 100644
--- a/stem/response/events.py
+++ b/stem/response/events.py
@@ -18,9 +18,9 @@ from stem.util import connection, log, str_tools, tor_tools
 # because some positional arguments, like circuit paths, can have an equal
 # sign.
 
-KW_ARG = re.compile("^(.*) ([A-Za-z0-9_]+)=(\S*)$")
-QUOTED_KW_ARG = re.compile("^(.*) ([A-Za-z0-9_]+)=\"(.*)\"$")
-CELL_TYPE = re.compile("^[a-z0-9_]+$")
+KW_ARG = re.compile('^(.*) ([A-Za-z0-9_]+)=(\S*)$')
+QUOTED_KW_ARG = re.compile('^(.*) ([A-Za-z0-9_]+)="(.*)"$')
+CELL_TYPE = re.compile('^[a-z0-9_]+$')
 
 
 class Event(stem.response.ControlMessage):
@@ -47,7 +47,7 @@ class Event(stem.response.ControlMessage):
       arrived_at = int(time.time())
 
     if not str(self).strip():
-      raise stem.ProtocolError("Received a blank tor event. Events must at the very least have a type.")
+      raise stem.ProtocolError('Received a blank tor event. Events must at the very least have a type.')
 
     self.type = str(self).split().pop(0)
     self.arrived_at = arrived_at
@@ -117,7 +117,7 @@ class Event(stem.response.ControlMessage):
             if attr_values[-1].endswith('"'):
               break
 
-          attr_value = " ".join(attr_values)[1:-1]
+          attr_value = ' '.join(attr_values)[1:-1]
         else:
           attr_value = positional.pop(0)
 
@@ -147,7 +147,7 @@ class Event(stem.response.ControlMessage):
 
       for value in attr_values:
         if not value in attr_enum:
-          log_id = "event.%s.unknown_%s.%s" % (self.type.lower(), attr, value)
+          log_id = 'event.%s.unknown_%s.%s' % (self.type.lower(), attr, value)
           unrecognized_msg = "%s event had an unrecognized %s (%s). Maybe a new addition to the control protocol? Full Event: '%s'" % (self.type, attr, value, self)
           log.log_once(log_id, log.INFO, unrecognized_msg)
 
@@ -173,34 +173,34 @@ class AddrMapEvent(Event):
     **False** otherwise or **None** if undefined
   """
 
-  _POSITIONAL_ARGS = ("hostname", "destination", "expiry")
+  _POSITIONAL_ARGS = ('hostname', 'destination', 'expiry')
   _KEYWORD_ARGS = {
-    "error": "error",
-    "EXPIRES": "utc_expiry",
-    "CACHED": "cached",
+    'error': 'error',
+    'EXPIRES': 'utc_expiry',
+    'CACHED': 'cached',
   }
-  _OPTIONALLY_QUOTED = ("expiry")
+  _OPTIONALLY_QUOTED = ('expiry')
 
   def _parse(self):
-    if self.destination == "<error>":
+    if self.destination == '<error>':
       self.destination = None
 
     if self.expiry is not None:
-      if self.expiry == "NEVER":
+      if self.expiry == 'NEVER':
         self.expiry = None
       else:
         try:
-          self.expiry = datetime.datetime.strptime(self.expiry, "%Y-%m-%d %H:%M:%S")
+          self.expiry = datetime.datetime.strptime(self.expiry, '%Y-%m-%d %H:%M:%S')
         except ValueError:
-          raise stem.ProtocolError("Unable to parse date in ADDRMAP event: %s" % self)
+          raise stem.ProtocolError('Unable to parse date in ADDRMAP event: %s' % self)
 
     if self.utc_expiry is not None:
-      self.utc_expiry = datetime.datetime.strptime(self.utc_expiry, "%Y-%m-%d %H:%M:%S")
+      self.utc_expiry = datetime.datetime.strptime(self.utc_expiry, '%Y-%m-%d %H:%M:%S')
 
     if self.cached is not None:
-      if self.cached == "YES":
+      if self.cached == 'YES':
         self.cached = True
-      elif self.cached == "NO":
+      elif self.cached == 'NO':
         self.cached = False
       else:
         raise stem.ProtocolError("An ADDRMAP event's CACHED mapping can only be 'YES' or 'NO': %s" % self)
@@ -227,7 +227,7 @@ class AuthDirNewDescEvent(Event):
 
     if len(lines) < 5:
       raise stem.ProtocolError("AUTHDIR_NEWDESCS events must contain lines for at least the type, action, message, descriptor, and terminating 'OK'")
-    elif not lines[-1] == "OK":
+    elif not lines[-1] == 'OK':
       raise stem.ProtocolError("AUTHDIR_NEWDESCS doesn't end with an 'OK'")
 
     self.action = lines[1]
@@ -246,13 +246,13 @@ class BandwidthEvent(Event):
   :var long written: bytes sent by tor that second
   """
 
-  _POSITIONAL_ARGS = ("read", "written")
+  _POSITIONAL_ARGS = ('read', 'written')
 
   def _parse(self):
     if not self.read:
-      raise stem.ProtocolError("BW event is missing its read value")
+      raise stem.ProtocolError('BW event is missing its read value')
     elif not self.written:
-      raise stem.ProtocolError("BW event is missing its written value")
+      raise stem.ProtocolError('BW event is missing its written value')
     elif not self.read.isdigit() or not self.written.isdigit():
       raise stem.ProtocolError("A BW event's bytes sent and received should be a positive numeric value, received: %s" % self)
 
@@ -278,16 +278,16 @@ class BuildTimeoutSetEvent(Event):
   :var float close_rate: ratio of measurement circuits that are closed
   """
 
-  _POSITIONAL_ARGS = ("set_type",)
+  _POSITIONAL_ARGS = ('set_type',)
   _KEYWORD_ARGS = {
-    "TOTAL_TIMES": "total_times",
-    "TIMEOUT_MS": "timeout",
-    "XM": "xm",
-    "ALPHA": "alpha",
-    "CUTOFF_QUANTILE": "quantile",
-    "TIMEOUT_RATE": "timeout_rate",
-    "CLOSE_MS": "close_timeout",
-    "CLOSE_RATE": "close_rate",
+    'TOTAL_TIMES': 'total_times',
+    'TIMEOUT_MS': 'timeout',
+    'XM': 'xm',
+    'ALPHA': 'alpha',
+    'CUTOFF_QUANTILE': 'quantile',
+    'TIMEOUT_RATE': 'timeout_rate',
+    'CLOSE_MS': 'close_timeout',
+    'CLOSE_RATE': 'close_rate',
   }
   _VERSION_ADDED = stem.version.Requirement.EVENT_BUILDTIMEOUT_SET
 
@@ -301,7 +301,7 @@ class BuildTimeoutSetEvent(Event):
         try:
           setattr(self, param, int(param_value))
         except ValueError:
-          raise stem.ProtocolError("The %s of a BUILDTIMEOUT_SET should be an integer: %s" % (param, self))
+          raise stem.ProtocolError('The %s of a BUILDTIMEOUT_SET should be an integer: %s' % (param, self))
 
     for param in ('alpha', 'quantile', 'timeout_rate', 'close_rate'):
       param_value = getattr(self, param)
@@ -310,7 +310,7 @@ class BuildTimeoutSetEvent(Event):
         try:
           setattr(self, param, float(param_value))
         except ValueError:
-          raise stem.ProtocolError("The %s of a BUILDTIMEOUT_SET should be a float: %s" % (param, self))
+          raise stem.ProtocolError('The %s of a BUILDTIMEOUT_SET should be a float: %s' % (param, self))
 
     self._log_if_unrecognized('set_type', stem.TimeoutSetType)
 
@@ -340,15 +340,15 @@ class CircuitEvent(Event):
   :var stem.CircClosureReason remote_reason: remote side's reason for the circuit to be closed
   """
 
-  _POSITIONAL_ARGS = ("id", "status", "path")
+  _POSITIONAL_ARGS = ('id', 'status', 'path')
   _KEYWORD_ARGS = {
-    "BUILD_FLAGS": "build_flags",
-    "PURPOSE": "purpose",
-    "HS_STATE": "hs_state",
-    "REND_QUERY": "rend_query",
-    "TIME_CREATED": "created",
-    "REASON": "reason",
-    "REMOTE_REASON": "remote_reason",
+    'BUILD_FLAGS': 'build_flags',
+    'PURPOSE': 'purpose',
+    'HS_STATE': 'hs_state',
+    'REND_QUERY': 'rend_query',
+    'TIME_CREATED': 'created',
+    'REASON': 'reason',
+    'REMOTE_REASON': 'remote_reason',
   }
 
   def _parse(self):
@@ -361,7 +361,7 @@ class CircuitEvent(Event):
       try:
         self.created = str_tools._parse_iso_timestamp(self.created)
       except ValueError as exc:
-        raise stem.ProtocolError("Unable to parse create date (%s): %s" % (exc, self))
+        raise stem.ProtocolError('Unable to parse create date (%s): %s' % (exc, self))
 
     if not tor_tools.is_valid_circuit_id(self.id):
       raise stem.ProtocolError("Circuit IDs must be one to sixteen alphanumeric characters, got '%s': %s" % (self.id, self))
@@ -432,15 +432,15 @@ class CircMinorEvent(Event):
   :var stem.HiddenServiceState old_hs_state: prior status as a hidden service circuit
   """
 
-  _POSITIONAL_ARGS = ("id", "event", "path")
+  _POSITIONAL_ARGS = ('id', 'event', 'path')
   _KEYWORD_ARGS = {
-    "BUILD_FLAGS": "build_flags",
-    "PURPOSE": "purpose",
-    "HS_STATE": "hs_state",
-    "REND_QUERY": "rend_query",
-    "TIME_CREATED": "created",
-    "OLD_PURPOSE": "old_purpose",
-    "OLD_HS_STATE": "old_hs_state",
+    'BUILD_FLAGS': 'build_flags',
+    'PURPOSE': 'purpose',
+    'HS_STATE': 'hs_state',
+    'REND_QUERY': 'rend_query',
+    'TIME_CREATED': 'created',
+    'OLD_PURPOSE': 'old_purpose',
+    'OLD_HS_STATE': 'old_hs_state',
   }
   _VERSION_ADDED = stem.version.Requirement.EVENT_CIRC_MINOR
 
@@ -454,7 +454,7 @@ class CircMinorEvent(Event):
       try:
         self.created = str_tools._parse_iso_timestamp(self.created)
       except ValueError as exc:
-        raise stem.ProtocolError("Unable to parse create date (%s): %s" % (exc, self))
+        raise stem.ProtocolError('Unable to parse create date (%s): %s' % (exc, self))
 
     if not tor_tools.is_valid_circuit_id(self.id):
       raise stem.ProtocolError("Circuit IDs must be one to sixteen alphanumeric characters, got '%s': %s" % (self.id, self))
@@ -479,15 +479,15 @@ class ClientsSeenEvent(Event):
   """
 
   _KEYWORD_ARGS = {
-    "TimeStarted": "start_time",
-    "CountrySummary": "locales",
-    "IPVersions": "ip_versions",
+    'TimeStarted': 'start_time',
+    'CountrySummary': 'locales',
+    'IPVersions': 'ip_versions',
   }
   _VERSION_ADDED = stem.version.Requirement.EVENT_CLIENTS_SEEN
 
   def _parse(self):
     if self.start_time is not None:
-      self.start_time = datetime.datetime.strptime(self.start_time, "%Y-%m-%d %H:%M:%S")
+      self.start_time = datetime.datetime.strptime(self.start_time, '%Y-%m-%d %H:%M:%S')
 
     if self.locales is not None:
       locale_to_count = {}
@@ -501,7 +501,7 @@ class ClientsSeenEvent(Event):
         if len(locale) != 2:
           raise stem.ProtocolError("Locales should be a two character code, got '%s': %s" % (locale, self))
         elif not count.isdigit():
-          raise stem.ProtocolError("Locale count was non-numeric (%s): %s" % (count, self))
+          raise stem.ProtocolError('Locale count was non-numeric (%s): %s' % (count, self))
         elif locale in locale_to_count:
           raise stem.ProtocolError("CountrySummary had multiple mappings for '%s': %s" % (locale, self))
 
@@ -519,7 +519,7 @@ class ClientsSeenEvent(Event):
         protocol, count = entry.split('=', 1)
 
         if not count.isdigit():
-          raise stem.ProtocolError("IP protocol count was non-numeric (%s): %s" % (count, self))
+          raise stem.ProtocolError('IP protocol count was non-numeric (%s): %s' % (count, self))
 
         protocol_to_count[protocol] = int(count)
 
@@ -591,7 +591,7 @@ class GuardEvent(Event):
   """
 
   _VERSION_ADDED = stem.version.Requirement.EVENT_GUARD
-  _POSITIONAL_ARGS = ("guard_type", "endpoint", "status")
+  _POSITIONAL_ARGS = ('guard_type', 'endpoint', 'status')
 
   def _parse(self):
     self.endpoint_fingerprint = None
@@ -625,7 +625,7 @@ class HSDescEvent(Event):
   """
 
   _VERSION_ADDED = stem.version.Requirement.EVENT_HS_DESC
-  _POSITIONAL_ARGS = ("action", "address", "authentication", "directory", "descriptor_id")
+  _POSITIONAL_ARGS = ('action', 'address', 'authentication', 'directory', 'descriptor_id')
 
   def _parse(self):
     self.directory_fingerprint = None
@@ -662,7 +662,7 @@ class LogEvent(Event):
     # message is our content, minus the runlevel and ending "OK" if a
     # multi-line message
 
-    self.message = str(self)[len(self.runlevel) + 1:].rstrip("\nOK")
+    self.message = str(self)[len(self.runlevel) + 1:].rstrip('\nOK')
 
 
 class NetworkStatusEvent(Event):
@@ -679,7 +679,7 @@ class NetworkStatusEvent(Event):
   _VERSION_ADDED = stem.version.Requirement.EVENT_NS
 
   def _parse(self):
-    content = str(self).lstrip("NS\n").rstrip("\nOK")
+    content = str(self).lstrip('NS\n').rstrip('\nOK')
 
     self.desc = list(stem.descriptor.router_status_entry._parse_file(
       io.BytesIO(str_tools._to_bytes(content)),
@@ -704,7 +704,7 @@ class NewConsensusEvent(Event):
   _VERSION_ADDED = stem.version.Requirement.EVENT_NEWCONSENSUS
 
   def _parse(self):
-    content = str(self).lstrip("NEWCONSENSUS\n").rstrip("\nOK")
+    content = str(self).lstrip('NEWCONSENSUS\n').rstrip('\nOK')
 
     self.desc = list(stem.descriptor.router_status_entry._parse_file(
       io.BytesIO(str_tools._to_bytes(content)),
@@ -762,11 +762,11 @@ class ORConnEvent(Event):
   :var int circ_count: number of established and pending circuits
   """
 
-  _POSITIONAL_ARGS = ("endpoint", "status")
+  _POSITIONAL_ARGS = ('endpoint', 'status')
   _KEYWORD_ARGS = {
-    "REASON": "reason",
-    "NCIRCS": "circ_count",
-    "ID": "id",
+    'REASON': 'reason',
+    'NCIRCS': 'circ_count',
+    'ID': 'id',
   }
 
   def _parse(self):
@@ -792,7 +792,7 @@ class ORConnEvent(Event):
 
     if self.circ_count is not None:
       if not self.circ_count.isdigit():
-        raise stem.ProtocolError("ORCONN event got a non-numeric circuit count (%s): %s" % (self.circ_count, self))
+        raise stem.ProtocolError('ORCONN event got a non-numeric circuit count (%s): %s' % (self.circ_count, self))
 
       self.circ_count = int(self.circ_count)
 
@@ -820,7 +820,7 @@ class SignalEvent(Event):
   :var stem.Signal signal: signal that tor received
   """
 
-  _POSITIONAL_ARGS = ("signal",)
+  _POSITIONAL_ARGS = ('signal',)
   _VERSION_ADDED = stem.version.Requirement.EVENT_SIGNAL
 
   def _parse(self):
@@ -851,7 +851,7 @@ class StatusEvent(Event):
   :var str message: logged message
   """
 
-  _POSITIONAL_ARGS = ("runlevel", "action")
+  _POSITIONAL_ARGS = ('runlevel', 'action')
   _VERSION_ADDED = stem.version.Requirement.EVENT_STATUS
 
   def _parse(self):
@@ -889,13 +889,13 @@ class StreamEvent(Event):
   :var stem.StreamPurpose purpose: purpose for the stream
   """
 
-  _POSITIONAL_ARGS = ("id", "status", "circ_id", "target")
+  _POSITIONAL_ARGS = ('id', 'status', 'circ_id', 'target')
   _KEYWORD_ARGS = {
-    "REASON": "reason",
-    "REMOTE_REASON": "remote_reason",
-    "SOURCE": "source",
-    "SOURCE_ADDR": "source_addr",
-    "PURPOSE": "purpose",
+    'REASON': 'reason',
+    'REMOTE_REASON': 'remote_reason',
+    'SOURCE': 'source',
+    'SOURCE_ADDR': 'source_addr',
+    'PURPOSE': 'purpose',
   }
 
   def _parse(self):
@@ -930,7 +930,7 @@ class StreamEvent(Event):
 
     # spec specifies a circ_id of zero if the stream is unattached
 
-    if self.circ_id == "0":
+    if self.circ_id == '0':
       self.circ_id = None
 
     self._log_if_unrecognized('reason', stem.StreamClosureReason)
@@ -950,16 +950,16 @@ class StreamBwEvent(Event):
   :var long read: bytes received by the application
   """
 
-  _POSITIONAL_ARGS = ("id", "written", "read")
+  _POSITIONAL_ARGS = ('id', 'written', 'read')
   _VERSION_ADDED = stem.version.Requirement.EVENT_STREAM_BW
 
   def _parse(self):
     if not tor_tools.is_valid_stream_id(self.id):
       raise stem.ProtocolError("Stream IDs must be one to sixteen alphanumeric characters, got '%s': %s" % (self.id, self))
     elif not self.written:
-      raise stem.ProtocolError("STREAM_BW event is missing its written value")
+      raise stem.ProtocolError('STREAM_BW event is missing its written value')
     elif not self.read:
-      raise stem.ProtocolError("STREAM_BW event is missing its read value")
+      raise stem.ProtocolError('STREAM_BW event is missing its read value')
     elif not self.read.isdigit() or not self.written.isdigit():
       raise stem.ProtocolError("A STREAM_BW event's bytes sent and received should be a positive numeric value, received: %s" % self)
 
@@ -982,7 +982,7 @@ class TransportLaunchedEvent(Event):
   :var int port: port where the transport is listening for connections
   """
 
-  _POSITIONAL_ARGS = ("type", "name", "address", "port")
+  _POSITIONAL_ARGS = ('type', 'name', 'address', 'port')
   _VERSION_ADDED = stem.version.Requirement.EVENT_TRANSPORT_LAUNCHED
 
   def _parse(self):
@@ -994,7 +994,7 @@ class TransportLaunchedEvent(Event):
       raise stem.ProtocolError("Transport address isn't a valid IPv4 or IPv6 address: %s" % self)
 
     if not connection.is_valid_port(self.port):
-      raise stem.ProtocolError("Transport port is invalid: %s" % self)
+      raise stem.ProtocolError('Transport port is invalid: %s' % self)
 
     self.port = int(self.port)
 
@@ -1015,23 +1015,23 @@ class ConnectionBandwidthEvent(Event):
   """
 
   _KEYWORD_ARGS = {
-    "ID": "id",
-    "TYPE": "type",
-    "READ": "read",
-    "WRITTEN": "written",
+    'ID': 'id',
+    'TYPE': 'type',
+    'READ': 'read',
+    'WRITTEN': 'written',
   }
 
   _VERSION_ADDED = stem.version.Requirement.EVENT_CONN_BW
 
   def _parse(self):
     if not self.id:
-      raise stem.ProtocolError("CONN_BW event is missing its id")
+      raise stem.ProtocolError('CONN_BW event is missing its id')
     elif not self.type:
-      raise stem.ProtocolError("CONN_BW event is missing its type")
+      raise stem.ProtocolError('CONN_BW event is missing its type')
     elif not self.read:
-      raise stem.ProtocolError("CONN_BW event is missing its read value")
+      raise stem.ProtocolError('CONN_BW event is missing its read value')
     elif not self.written:
-      raise stem.ProtocolError("CONN_BW event is missing its written value")
+      raise stem.ProtocolError('CONN_BW event is missing its written value')
     elif not self.read.isdigit() or not self.written.isdigit():
       raise stem.ProtocolError("A CONN_BW event's bytes sent and received should be a positive numeric value, received: %s" % self)
     elif not tor_tools.is_valid_connection_id(self.id):
@@ -1058,20 +1058,20 @@ class CircuitBandwidthEvent(Event):
   """
 
   _KEYWORD_ARGS = {
-    "ID": "id",
-    "READ": "read",
-    "WRITTEN": "written",
+    'ID': 'id',
+    'READ': 'read',
+    'WRITTEN': 'written',
   }
 
   _VERSION_ADDED = stem.version.Requirement.EVENT_CIRC_BW
 
   def _parse(self):
     if not self.id:
-      raise stem.ProtocolError("CIRC_BW event is missing its id")
+      raise stem.ProtocolError('CIRC_BW event is missing its id')
     elif not self.read:
-      raise stem.ProtocolError("CIRC_BW event is missing its read value")
+      raise stem.ProtocolError('CIRC_BW event is missing its read value')
     elif not self.written:
-      raise stem.ProtocolError("CIRC_BW event is missing its written value")
+      raise stem.ProtocolError('CIRC_BW event is missing its written value')
     elif not self.read.isdigit() or not self.written.isdigit():
       raise stem.ProtocolError("A CIRC_BW event's bytes sent and received should be a positive numeric value, received: %s" % self)
     elif not tor_tools.is_valid_circuit_id(self.id):
@@ -1105,17 +1105,17 @@ class CellStatsEvent(Event):
   """
 
   _KEYWORD_ARGS = {
-    "ID": "id",
-    "InboundQueue": "inbound_queue",
-    "InboundConn": "inbound_connection",
-    "InboundAdded": "inbound_added",
-    "InboundRemoved": "inbound_removed",
-    "InboundTime": "inbound_time",
-    "OutboundQueue": "outbound_queue",
-    "OutboundConn": "outbound_connection",
-    "OutboundAdded": "outbound_added",
-    "OutboundRemoved": "outbound_removed",
-    "OutboundTime": "outbound_time",
+    'ID': 'id',
+    'InboundQueue': 'inbound_queue',
+    'InboundConn': 'inbound_connection',
+    'InboundAdded': 'inbound_added',
+    'InboundRemoved': 'inbound_removed',
+    'InboundTime': 'inbound_time',
+    'OutboundQueue': 'outbound_queue',
+    'OutboundConn': 'outbound_connection',
+    'OutboundAdded': 'outbound_added',
+    'OutboundRemoved': 'outbound_removed',
+    'OutboundTime': 'outbound_time',
   }
 
   _VERSION_ADDED = stem.version.Requirement.EVENT_CELL_STATS
@@ -1156,12 +1156,12 @@ class TokenBucketEmptyEvent(Event):
   :var int last_refill: time in milliseconds the bucket has been empty since last refilled
   """
 
-  _POSITIONAL_ARGS = ("bucket",)
+  _POSITIONAL_ARGS = ('bucket',)
   _KEYWORD_ARGS = {
-    "ID": "id",
-    "READ": "read",
-    "WRITTEN": "written",
-    "LAST": "last_refill",
+    'ID': 'id',
+    'READ': 'read',
+    'WRITTEN': 'written',
+    'LAST': 'last_refill',
   }
 
   _VERSION_ADDED = stem.version.Requirement.EVENT_TB_EMPTY
@@ -1220,38 +1220,38 @@ def _parse_cell_type_mapping(mapping):
 
 
 EVENT_TYPE_TO_CLASS = {
-  "ADDRMAP": AddrMapEvent,
-  "AUTHDIR_NEWDESCS": AuthDirNewDescEvent,
-  "BUILDTIMEOUT_SET": BuildTimeoutSetEvent,
-  "BW": BandwidthEvent,
-  "CELL_STATS": CellStatsEvent,
-  "CIRC": CircuitEvent,
-  "CIRC_BW": CircuitBandwidthEvent,
-  "CIRC_MINOR": CircMinorEvent,
-  "CLIENTS_SEEN": ClientsSeenEvent,
-  "CONF_CHANGED": ConfChangedEvent,
-  "CONN_BW": ConnectionBandwidthEvent,
-  "DEBUG": LogEvent,
-  "DESCCHANGED": DescChangedEvent,
-  "ERR": LogEvent,
-  "GUARD": GuardEvent,
-  "HS_DESC": HSDescEvent,
-  "INFO": LogEvent,
-  "NEWCONSENSUS": NewConsensusEvent,
-  "NEWDESC": NewDescEvent,
-  "NOTICE": LogEvent,
-  "NS": NetworkStatusEvent,
-  "ORCONN": ORConnEvent,
-  "SIGNAL": SignalEvent,
-  "STATUS_CLIENT": StatusEvent,
-  "STATUS_GENERAL": StatusEvent,
-  "STATUS_SERVER": StatusEvent,
-  "STREAM": StreamEvent,
-  "STREAM_BW": StreamBwEvent,
-  "TB_EMPTY": TokenBucketEmptyEvent,
-  "TRANSPORT_LAUNCHED": TransportLaunchedEvent,
-  "WARN": LogEvent,
+  'ADDRMAP': AddrMapEvent,
+  'AUTHDIR_NEWDESCS': AuthDirNewDescEvent,
+  'BUILDTIMEOUT_SET': BuildTimeoutSetEvent,
+  'BW': BandwidthEvent,
+  'CELL_STATS': CellStatsEvent,
+  'CIRC': CircuitEvent,
+  'CIRC_BW': CircuitBandwidthEvent,
+  'CIRC_MINOR': CircMinorEvent,
+  'CLIENTS_SEEN': ClientsSeenEvent,
+  'CONF_CHANGED': ConfChangedEvent,
+  'CONN_BW': ConnectionBandwidthEvent,
+  'DEBUG': LogEvent,
+  'DESCCHANGED': DescChangedEvent,
+  'ERR': LogEvent,
+  'GUARD': GuardEvent,
+  'HS_DESC': HSDescEvent,
+  'INFO': LogEvent,
+  'NEWCONSENSUS': NewConsensusEvent,
+  'NEWDESC': NewDescEvent,
+  'NOTICE': LogEvent,
+  'NS': NetworkStatusEvent,
+  'ORCONN': ORConnEvent,
+  'SIGNAL': SignalEvent,
+  'STATUS_CLIENT': StatusEvent,
+  'STATUS_GENERAL': StatusEvent,
+  'STATUS_SERVER': StatusEvent,
+  'STREAM': StreamEvent,
+  'STREAM_BW': StreamBwEvent,
+  'TB_EMPTY': TokenBucketEmptyEvent,
+  'TRANSPORT_LAUNCHED': TransportLaunchedEvent,
+  'WARN': LogEvent,
 
   # accounting for a bug in tor 0.2.0.22
-  "STATUS_SEVER": StatusEvent,
+  'STATUS_SEVER': StatusEvent,
 }
diff --git a/stem/response/getconf.py b/stem/response/getconf.py
index 0eaafcb..72f91af 100644
--- a/stem/response/getconf.py
+++ b/stem/response/getconf.py
@@ -10,7 +10,7 @@ class GetConfResponse(stem.response.ControlMessage):
   Reply for a GETCONF query.
 
   Note that configuration parameters won't match what we queried for if it's one
-  of the special mapping options (ex. "HiddenServiceOptions").
+  of the special mapping options (ex. 'HiddenServiceOptions').
 
   :var dict entries: mapping between the config parameter (**str**) and their
     values (**list** of **str**)
@@ -26,25 +26,25 @@ class GetConfResponse(stem.response.ControlMessage):
     self.entries = {}
     remaining_lines = list(self)
 
-    if self.content() == [("250", " ", "OK")]:
+    if self.content() == [('250', ' ', 'OK')]:
       return
 
     if not self.is_ok():
       unrecognized_keywords = []
       for code, _, line in self.content():
-        if code == "552" and line.startswith("Unrecognized configuration key \"") and line.endswith("\""):
+        if code == '552' and line.startswith('Unrecognized configuration key "') and line.endswith('"'):
           unrecognized_keywords.append(line[32:-1])
 
       if unrecognized_keywords:
-        raise stem.InvalidArguments("552", "GETCONF request contained unrecognized keywords: %s" % ', '.join(unrecognized_keywords), unrecognized_keywords)
+        raise stem.InvalidArguments('552', 'GETCONF request contained unrecognized keywords: %s' % ', '.join(unrecognized_keywords), unrecognized_keywords)
       else:
-        raise stem.ProtocolError("GETCONF response contained a non-OK status code:\n%s" % self)
+        raise stem.ProtocolError('GETCONF response contained a non-OK status code:\n%s' % self)
 
     while remaining_lines:
       line = remaining_lines.pop(0)
 
       if line.is_next_mapping():
-        key, value = line.split("=", 1)
+        key, value = line.split('=', 1)
       else:
         key, value = (line.pop(), None)
 
diff --git a/stem/response/getinfo.py b/stem/response/getinfo.py
index 4cced1b..6adfb62 100644
--- a/stem/response/getinfo.py
+++ b/stem/response/getinfo.py
@@ -28,22 +28,22 @@ class GetInfoResponse(stem.response.ControlMessage):
     self.entries = {}
     remaining_lines = [content for (code, div, content) in self.content(get_bytes = True)]
 
-    if not self.is_ok() or not remaining_lines.pop() == b"OK":
+    if not self.is_ok() or not remaining_lines.pop() == b'OK':
       unrecognized_keywords = []
       for code, _, line in self.content():
-        if code == '552' and line.startswith("Unrecognized key \"") and line.endswith("\""):
+        if code == '552' and line.startswith('Unrecognized key "') and line.endswith('"'):
           unrecognized_keywords.append(line[18:-1])
 
       if unrecognized_keywords:
-        raise stem.InvalidArguments("552", "GETINFO request contained unrecognized keywords: %s\n" % ', '.join(unrecognized_keywords), unrecognized_keywords)
+        raise stem.InvalidArguments('552', 'GETINFO request contained unrecognized keywords: %s\n' % ', '.join(unrecognized_keywords), unrecognized_keywords)
       else:
         raise stem.ProtocolError("GETINFO response didn't have an OK status:\n%s" % self)
 
     while remaining_lines:
       try:
-        key, value = remaining_lines.pop(0).split(b"=", 1)
+        key, value = remaining_lines.pop(0).split(b'=', 1)
       except ValueError:
-        raise stem.ProtocolError("GETINFO replies should only contain parameter=value mappings:\n%s" % self)
+        raise stem.ProtocolError('GETINFO replies should only contain parameter=value mappings:\n%s' % self)
 
       if stem.prereq.is_python_3():
         key = stem.util.str_tools._to_unicode(key)
@@ -51,8 +51,8 @@ class GetInfoResponse(stem.response.ControlMessage):
       # if the value is a multiline value then it *must* be of the form
       # '<key>=\n<value>'
 
-      if b"\n" in value:
-        if not value.startswith(b"\n"):
+      if b'\n' in value:
+        if not value.startswith(b'\n'):
           raise stem.ProtocolError("GETINFO response contained a multi-line value that didn't start with a newline:\n%s" % self)
 
         value = value[1:]
@@ -72,7 +72,7 @@ class GetInfoResponse(stem.response.ControlMessage):
     reply_params = set(self.entries.keys())
 
     if params != reply_params:
-      requested_label = ", ".join(params)
-      reply_label = ", ".join(reply_params)
+      requested_label = ', '.join(params)
+      reply_label = ', '.join(reply_params)
 
       raise stem.ProtocolError("GETINFO reply doesn't match the parameters that we requested. Queried '%s' but got '%s'." % (requested_label, reply_label))
diff --git a/stem/response/mapaddress.py b/stem/response/mapaddress.py
index 79428e1..e5a26a7 100644
--- a/stem/response/mapaddress.py
+++ b/stem/response/mapaddress.py
@@ -24,19 +24,19 @@ class MapAddressResponse(stem.response.ControlMessage):
 
     if not self.is_ok():
       for code, _, message in self.content():
-        if code == "512":
+        if code == '512':
           raise stem.InvalidRequest(code, message)
-        elif code == "451":
+        elif code == '451':
           raise stem.OperationFailed(code, message)
         else:
-          raise stem.ProtocolError("MAPADDRESS returned unexpected response code: %s", code)
+          raise stem.ProtocolError('MAPADDRESS returned unexpected response code: %s', code)
 
     self.entries = {}
 
     for code, _, message in self.content():
-      if code == "250":
+      if code == '250':
         try:
-          key, value = message.split("=", 1)
+          key, value = message.split('=', 1)
           self.entries[key] = value
         except ValueError:
           raise stem.ProtocolError(None, "MAPADDRESS returned '%s', which isn't a mapping" % message)
diff --git a/stem/response/protocolinfo.py b/stem/response/protocolinfo.py
index 96fe3a4..82e5ec0 100644
--- a/stem/response/protocolinfo.py
+++ b/stem/response/protocolinfo.py
@@ -39,18 +39,18 @@ class ProtocolInfoResponse(stem.response.ControlMessage):
     auth_methods, unknown_auth_methods = [], []
     remaining_lines = list(self)
 
-    if not self.is_ok() or not remaining_lines.pop() == "OK":
+    if not self.is_ok() or not remaining_lines.pop() == 'OK':
       raise stem.ProtocolError("PROTOCOLINFO response didn't have an OK status:\n%s" % self)
 
     # sanity check that we're a PROTOCOLINFO response
-    if not remaining_lines[0].startswith("PROTOCOLINFO"):
-      raise stem.ProtocolError("Message is not a PROTOCOLINFO response:\n%s" % self)
+    if not remaining_lines[0].startswith('PROTOCOLINFO'):
+      raise stem.ProtocolError('Message is not a PROTOCOLINFO response:\n%s' % self)
 
     while remaining_lines:
       line = remaining_lines.pop(0)
       line_type = line.pop()
 
-      if line_type == "PROTOCOLINFO":
+      if line_type == 'PROTOCOLINFO':
         # Line format:
         #   FirstLine = "PROTOCOLINFO" SP PIVERSION CRLF
         #   PIVERSION = 1*DIGIT
@@ -61,16 +61,16 @@ class ProtocolInfoResponse(stem.response.ControlMessage):
         try:
           self.protocol_version = int(line.pop())
         except ValueError:
-          raise stem.ProtocolError("PROTOCOLINFO response version is non-numeric: %s" % line)
+          raise stem.ProtocolError('PROTOCOLINFO response version is non-numeric: %s' % line)
 
-        # The piversion really should be "1" but, according to the spec, tor
+        # The piversion really should be '1' but, according to the spec, tor
         # does not necessarily need to provide the PROTOCOLINFO version that we
         # requested. Log if it's something we aren't expecting but still make
         # an effort to parse like a v1 response.
 
         if self.protocol_version != 1:
           log.info("We made a PROTOCOLINFO version 1 query but got a version %i response instead. We'll still try to use it, but this may cause problems." % self.protocol_version)
-      elif line_type == "AUTH":
+      elif line_type == 'AUTH':
         # Line format:
         #   AuthLine = "250-AUTH" SP "METHODS=" AuthMethod *("," AuthMethod)
         #              *(SP "COOKIEFILE=" AuthCookieFile) CRLF
@@ -78,21 +78,21 @@ class ProtocolInfoResponse(stem.response.ControlMessage):
         #   AuthCookieFile = QuotedString
 
         # parse AuthMethod mapping
-        if not line.is_next_mapping("METHODS"):
+        if not line.is_next_mapping('METHODS'):
           raise stem.ProtocolError("PROTOCOLINFO response's AUTH line is missing its mandatory 'METHODS' mapping: %s" % line)
 
-        for method in line.pop_mapping()[1].split(","):
-          if method == "NULL":
+        for method in line.pop_mapping()[1].split(','):
+          if method == 'NULL':
             auth_methods.append(AuthMethod.NONE)
-          elif method == "HASHEDPASSWORD":
+          elif method == 'HASHEDPASSWORD':
             auth_methods.append(AuthMethod.PASSWORD)
-          elif method == "COOKIE":
+          elif method == 'COOKIE':
             auth_methods.append(AuthMethod.COOKIE)
-          elif method == "SAFECOOKIE":
+          elif method == 'SAFECOOKIE':
             auth_methods.append(AuthMethod.SAFECOOKIE)
           else:
             unknown_auth_methods.append(method)
-            message_id = "stem.response.protocolinfo.unknown_auth_%s" % method
+            message_id = 'stem.response.protocolinfo.unknown_auth_%s' % method
             log.log_once(message_id, log.INFO, "PROTOCOLINFO response included a type of authentication that we don't recognize: %s" % method)
 
             # our auth_methods should have a single AuthMethod.UNKNOWN entry if
@@ -101,14 +101,14 @@ class ProtocolInfoResponse(stem.response.ControlMessage):
               auth_methods.append(AuthMethod.UNKNOWN)
 
         # parse optional COOKIEFILE mapping (quoted and can have escapes)
-        if line.is_next_mapping("COOKIEFILE", True, True):
+        if line.is_next_mapping('COOKIEFILE', True, True):
           self.cookie_path = line.pop_mapping(True, True)[1]
-      elif line_type == "VERSION":
+      elif line_type == 'VERSION':
         # Line format:
         #   VersionLine = "250-VERSION" SP "Tor=" TorVersion OptArguments CRLF
         #   TorVersion = QuotedString
 
-        if not line.is_next_mapping("Tor", True):
+        if not line.is_next_mapping('Tor', True):
           raise stem.ProtocolError("PROTOCOLINFO response's VERSION line is missing its mandatory tor version mapping: %s" % line)
 
         try:
diff --git a/stem/socket.py b/stem/socket.py
index 6a452c7..fe17380 100644
--- a/stem/socket.py
+++ b/stem/socket.py
@@ -24,10 +24,10 @@ Tor...
       control_socket = stem.socket.ControlPort(port = 9051)
       stem.connection.authenticate(control_socket)
     except stem.SocketError as exc:
-      print "Unable to connect to tor on port 9051: %s" % exc
+      print 'Unable to connect to tor on port 9051: %s' % exc
       sys.exit(1)
     except stem.connection.AuthenticationFailure as exc:
-      print "Unable to authenticate: %s" % exc
+      print 'Unable to authenticate: %s' % exc
       sys.exit(1)
 
     print "Issuing 'GETINFO version' query...\\n"
@@ -221,7 +221,7 @@ class ControlSocket(object):
 
       with self._recv_lock:
         self._socket = self._make_socket()
-        self._socket_file = self._socket.makefile(mode = "rwb")
+        self._socket_file = self._socket.makefile(mode = 'rwb')
         self._is_alive = True
 
         # It's possible for this to have a transient failure...
@@ -321,7 +321,7 @@ class ControlSocket(object):
       * **NotImplementedError** if not implemented by a subclass
     """
 
-    raise NotImplementedError("Unsupported Operation: this should be implemented by the ControlSocket subclass")
+    raise NotImplementedError('Unsupported Operation: this should be implemented by the ControlSocket subclass')
 
 
 class ControlPort(ControlSocket):
@@ -330,7 +330,7 @@ class ControlPort(ControlSocket):
   option.
   """
 
-  def __init__(self, address = "127.0.0.1", port = 9051, connect = True):
+  def __init__(self, address = '127.0.0.1', port = 9051, connect = True):
     """
     ControlPort constructor.
 
@@ -368,7 +368,7 @@ class ControlPort(ControlSocket):
     return self._control_port
 
   def is_localhost(self):
-    return self._control_addr == "127.0.0.1"
+    return self._control_addr == '127.0.0.1'
 
   def _make_socket(self):
     try:
@@ -385,7 +385,7 @@ class ControlSocketFile(ControlSocket):
   option.
   """
 
-  def __init__(self, path = "/var/run/tor/control", connect = True):
+  def __init__(self, path = '/var/run/tor/control', connect = True):
     """
     ControlSocketFile constructor.
 
@@ -462,16 +462,16 @@ def send_message(control_file, message, raw = False):
     control_file.write(stem.util.str_tools._to_bytes(message))
     control_file.flush()
 
-    log_message = message.replace("\r\n", "\n").rstrip()
-    log.trace("Sent to tor:\n" + log_message)
+    log_message = message.replace('\r\n', '\n').rstrip()
+    log.trace('Sent to tor:\n' + log_message)
   except socket.error as exc:
-    log.info("Failed to send message: %s" % exc)
+    log.info('Failed to send message: %s' % exc)
 
     # When sending there doesn't seem to be a reliable method for
     # distinguishing between failures from a disconnect verses other things.
     # Just accounting for known disconnection responses.
 
-    if str(exc) == "[Errno 32] Broken pipe":
+    if str(exc) == '[Errno 32] Broken pipe':
       raise stem.SocketClosed(exc)
     else:
       raise stem.SocketError(exc)
@@ -479,8 +479,8 @@ def send_message(control_file, message, raw = False):
     # if the control_file has been closed then flush will receive:
     # AttributeError: 'NoneType' object has no attribute 'sendall'
 
-    log.info("Failed to send message: file has been closed")
-    raise stem.SocketClosed("file has been closed")
+    log.info('Failed to send message: file has been closed')
+    raise stem.SocketClosed('file has been closed')
 
 
 def recv_message(control_file):
@@ -499,8 +499,8 @@ def recv_message(control_file):
       a complete message
   """
 
-  parsed_content, raw_content = [], b""
-  logging_prefix = "Error while receiving a control message (%s): "
+  parsed_content, raw_content = [], b''
+  logging_prefix = 'Error while receiving a control message (%s): '
 
   while True:
     try:
@@ -513,9 +513,9 @@ def recv_message(control_file):
       # if the control_file has been closed then we will receive:
       # AttributeError: 'NoneType' object has no attribute 'recv'
 
-      prefix = logging_prefix % "SocketClosed"
-      log.info(prefix + "socket file has been closed")
-      raise stem.SocketClosed("socket file has been closed")
+      prefix = logging_prefix % 'SocketClosed'
+      log.info(prefix + 'socket file has been closed')
+      raise stem.SocketClosed('socket file has been closed')
     except (socket.error, ValueError) as exc:
       # When disconnected we get...
       #
@@ -525,8 +525,8 @@ def recv_message(control_file):
       # Python 3:
       #   ValueError: I/O operation on closed file.
 
-      prefix = logging_prefix % "SocketClosed"
-      log.info(prefix + "received exception \"%s\"" % exc)
+      prefix = logging_prefix % 'SocketClosed'
+      log.info(prefix + 'received exception "%s"' % exc)
       raise stem.SocketClosed(exc)
 
     raw_content += line
@@ -538,21 +538,21 @@ def recv_message(control_file):
       # if the socket is disconnected then the readline() method will provide
       # empty content
 
-      prefix = logging_prefix % "SocketClosed"
-      log.info(prefix + "empty socket content")
-      raise stem.SocketClosed("Received empty socket content.")
+      prefix = logging_prefix % 'SocketClosed'
+      log.info(prefix + 'empty socket content')
+      raise stem.SocketClosed('Received empty socket content.')
     elif len(line) < 4:
-      prefix = logging_prefix % "ProtocolError"
-      log.info(prefix + "line too short, \"%s\"" % log.escape(line))
-      raise stem.ProtocolError("Badly formatted reply line: too short")
+      prefix = logging_prefix % 'ProtocolError'
+      log.info(prefix + 'line too short, "%s"' % log.escape(line))
+      raise stem.ProtocolError('Badly formatted reply line: too short')
     elif not re.match(b'^[a-zA-Z0-9]{3}[-+ ]', line):
-      prefix = logging_prefix % "ProtocolError"
-      log.info(prefix + "malformed status code/divider, \"%s\"" % log.escape(line))
-      raise stem.ProtocolError("Badly formatted reply line: beginning is malformed")
-    elif not line.endswith(b"\r\n"):
-      prefix = logging_prefix % "ProtocolError"
-      log.info(prefix + "no CRLF linebreak, \"%s\"" % log.escape(line))
-      raise stem.ProtocolError("All lines should end with CRLF")
+      prefix = logging_prefix % 'ProtocolError'
+      log.info(prefix + 'malformed status code/divider, "%s"' % log.escape(line))
+      raise stem.ProtocolError('Badly formatted reply line: beginning is malformed')
+    elif not line.endswith(b'\r\n'):
+      prefix = logging_prefix % 'ProtocolError'
+      log.info(prefix + 'no CRLF linebreak, "%s"' % log.escape(line))
+      raise stem.ProtocolError('All lines should end with CRLF')
 
     line = line[:-2]  # strips off the CRLF
     status_code, divider, content = line[:3], line[3:4], line[4:]
@@ -561,18 +561,18 @@ def recv_message(control_file):
       status_code = stem.util.str_tools._to_unicode(status_code)
       divider = stem.util.str_tools._to_unicode(divider)
 
-    if divider == "-":
+    if divider == '-':
       # mid-reply line, keep pulling for more content
       parsed_content.append((status_code, divider, content))
-    elif divider == " ":
+    elif divider == ' ':
       # end of the message, return the message
       parsed_content.append((status_code, divider, content))
 
-      log_message = raw_content.replace(b"\r\n", b"\n").rstrip()
-      log.trace("Received from tor:\n" + stem.util.str_tools._to_unicode(log_message))
+      log_message = raw_content.replace(b'\r\n', b'\n').rstrip()
+      log.trace('Received from tor:\n' + stem.util.str_tools._to_unicode(log_message))
 
       return stem.response.ControlMessage(parsed_content, raw_content)
-    elif divider == "+":
+    elif divider == '+':
       # data entry, all of the following lines belong to the content until we
       # get a line with just a period
 
@@ -580,17 +580,17 @@ def recv_message(control_file):
         try:
           line = stem.util.str_tools._to_bytes(control_file.readline())
         except socket.error as exc:
-          prefix = logging_prefix % "SocketClosed"
-          log.info(prefix + "received an exception while mid-way through a data reply (exception: \"%s\", read content: \"%s\")" % (exc, log.escape(raw_content)))
+          prefix = logging_prefix % 'SocketClosed'
+          log.info(prefix + 'received an exception while mid-way through a data reply (exception: "%s", read content: "%s")' % (exc, log.escape(raw_content)))
           raise stem.SocketClosed(exc)
 
         raw_content += line
 
-        if not line.endswith(b"\r\n"):
-          prefix = logging_prefix % "ProtocolError"
-          log.info(prefix + "CRLF linebreaks missing from a data reply, \"%s\"" % log.escape(raw_content))
-          raise stem.ProtocolError("All lines should end with CRLF")
-        elif line == b".\r\n":
+        if not line.endswith(b'\r\n'):
+          prefix = logging_prefix % 'ProtocolError'
+          log.info(prefix + 'CRLF linebreaks missing from a data reply, "%s"' % log.escape(raw_content))
+          raise stem.ProtocolError('All lines should end with CRLF')
+        elif line == b'.\r\n':
           break  # data block termination
 
         line = line[:-2]  # strips off the CRLF
@@ -598,20 +598,20 @@ def recv_message(control_file):
         # lines starting with a period are escaped by a second period (as per
         # section 2.4 of the control-spec)
 
-        if line.startswith(b".."):
+        if line.startswith(b'..'):
           line = line[1:]
 
         # appends to previous content, using a newline rather than CRLF
         # separator (more conventional for multi-line string content outside
         # the windows world)
 
-        content += b"\n" + line
+        content += b'\n' + line
 
       parsed_content.append((status_code, divider, content))
     else:
       # this should never be reached due to the prefix regex, but might as well
       # be safe...
-      prefix = logging_prefix % "ProtocolError"
+      prefix = logging_prefix % 'ProtocolError'
       log.warn(prefix + "\"%s\" isn't a recognized divider type" % divider)
       raise stem.ProtocolError("Unrecognized divider type '%s': %s" % (divider, stem.util.str_tools._to_unicode(line)))
 
@@ -637,9 +637,9 @@ def send_formatting(message):
   # section ends with a single "." on a line of its own.
 
   # if we already have \r\n entries then standardize on \n to start with
-  message = message.replace("\r\n", "\n")
+  message = message.replace('\r\n', '\n')
 
-  if "\n" in message:
-    return "+%s\r\n.\r\n" % message.replace("\n", "\r\n")
+  if '\n' in message:
+    return '+%s\r\n.\r\n' % message.replace('\n', '\r\n')
   else:
-    return message + "\r\n"
+    return message + '\r\n'
diff --git a/stem/util/__init__.py b/stem/util/__init__.py
index 5885e47..226df2c 100644
--- a/stem/util/__init__.py
+++ b/stem/util/__init__.py
@@ -6,15 +6,15 @@ Utility functions used by the stem library.
 """
 
 __all__ = [
-  "conf",
-  "connection",
-  "enum",
-  "log",
-  "lru_cache",
-  "ordereddict",
-  "proc",
-  "system",
-  "term",
-  "test_tools",
-  "tor_tools",
+  'conf',
+  'connection',
+  'enum',
+  'log',
+  'lru_cache',
+  'ordereddict',
+  'proc',
+  'system',
+  'term',
+  'test_tools',
+  'tor_tools',
 ]
diff --git a/stem/util/conf.py b/stem/util/conf.py
index 254e2a4..7c1cd69 100644
--- a/stem/util/conf.py
+++ b/stem/util/conf.py
@@ -6,7 +6,7 @@ Handlers for text configuration files. Configurations are simple string to
 string mappings, with the configuration files using the following rules...
 
 * the key/value is separated by a space
-* anything after a "#" is ignored as a comment
+* anything after a '#' is ignored as a comment
 * excess whitespace is trimmed
 * empty lines are ignored
 * multi-line values can be defined by following the key with lines starting
@@ -31,11 +31,11 @@ For instance...
 ::
 
   config = {
-    "user.name": "Galen",
-    "user.password": "yabba1234",
-    "user.notes": "takes a fancy to pepperjack cheese",
-    "blankEntry.example": "",
-    "msg.greeting": "Multi-line message exclaiming of the\\nwonder and awe that is pepperjack!",
+    'user.name': 'Galen',
+    'user.password': 'yabba1234',
+    'user.notes': 'takes a fancy to pepperjack cheese',
+    'blankEntry.example': '',
+    'msg.greeting': 'Multi-line message exclaiming of the\\nwonder and awe that is pepperjack!',
   }
 
 Configurations are managed via the :class:`~stem.util.conf.Config` class. The
@@ -52,27 +52,27 @@ To do this use the :func:`~stem.util.conf.config_dict` function. For example...
   from stem.util import conf, connection
 
   def config_validator(key, value):
-    if key == "timeout":
+    if key == 'timeout':
       # require at least a one second timeout
       return max(1, value)
-    elif key == "endpoint":
+    elif key == 'endpoint':
       if not connection.is_valid_ipv4_address(value):
         raise ValueError("'%s' isn't a valid IPv4 address" % value)
-    elif key == "port":
+    elif key == 'port':
       if not connection.is_valid_port(value):
         raise ValueError("'%s' isn't a valid port" % value)
-    elif key == "retries":
+    elif key == 'retries':
       # negative retries really don't make sense
       return max(0, value)
 
-  CONFIG = conf.config_dict("ssh_login", {
-    "username": getpass.getuser(),
-    "password": "",
-    "timeout": 10,
-    "endpoint": "263.12.8.0",
-    "port": 22,
-    "reconnect": False,
-    "retries": 3,
+  CONFIG = conf.config_dict('ssh_login', {
+    'username': getpass.getuser(),
+    'password': '',
+    'timeout': 10,
+    'endpoint': '263.12.8.0',
+    'port': 22,
+    'reconnect': False,
+    'retries': 3,
   }, config_validator)
 
 There's several things going on here so lets take it step by step...
@@ -107,8 +107,8 @@ Now lets say our user has the following configuration file...
 ::
 
   >>> from stem.util import conf
-  >>> our_config = conf.get_config("ssh_login")
-  >>> our_config.load("/home/atagar/user_config")
+  >>> our_config = conf.get_config('ssh_login')
+  >>> our_config.load('/home/atagar/user_config')
   >>> print CONFIG  # doctest: +SKIP
   {
     "username": "waddle_doo",
@@ -385,19 +385,19 @@ class Config(object):
     # have something different in their config file (or it doesn't match this
     # type).
 
-    ssh_config = conf.config_dict("ssh_login", {
-      "login.user": "atagar",
-      "login.password": "pepperjack_is_awesome!",
-      "destination.ip": "127.0.0.1",
-      "destination.port": 22,
-      "startup.run": [],
+    ssh_config = conf.config_dict('ssh_login', {
+      'login.user': 'atagar',
+      'login.password': 'pepperjack_is_awesome!',
+      'destination.ip': '127.0.0.1',
+      'destination.port': 22,
+      'startup.run': [],
     })
 
     # Makes an empty config instance with the handle of 'ssh_login'. This is
     # a singleton so other classes can fetch this same configuration from
     # this handle.
 
-    user_config = conf.get_config("ssh_login")
+    user_config = conf.get_config('ssh_login')
 
     # Loads the user's configuration file, warning if this fails.
 
@@ -424,11 +424,11 @@ class Config(object):
     #
     # The other values are replaced, so ssh_config now becomes...
     #
-    # {"login.user": "atagar",
-    #  "login.password": "pepperjack_is_awesome!",
-    #  "destination.ip": "1.2.3.4",
-    #  "destination.port": 22,
-    #  "startup.run": ["export PATH=$PATH:~/bin", "alias l=ls"]}
+    # {'login.user': 'atagar',
+    #  'login.password': 'pepperjack_is_awesome!',
+    #  'destination.ip': '1.2.3.4',
+    #  'destination.port': 22,
+    #  'startup.run': ['export PATH=$PATH:~/bin', 'alias l=ls']}
     #
     # Information for what values fail to load and why are reported to
     # 'stem.util.log'.
@@ -462,9 +462,9 @@ class Config(object):
     if path:
       self._path = path
     elif not self._path:
-      raise ValueError("Unable to load configuration: no path provided")
+      raise ValueError('Unable to load configuration: no path provided')
 
-    with open(self._path, "r") as config_file:
+    with open(self._path, 'r') as config_file:
       read_contents = config_file.readlines()
 
     with self._contents_lock:
@@ -472,7 +472,7 @@ class Config(object):
         line = read_contents.pop(0)
 
         # strips any commenting or excess whitespace
-        comment_start = line.find("#")
+        comment_start = line.find('#')
 
         if comment_start != -1:
           line = line[:comment_start]
@@ -482,23 +482,23 @@ class Config(object):
         # parse the key/value pair
         if line:
           try:
-            key, value = line.split(" ", 1)
+            key, value = line.split(' ', 1)
             value = value.strip()
           except ValueError:
             log.debug("Config entry '%s' is expected to be of the format 'Key Value', defaulting to '%s' -> ''" % (line, line))
-            key, value = line, ""
+            key, value = line, ''
 
           if not value:
             # this might be a multi-line entry, try processing it as such
             multiline_buffer = []
 
-            while read_contents and read_contents[0].lstrip().startswith("|"):
+            while read_contents and read_contents[0].lstrip().startswith('|'):
               content = read_contents.pop(0).lstrip()[1:]  # removes '\s+|' prefix
-              content = content.rstrip("\n")           # trailing newline
+              content = content.rstrip('\n')  # trailing newline
               multiline_buffer.append(content)
 
             if multiline_buffer:
-              self.set(key, "\n".join(multiline_buffer), False)
+              self.set(key, '\n'.join(multiline_buffer), False)
               continue
 
           self.set(key, value, False)
@@ -516,15 +516,15 @@ class Config(object):
     if path:
       self._path = path
     elif not self._path:
-      raise ValueError("Unable to save configuration: no path provided")
+      raise ValueError('Unable to save configuration: no path provided')
 
     with self._contents_lock:
       with open(self._path, 'w') as output_file:
         for entry_key in sorted(self.keys()):
           for entry_value in self.get_value(entry_key, multiple = True):
             # check for multi line entries
-            if "\n" in entry_value:
-              entry_value = "\n|" + entry_value.replace("\n", "\n|")
+            if '\n' in entry_value:
+              entry_value = '\n|' + entry_value.replace('\n', '\n|')
 
             output_file.write('%s %s\n' % (entry_key, entry_value))
 
@@ -658,9 +658,9 @@ class Config(object):
       return val  # don't try to infer undefined values
 
     if isinstance(default, bool):
-      if val.lower() == "true":
+      if val.lower() == 'true':
         val = True
-      elif val.lower() == "false":
+      elif val.lower() == 'false':
         val = False
       else:
         log.debug("Config entry '%s' is expected to be a boolean, defaulting to '%s'" % (key, str(default)))
@@ -684,11 +684,11 @@ class Config(object):
     elif isinstance(default, dict):
       valMap = collections.OrderedDict()
       for entry in val:
-        if "=>" in entry:
-          entryKey, entryVal = entry.split("=>", 1)
+        if '=>' in entry:
+          entryKey, entryVal = entry.split('=>', 1)
           valMap[entryKey.strip()] = entryVal.strip()
         else:
-          log.debug("Ignoring invalid %s config entry (expected a mapping, but \"%s\" was missing \"=>\")" % (key, entry))
+          log.debug('Ignoring invalid %s config entry (expected a mapping, but "%s" was missing "=>")' % (key, entry))
       val = valMap
 
     return val
@@ -715,6 +715,6 @@ class Config(object):
         else:
           return self._contents[key][-1]
       else:
-        message_id = "stem.util.conf.missing_config_key_%s" % key
+        message_id = 'stem.util.conf.missing_config_key_%s' % key
         log.log_once(message_id, log.TRACE, "config entry '%s' not found, defaulting to '%s'" % (key, default))
         return default
diff --git a/stem/util/connection.py b/stem/util/connection.py
index e36d6c0..5dce161 100644
--- a/stem/util/connection.py
+++ b/stem/util/connection.py
@@ -75,8 +75,8 @@ Connection = collections.namedtuple('Connection', [
   'protocol',
 ])
 
-FULL_IPv4_MASK = "255.255.255.255"
-FULL_IPv6_MASK = "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF"
+FULL_IPv4_MASK = '255.255.255.255'
+FULL_IPv6_MASK = 'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF'
 
 CRYPTOVARIABLE_EQUALITY_COMPARISON_NONCE = os.urandom(32)
 
@@ -159,17 +159,17 @@ def get_connections(resolver, process_pid = None, process_name = None):
     if LOG_CONNECTION_RESOLUTION:
       log.debug(msg)
 
-  _log("=" * 80)
-  _log("Querying connections for resolver: %s, pid: %s, name: %s" % (resolver, process_pid, process_name))
+  _log('=' * 80)
+  _log('Querying connections for resolver: %s, pid: %s, name: %s' % (resolver, process_pid, process_name))
 
   if isinstance(process_pid, str):
     try:
       process_pid = int(process_pid)
     except ValueError:
-      raise ValueError("Process pid was non-numeric: %s" % process_pid)
+      raise ValueError('Process pid was non-numeric: %s' % process_pid)
 
   if process_pid is None and resolver in (Resolver.PROC, Resolver.BSD_PROCSTAT):
-    raise ValueError("%s resolution requires a pid" % resolver)
+    raise ValueError('%s resolution requires a pid' % resolver)
 
   if resolver == Resolver.PROC:
     return [Connection(*conn) for conn in stem.util.proc.get_connections(process_pid)]
@@ -191,8 +191,8 @@ def get_connections(resolver, process_pid = None, process_name = None):
     name = process_name if process_name else '\S*',
   )
 
-  _log("Resolver regex: %s" % resolver_regex_str)
-  _log("Resolver results:\n%s" % '\n'.join(results))
+  _log('Resolver regex: %s' % resolver_regex_str)
+  _log('Resolver results:\n%s' % '\n'.join(results))
 
   connections = []
   resolver_regex = re.compile(resolver_regex_str)
@@ -212,20 +212,20 @@ def get_connections(resolver, process_pid = None, process_name = None):
         continue  # procstat response for unestablished connections
 
       if not (is_valid_ipv4_address(local_addr) and is_valid_ipv4_address(remote_addr)):
-        _log("Invalid address (%s or %s): %s" % (local_addr, remote_addr, line))
+        _log('Invalid address (%s or %s): %s' % (local_addr, remote_addr, line))
       elif not (is_valid_port(local_port) and is_valid_port(remote_port)):
-        _log("Invalid port (%s or %s): %s" % (local_port, remote_port, line))
+        _log('Invalid port (%s or %s): %s' % (local_port, remote_port, line))
       elif protocol not in ('tcp', 'udp'):
-        _log("Unrecognized protocol (%s): %s" % (protocol, line))
+        _log('Unrecognized protocol (%s): %s' % (protocol, line))
 
       conn = Connection(local_addr, local_port, remote_addr, remote_port, protocol)
       connections.append(conn)
       _log(str(conn))
 
-  _log("%i connections found" % len(connections))
+  _log('%i connections found' % len(connections))
 
   if not connections:
-    raise IOError("No results found using: %s" % resolver_command)
+    raise IOError('No results found using: %s' % resolver_command)
 
   return connections
 
@@ -332,15 +332,15 @@ def is_valid_ipv4_address(address):
 
   # checks if theres four period separated values
 
-  if address.count(".") != 3:
+  if address.count('.') != 3:
     return False
 
   # checks that each value in the octet are decimal values between 0-255
-  for entry in address.split("."):
+  for entry in address.split('.'):
     if not entry.isdigit() or int(entry) < 0 or int(entry) > 255:
       return False
-    elif entry[0] == "0" and len(entry) > 1:
-      return False  # leading zeros, for instance in "1.2.3.001"
+    elif entry[0] == '0' and len(entry) > 1:
+      return False  # leading zeros, for instance in '1.2.3.001'
 
   return True
 
@@ -356,24 +356,24 @@ def is_valid_ipv6_address(address, allow_brackets = False):
   """
 
   if allow_brackets:
-    if address.startswith("[") and address.endswith("]"):
+    if address.startswith('[') and address.endswith(']'):
       address = address[1:-1]
 
   # addresses are made up of eight colon separated groups of four hex digits
   # with leading zeros being optional
   # https://en.wikipedia.org/wiki/IPv6#Address_format
 
-  colon_count = address.count(":")
+  colon_count = address.count(':')
 
   if colon_count > 7:
     return False  # too many groups
-  elif colon_count != 7 and not "::" in address:
+  elif colon_count != 7 and not '::' in address:
     return False  # not enough groups and none are collapsed
-  elif address.count("::") > 1 or ":::" in address:
+  elif address.count('::') > 1 or ':::' in address:
     return False  # multiple groupings of zeros can't be collapsed
 
-  for entry in address.split(":"):
-    if not re.match("^[0-9a-fA-f]{0,4}$", entry):
+  for entry in address.split(':'):
+    if not re.match('^[0-9a-fA-f]{0,4}$', entry):
       return False
 
   return True
@@ -398,8 +398,8 @@ def is_valid_port(entry, allow_zero = False):
   elif isinstance(entry, (bytes, unicode)):
     if not entry.isdigit():
       return False
-    elif entry[0] == "0" and len(entry) > 1:
-      return False  # leading zeros, ex "001"
+    elif entry[0] == '0' and len(entry) > 1:
+      return False  # leading zeros, ex '001'
 
     entry = int(entry)
 
@@ -431,12 +431,12 @@ def is_private_address(address):
 
   # checks for any of the simple wildcard ranges
 
-  if address.startswith("10.") or address.startswith("192.168.") or address.startswith("127."):
+  if address.startswith('10.') or address.startswith('192.168.') or address.startswith('127.'):
     return True
 
   # checks for the 172.16.* - 172.31.* range
 
-  if address.startswith("172."):
+  if address.startswith('172.'):
     second_octet = int(address.split('.')[1])
 
     if second_octet >= 16 and second_octet <= 31:
@@ -452,10 +452,10 @@ def expand_ipv6_address(address):
 
   ::
 
-    >>> expand_ipv6_address("2001:db8::ff00:42:8329")
+    >>> expand_ipv6_address('2001:db8::ff00:42:8329')
     '2001:0db8:0000:0000:0000:ff00:0042:8329'
 
-    >>> expand_ipv6_address("::")
+    >>> expand_ipv6_address('::')
     '0000:0000:0000:0000:0000:0000:0000:0000'
 
   :param str address: IPv6 address to be expanded
@@ -469,17 +469,17 @@ def expand_ipv6_address(address):
   # expands collapsed groupings, there can only be a single '::' in a valid
   # address
   if "::" in address:
-    missing_groups = 7 - address.count(":")
-    address = address.replace("::", "::" + ":" * missing_groups)
+    missing_groups = 7 - address.count(':')
+    address = address.replace('::', '::' + ':' * missing_groups)
 
   # inserts missing zeros
   for index in xrange(8):
     start = index * 5
-    end = address.index(":", start) if index != 7 else len(address)
+    end = address.index(':', start) if index != 7 else len(address)
     missing_zeros = 4 - (end - start)
 
     if missing_zeros > 0:
-      address = address[:start] + "0" * missing_zeros + address[start:]
+      address = address[:start] + '0' * missing_zeros + address[start:]
 
   return address
 
@@ -496,7 +496,7 @@ def get_mask_ipv4(bits):
   """
 
   if bits > 32 or bits < 0:
-    raise ValueError("A mask can only be 0-32 bits, got %i" % bits)
+    raise ValueError('A mask can only be 0-32 bits, got %i' % bits)
   elif bits == 32:
     return FULL_IPv4_MASK
 
@@ -507,7 +507,7 @@ def get_mask_ipv4(bits):
   octets = [mask_bin[8 * i:8 * (i + 1)] for i in xrange(4)]
 
   # converts each octet into its integer value
-  return ".".join([str(int(octet, 2)) for octet in octets])
+  return '.'.join([str(int(octet, 2)) for octet in octets])
 
 
 def get_mask_ipv6(bits):
@@ -523,7 +523,7 @@ def get_mask_ipv6(bits):
   """
 
   if bits > 128 or bits < 0:
-    raise ValueError("A mask can only be 0-128 bits, got %i" % bits)
+    raise ValueError('A mask can only be 0-128 bits, got %i' % bits)
   elif bits == 128:
     return FULL_IPv6_MASK
 
@@ -534,7 +534,7 @@ def get_mask_ipv6(bits):
   groupings = [mask_bin[16 * i:16 * (i + 1)] for i in xrange(8)]
 
   # converts each group into its hex value
-  return ":".join(["%04x" % int(group, 2) for group in groupings]).upper()
+  return ':'.join(['%04x' % int(group, 2) for group in groupings]).upper()
 
 
 def _get_masked_bits(mask):
@@ -554,12 +554,12 @@ def _get_masked_bits(mask):
 
   # converts octets to binary representation
   mask_bin = _get_address_binary(mask)
-  mask_match = re.match("^(1*)(0*)$", mask_bin)
+  mask_match = re.match('^(1*)(0*)$', mask_bin)
 
   if mask_match:
     return 32 - len(mask_match.groups()[1])
   else:
-    raise ValueError("Unable to convert mask to a bit count: %s" % mask)
+    raise ValueError('Unable to convert mask to a bit count: %s' % mask)
 
 
 def _get_binary(value, bits):
@@ -572,7 +572,7 @@ def _get_binary(value, bits):
   """
 
   # http://www.daniweb.com/code/snippet216539.html
-  return "".join([str((value >> y) & 1) for y in range(bits - 1, -1, -1)])
+  return ''.join([str((value >> y) & 1) for y in range(bits - 1, -1, -1)])
 
 
 def _get_address_binary(address):
@@ -585,10 +585,10 @@ def _get_address_binary(address):
   """
 
   if is_valid_ipv4_address(address):
-    return "".join([_get_binary(int(octet), 8) for octet in address.split(".")])
+    return ''.join([_get_binary(int(octet), 8) for octet in address.split('.')])
   elif is_valid_ipv6_address(address):
     address = expand_ipv6_address(address)
-    return "".join([_get_binary(int(grouping, 16), 16) for grouping in address.split(":")])
+    return ''.join([_get_binary(int(grouping, 16), 16) for grouping in address.split(':')])
   else:
     raise ValueError("'%s' is neither an IPv4 or IPv6 address" % address)
 
diff --git a/stem/util/enum.py b/stem/util/enum.py
index 5cd1f4f..1500a43 100644
--- a/stem/util/enum.py
+++ b/stem/util/enum.py
@@ -8,7 +8,7 @@ constructed as simple type listings...
 ::
 
   >>> from stem.util import enum
-  >>> insects = enum.Enum("ANT", "WASP", "LADYBUG", "FIREFLY")
+  >>> insects = enum.Enum('ANT', 'WASP', 'LADYBUG', 'FIREFLY')
   >>> insects.ANT
   'Ant'
   >>> tuple(insects)
@@ -19,7 +19,7 @@ constructed as simple type listings...
 ::
 
   >>> from stem.util import enum
-  >>> pets = enum.Enum(("DOG", "Skippy"), "CAT", ("FISH", "Nemo"))
+  >>> pets = enum.Enum(('DOG', 'Skippy'), 'CAT', ('FISH', 'Nemo'))
   >>> pets.DOG
   'Skippy'
   >>> pets.CAT
@@ -52,7 +52,7 @@ def UppercaseEnum(*args):
   ::
 
     >>> from stem.util import enum
-    >>> runlevels = enum.UppercaseEnum("DEBUG", "INFO", "NOTICE", "WARN", "ERROR")
+    >>> runlevels = enum.UppercaseEnum('DEBUG', 'INFO', 'NOTICE', 'WARN', 'ERROR')
     >>> runlevels.DEBUG
     'DEBUG'
 
@@ -79,7 +79,7 @@ class Enum(object):
       elif isinstance(entry, tuple) and len(entry) == 2:
         key, val = entry
       else:
-        raise ValueError("Unrecognized input: %s" % args)
+        raise ValueError('Unrecognized input: %s' % args)
 
       keys.append(key)
       values.append(val)
@@ -122,7 +122,7 @@ class Enum(object):
     """
 
     if not value in self._values:
-      raise ValueError("No such enumeration exists: %s (options: %s)" % (value, ", ".join(self._values)))
+      raise ValueError('No such enumeration exists: %s (options: %s)' % (value, ', '.join(self._values)))
 
     next_index = (self._values.index(value) + 1) % len(self._values)
     return self._values[next_index]
@@ -139,7 +139,7 @@ class Enum(object):
     """
 
     if not value in self._values:
-      raise ValueError("No such enumeration exists: %s (options: %s)" % (value, ", ".join(self._values)))
+      raise ValueError('No such enumeration exists: %s (options: %s)' % (value, ', '.join(self._values)))
 
     prev_index = (self._values.index(value) - 1) % len(self._values)
     return self._values[prev_index]
@@ -158,7 +158,7 @@ class Enum(object):
     if item in vars(self):
       return getattr(self, item)
     else:
-      keys = ", ".join(self.keys())
+      keys = ', '.join(self.keys())
       raise ValueError("'%s' isn't among our enumeration keys, which includes: %s" % (item, keys))
 
   def __iter__(self):
diff --git a/stem/util/log.py b/stem/util/log.py
index 7e77911..485b6db 100644
--- a/stem/util/log.py
+++ b/stem/util/log.py
@@ -57,7 +57,7 @@ import stem.util.str_tools
 # Logging runlevels. These are *very* commonly used so including shorter
 # aliases (so they can be referenced as log.DEBUG, log.WARN, etc).
 
-Runlevel = stem.util.enum.UppercaseEnum("TRACE", "DEBUG", "INFO", "NOTICE", "WARN", "ERROR")
+Runlevel = stem.util.enum.UppercaseEnum('TRACE', 'DEBUG', 'INFO', 'NOTICE', 'WARN', 'ERROR')
 TRACE, DEBUG, INFO, NOTICE, WARN, ERR = list(Runlevel)
 
 # mapping of runlevels to the logger module's values, TRACE and DEBUG aren't
@@ -72,10 +72,10 @@ LOG_VALUES = {
   Runlevel.ERROR: logging.ERROR,
 }
 
-logging.addLevelName(LOG_VALUES[TRACE], "TRACE")
-logging.addLevelName(LOG_VALUES[NOTICE], "NOTICE")
+logging.addLevelName(LOG_VALUES[TRACE], 'TRACE')
+logging.addLevelName(LOG_VALUES[NOTICE], 'NOTICE')
 
-LOGGER = logging.getLogger("stem")
+LOGGER = logging.getLogger('stem')
 LOGGER.setLevel(LOG_VALUES[TRACE])
 
 # There's some messages that we don't want to log more than once. This set has
@@ -131,7 +131,7 @@ def escape(message):
   if stem.prereq.is_python_3():
     message = stem.util.str_tools._to_unicode(message)
 
-  for pattern, replacement in (("\n", "\\n"), ("\r", "\\r"), ("\t", "\\t")):
+  for pattern, replacement in (('\n', '\\n'), ('\r', '\\r'), ('\t', '\\t')):
     message = message.replace(pattern, replacement)
 
   return message
diff --git a/stem/util/proc.py b/stem/util/proc.py
index 9bdc54a..62b7a5e 100644
--- a/stem/util/proc.py
+++ b/stem/util/proc.py
@@ -61,13 +61,13 @@ except ImportError:
 
 # os.sysconf is only defined on unix
 try:
-  CLOCK_TICKS = os.sysconf(os.sysconf_names["SC_CLK_TCK"])
+  CLOCK_TICKS = os.sysconf(os.sysconf_names['SC_CLK_TCK'])
 except AttributeError:
   CLOCK_TICKS = None
 
 Stat = stem.util.enum.Enum(
-  ("COMMAND", "command"), ("CPU_UTIME", "utime"),
-  ("CPU_STIME", "stime"), ("START_TIME", "start time")
+  ('COMMAND', 'command'), ('CPU_UTIME', 'utime'),
+  ('CPU_STIME', 'stime'), ('START_TIME', 'start time')
 )
 
 
@@ -79,11 +79,11 @@ def is_available():
   :returns: **True** if proc contents exist on this platform, **False** otherwise
   """
 
-  if platform.system() != "Linux":
+  if platform.system() != 'Linux':
     return False
   else:
     # list of process independent proc paths we use
-    proc_paths = ("/proc/stat", "/proc/meminfo", "/proc/net/tcp", "/proc/net/udp")
+    proc_paths = ('/proc/stat', '/proc/meminfo', '/proc/net/tcp', '/proc/net/udp')
 
     for path in proc_paths:
       if not os.path.exists(path):
@@ -102,15 +102,15 @@ def get_system_start_time():
   :raises: **IOError** if it can't be determined
   """
 
-  start_time, parameter = time.time(), "system start time"
-  btime_line = _get_line("/proc/stat", "btime", parameter)
+  start_time, parameter = time.time(), 'system start time'
+  btime_line = _get_line('/proc/stat', 'btime', parameter)
 
   try:
     result = float(btime_line.strip().split()[1])
-    _log_runtime(parameter, "/proc/stat[btime]", start_time)
+    _log_runtime(parameter, '/proc/stat[btime]', start_time)
     return result
   except:
-    exc = IOError("unable to parse the /proc/stat btime entry: %s" % btime_line)
+    exc = IOError('unable to parse the /proc/stat btime entry: %s' % btime_line)
     _log_failure(parameter, exc)
     raise exc
 
@@ -125,15 +125,15 @@ def get_physical_memory():
   :raises: **IOError** if it can't be determined
   """
 
-  start_time, parameter = time.time(), "system physical memory"
-  mem_total_line = _get_line("/proc/meminfo", "MemTotal:", parameter)
+  start_time, parameter = time.time(), 'system physical memory'
+  mem_total_line = _get_line('/proc/meminfo', 'MemTotal:', parameter)
 
   try:
     result = int(mem_total_line.split()[1]) * 1024
-    _log_runtime(parameter, "/proc/meminfo[MemTotal]", start_time)
+    _log_runtime(parameter, '/proc/meminfo[MemTotal]', start_time)
     return result
   except:
-    exc = IOError("unable to parse the /proc/meminfo MemTotal entry: %s" % mem_total_line)
+    exc = IOError('unable to parse the /proc/meminfo MemTotal entry: %s' % mem_total_line)
     _log_failure(parameter, exc)
     raise exc
 
@@ -149,16 +149,16 @@ def get_cwd(pid):
   :raises: **IOError** if it can't be determined
   """
 
-  start_time, parameter = time.time(), "cwd"
-  proc_cwd_link = "/proc/%s/cwd" % pid
+  start_time, parameter = time.time(), 'cwd'
+  proc_cwd_link = '/proc/%s/cwd' % pid
 
   if pid == 0:
-    cwd = ""
+    cwd = ''
   else:
     try:
       cwd = os.readlink(proc_cwd_link)
     except OSError:
-      exc = IOError("unable to read %s" % proc_cwd_link)
+      exc = IOError('unable to read %s' % proc_cwd_link)
       _log_failure(parameter, exc)
       raise exc
 
@@ -177,16 +177,16 @@ def get_uid(pid):
   :raises: **IOError** if it can't be determined
   """
 
-  start_time, parameter = time.time(), "uid"
-  status_path = "/proc/%s/status" % pid
-  uid_line = _get_line(status_path, "Uid:", parameter)
+  start_time, parameter = time.time(), 'uid'
+  status_path = '/proc/%s/status' % pid
+  uid_line = _get_line(status_path, 'Uid:', parameter)
 
   try:
     result = int(uid_line.split()[1])
-    _log_runtime(parameter, "%s[Uid]" % status_path, start_time)
+    _log_runtime(parameter, '%s[Uid]' % status_path, start_time)
     return result
   except:
-    exc = IOError("unable to parse the %s Uid entry: %s" % (status_path, uid_line))
+    exc = IOError('unable to parse the %s Uid entry: %s' % (status_path, uid_line))
     _log_failure(parameter, exc)
     raise exc
 
@@ -208,18 +208,18 @@ def get_memory_usage(pid):
   if pid == 0:
     return (0, 0)
 
-  start_time, parameter = time.time(), "memory usage"
-  status_path = "/proc/%s/status" % pid
-  mem_lines = _get_lines(status_path, ("VmRSS:", "VmSize:"), parameter)
+  start_time, parameter = time.time(), 'memory usage'
+  status_path = '/proc/%s/status' % pid
+  mem_lines = _get_lines(status_path, ('VmRSS:', 'VmSize:'), parameter)
 
   try:
-    residentSize = int(mem_lines["VmRSS:"].split()[1]) * 1024
-    virtualSize = int(mem_lines["VmSize:"].split()[1]) * 1024
+    residentSize = int(mem_lines['VmRSS:'].split()[1]) * 1024
+    virtualSize = int(mem_lines['VmSize:'].split()[1]) * 1024
 
-    _log_runtime(parameter, "%s[VmRSS|VmSize]" % status_path, start_time)
+    _log_runtime(parameter, '%s[VmRSS|VmSize]' % status_path, start_time)
     return (residentSize, virtualSize)
   except:
-    exc = IOError("unable to parse the %s VmRSS and VmSize entries: %s" % (status_path, ", ".join(mem_lines)))
+    exc = IOError('unable to parse the %s VmRSS and VmSize entries: %s' % (status_path, ', '.join(mem_lines)))
     _log_failure(parameter, exc)
     raise exc
 
@@ -238,18 +238,18 @@ def get_stats(pid, *stat_types):
   """
 
   if CLOCK_TICKS is None:
-    raise IOError("Unable to look up SC_CLK_TCK")
+    raise IOError('Unable to look up SC_CLK_TCK')
 
-  start_time, parameter = time.time(), "process %s" % ", ".join(stat_types)
+  start_time, parameter = time.time(), 'process %s' % ', '.join(stat_types)
 
   # the stat file contains a single line, of the form...
   # 8438 (tor) S 8407 8438 8407 34818 8438 4202496...
-  stat_path = "/proc/%s/stat" % pid
+  stat_path = '/proc/%s/stat' % pid
   stat_line = _get_line(stat_path, str(pid), parameter)
 
   # breaks line into component values
   stat_comp = []
-  cmd_start, cmd_end = stat_line.find("("), stat_line.find(")")
+  cmd_start, cmd_end = stat_line.find('('), stat_line.find(')')
 
   if cmd_start != -1 and cmd_end != -1:
     stat_comp.append(stat_line[:cmd_start])
@@ -257,7 +257,7 @@ def get_stats(pid, *stat_types):
     stat_comp += stat_line[cmd_end + 1:].split()
 
   if len(stat_comp) < 44 and _is_float(stat_comp[13], stat_comp[14], stat_comp[21]):
-    exc = IOError("stat file had an unexpected format: %s" % stat_path)
+    exc = IOError('stat file had an unexpected format: %s' % stat_path)
     _log_failure(parameter, exc)
     raise exc
 
@@ -265,17 +265,17 @@ def get_stats(pid, *stat_types):
   for stat_type in stat_types:
     if stat_type == Stat.COMMAND:
       if pid == 0:
-        results.append("sched")
+        results.append('sched')
       else:
         results.append(stat_comp[1])
     elif stat_type == Stat.CPU_UTIME:
       if pid == 0:
-        results.append("0")
+        results.append('0')
       else:
         results.append(str(float(stat_comp[13]) / CLOCK_TICKS))
     elif stat_type == Stat.CPU_STIME:
       if pid == 0:
-        results.append("0")
+        results.append('0')
       else:
         results.append(str(float(stat_comp[14]) / CLOCK_TICKS))
     elif stat_type == Stat.START_TIME:
@@ -311,18 +311,18 @@ def get_connections(pid):
     try:
       pid = int(pid)
     except ValueError:
-      raise IOError("Process pid was non-numeric: %s" % pid)
+      raise IOError('Process pid was non-numeric: %s' % pid)
 
   if pid == 0:
     return []
 
   # fetches the inode numbers for socket file descriptors
 
-  start_time, parameter = time.time(), "process connections"
+  start_time, parameter = time.time(), 'process connections'
   inodes = []
 
-  for fd in os.listdir("/proc/%s/fd" % pid):
-    fd_path = "/proc/%s/fd/%s" % (pid, fd)
+  for fd in os.listdir('/proc/%s/fd' % pid):
+    fd_path = '/proc/%s/fd/%s' % (pid, fd)
 
     try:
       # File descriptor link, such as 'socket:[30899]'
@@ -333,7 +333,7 @@ def get_connections(pid):
         inodes.append(fd_name[8:-1])
     except OSError:
       # most likely couldn't be read due to permissions
-      exc = IOError("unable to determine file descriptor destination: %s" % fd_path)
+      exc = IOError('unable to determine file descriptor destination: %s' % fd_path)
       _log_failure(parameter, exc)
       raise exc
 
@@ -345,7 +345,7 @@ def get_connections(pid):
 
   conn = []
 
-  for proc_file_path in ("/proc/net/tcp", "/proc/net/udp"):
+  for proc_file_path in ('/proc/net/tcp', '/proc/net/udp'):
     try:
       proc_file = open(proc_file_path)
       proc_file.readline()  # skip the first line
@@ -355,7 +355,7 @@ def get_connections(pid):
 
         if inode in inodes:
           # if a tcp connection, skip if it isn't yet established
-          if proc_file_path.endswith("/tcp") and status != "01":
+          if proc_file_path.endswith('/tcp') and status != '01':
             continue
 
           local_ip, local_port = _decode_proc_address_encoding(l_addr)
@@ -373,7 +373,7 @@ def get_connections(pid):
       _log_failure(parameter, exc)
       raise exc
 
-  _log_runtime(parameter, "/proc/net/[tcp|udp]", start_time)
+  _log_runtime(parameter, '/proc/net/[tcp|udp]', start_time)
   return conn
 
 
@@ -462,9 +462,9 @@ def _get_lines(file_path, line_prefixes, parameter):
 
     if remaining_prefixes:
       if len(remaining_prefixes) == 1:
-        msg = "%s did not contain a %s entry" % (file_path, remaining_prefixes[0])
+        msg = '%s did not contain a %s entry' % (file_path, remaining_prefixes[0])
       else:
-        msg = "%s did not contain %s entries" % (file_path, ", ".join(remaining_prefixes))
+        msg = '%s did not contain %s entries' % (file_path, ', '.join(remaining_prefixes))
 
       raise IOError(msg)
     else:
@@ -484,7 +484,7 @@ def _log_runtime(parameter, proc_location, start_time):
   """
 
   runtime = time.time() - start_time
-  log.debug("proc call (%s): %s (runtime: %0.4f)" % (parameter, proc_location, runtime))
+  log.debug('proc call (%s): %s (runtime: %0.4f)' % (parameter, proc_location, runtime))
 
 
 def _log_failure(parameter, exc):
@@ -495,4 +495,4 @@ def _log_failure(parameter, exc):
   :param Exception exc: exception that we're raising
   """
 
-  log.debug("proc call failed (%s): %s" % (parameter, exc))
+  log.debug('proc call failed (%s): %s' % (parameter, exc))
diff --git a/stem/util/str_tools.py b/stem/util/str_tools.py
index 71d5969..4b5ccca 100644
--- a/stem/util/str_tools.py
+++ b/stem/util/str_tools.py
@@ -23,52 +23,52 @@ import stem.prereq
 # label conversion tuples of the form...
 # (bits / bytes / seconds, short label, long label)
 SIZE_UNITS_BITS = (
-  (140737488355328.0, " Pb", " Petabit"),
-  (137438953472.0, " Tb", " Terabit"),
-  (134217728.0, " Gb", " Gigabit"),
-  (131072.0, " Mb", " Megabit"),
-  (128.0, " Kb", " Kilobit"),
-  (0.125, " b", " Bit"),
+  (140737488355328.0, ' Pb', ' Petabit'),
+  (137438953472.0, ' Tb', ' Terabit'),
+  (134217728.0, ' Gb', ' Gigabit'),
+  (131072.0, ' Mb', ' Megabit'),
+  (128.0, ' Kb', ' Kilobit'),
+  (0.125, ' b', ' Bit'),
 )
 
 SIZE_UNITS_BYTES = (
-  (1125899906842624.0, " PB", " Petabyte"),
-  (1099511627776.0, " TB", " Terabyte"),
-  (1073741824.0, " GB", " Gigabyte"),
-  (1048576.0, " MB", " Megabyte"),
-  (1024.0, " KB", " Kilobyte"),
-  (1.0, " B", " Byte"),
+  (1125899906842624.0, ' PB', ' Petabyte'),
+  (1099511627776.0, ' TB', ' Terabyte'),
+  (1073741824.0, ' GB', ' Gigabyte'),
+  (1048576.0, ' MB', ' Megabyte'),
+  (1024.0, ' KB', ' Kilobyte'),
+  (1.0, ' B', ' Byte'),
 )
 
 TIME_UNITS = (
-  (86400.0, "d", " day"),
-  (3600.0, "h", " hour"),
-  (60.0, "m", " minute"),
-  (1.0, "s", " second"),
+  (86400.0, 'd', ' day'),
+  (3600.0, 'h', ' hour'),
+  (60.0, 'm', ' minute'),
+  (1.0, 's', ' second'),
 )
 
 if stem.prereq.is_python_3():
   def _to_bytes_impl(msg):
     if isinstance(msg, str):
-      return codecs.latin_1_encode(msg, "replace")[0]
+      return codecs.latin_1_encode(msg, 'replace')[0]
     else:
       return msg
 
   def _to_unicode_impl(msg):
     if msg is not None and not isinstance(msg, str):
-      return msg.decode("utf-8", "replace")
+      return msg.decode('utf-8', 'replace')
     else:
       return msg
 else:
   def _to_bytes_impl(msg):
     if msg is not None and isinstance(msg, unicode):
-      return codecs.latin_1_encode(msg, "replace")[0]
+      return codecs.latin_1_encode(msg, 'replace')[0]
     else:
       return msg
 
   def _to_unicode_impl(msg):
     if msg is not None and not isinstance(msg, unicode):
-      return msg.decode("utf-8", "replace")
+      return msg.decode('utf-8', 'replace')
     else:
       return msg
 
@@ -103,13 +103,13 @@ def _to_unicode(msg):
   return _to_unicode_impl(msg)
 
 
-def _to_camel_case(label, divider = "_", joiner = " "):
+def _to_camel_case(label, divider = '_', joiner = ' '):
   """
   Converts the given string to camel case, ie:
 
   ::
 
-    >>> _to_camel_case("I_LIKE_PEPPERJACK!")
+    >>> _to_camel_case('I_LIKE_PEPPERJACK!')
     'I Like Pepperjack!'
 
   :param str label: input string to be converted
@@ -122,7 +122,7 @@ def _to_camel_case(label, divider = "_", joiner = " "):
   words = []
   for entry in label.split(divider):
     if len(entry) == 0:
-      words.append("")
+      words.append('')
     elif len(entry) == 1:
       words.append(entry.upper())
     else:
@@ -255,12 +255,12 @@ def get_short_time_label(seconds):
     seconds %= amount
     time_comp[label.strip()] = count
 
-  label = "%02i:%02i" % (time_comp["minute"], time_comp["second"])
+  label = '%02i:%02i' % (time_comp['minute'], time_comp['second'])
 
-  if time_comp["day"]:
-    label = "%i-%02i:%s" % (time_comp["day"], time_comp["hour"], label)
-  elif time_comp["hour"]:
-    label = "%02i:%s" % (time_comp["hour"], label)
+  if time_comp['day']:
+    label = '%i-%02i:%s' % (time_comp['day'], time_comp['hour'], label)
+  elif time_comp['hour']:
+    label = '%02i:%s' % (time_comp['hour'], label)
 
   return label
 
@@ -291,7 +291,7 @@ def parse_short_time_label(label):
   if '-' in label:
     days, label = label.split('-', 1)
 
-  time_comp = label.split(":")
+  time_comp = label.split(':')
 
   if len(time_comp) == 3:
     hours, minutes, seconds = time_comp
@@ -307,7 +307,7 @@ def parse_short_time_label(label):
     time_sum += int(days) * 86400
     return time_sum
   except ValueError:
-    raise ValueError("Non-numeric value in time entry: %s" % label)
+    raise ValueError('Non-numeric value in time entry: %s' % label)
 
 
 def _parse_iso_timestamp(entry):
@@ -326,7 +326,7 @@ def _parse_iso_timestamp(entry):
   """
 
   if not isinstance(entry, str):
-    raise ValueError("parse_iso_timestamp() input must be a str, got a %s" % type(entry))
+    raise ValueError('parse_iso_timestamp() input must be a str, got a %s' % type(entry))
 
   # based after suggestions from...
   # http://stackoverflow.com/questions/127803/how-to-parse-iso-formatted-date-in-python
@@ -356,14 +356,14 @@ def _get_label(units, count, decimal, is_long):
   """
 
   # formatted string for the requested number of digits
-  label_format = "%%.%if" % decimal
+  label_format = '%%.%if' % decimal
 
   if count < 0:
-    label_format = "-" + label_format
+    label_format = '-' + label_format
     count = abs(count)
   elif count == 0:
-    units_label = units[-1][2] + "s" if is_long else units[-1][1]
-    return "%s%s" % (label_format % count, units_label)
+    units_label = units[-1][2] + 's' if is_long else units[-1][1]
+    return '%s%s' % (label_format % count, units_label)
 
   for count_per_unit, short_label, long_label in units:
     if count >= count_per_unit:
@@ -382,6 +382,6 @@ def _get_label(units, count, decimal, is_long):
         else:
           is_plural = count >= count_per_unit * 2
 
-        return count_label + long_label + ("s" if is_plural else "")
+        return count_label + long_label + ('s' if is_plural else '')
       else:
         return count_label + short_label
diff --git a/stem/util/system.py b/stem/util/system.py
index 39552cf..7827eb6 100644
--- a/stem/util/system.py
+++ b/stem/util/system.py
@@ -59,22 +59,22 @@ CMD_AVAILABLE_CACHE = {}
 
 SHELL_COMMANDS = ['ulimit']
 
-IS_RUNNING_PS_LINUX = "ps -A co command"
-IS_RUNNING_PS_BSD = "ps -ao ucomm="
-GET_NAME_BY_PID_PS = "ps -p %s -o comm"
-GET_PID_BY_NAME_PGREP = "pgrep -x %s"
-GET_PID_BY_NAME_PIDOF = "pidof %s"
-GET_PID_BY_NAME_PS_LINUX = "ps -o pid -C %s"
-GET_PID_BY_NAME_PS_BSD = "ps axc"
-GET_PID_BY_NAME_LSOF = "lsof -tc %s"
-GET_PID_BY_PORT_NETSTAT = "netstat -npltu"
-GET_PID_BY_PORT_SOCKSTAT = "sockstat -4l -P tcp -p %s"
-GET_PID_BY_PORT_LSOF = "lsof -wnP -iTCP -sTCP:LISTEN"
-GET_PID_BY_FILE_LSOF = "lsof -tw %s"
-GET_CWD_PWDX = "pwdx %s"
-GET_CWD_LSOF = "lsof -a -p %s -d cwd -Fn"
-GET_BSD_JAIL_ID_PS = "ps -p %s -o jid"
-GET_BSD_JAIL_PATH = "jls -j %s"
+IS_RUNNING_PS_LINUX = 'ps -A co command'
+IS_RUNNING_PS_BSD = 'ps -ao ucomm='
+GET_NAME_BY_PID_PS = 'ps -p %s -o comm'
+GET_PID_BY_NAME_PGREP = 'pgrep -x %s'
+GET_PID_BY_NAME_PIDOF = 'pidof %s'
+GET_PID_BY_NAME_PS_LINUX = 'ps -o pid -C %s'
+GET_PID_BY_NAME_PS_BSD = 'ps axc'
+GET_PID_BY_NAME_LSOF = 'lsof -tc %s'
+GET_PID_BY_PORT_NETSTAT = 'netstat -npltu'
+GET_PID_BY_PORT_SOCKSTAT = 'sockstat -4l -P tcp -p %s'
+GET_PID_BY_PORT_LSOF = 'lsof -wnP -iTCP -sTCP:LISTEN'
+GET_PID_BY_FILE_LSOF = 'lsof -tw %s'
+GET_CWD_PWDX = 'pwdx %s'
+GET_CWD_LSOF = 'lsof -a -p %s -d cwd -Fn'
+GET_BSD_JAIL_ID_PS = 'ps -p %s -o jid'
+GET_BSD_JAIL_PATH = 'jls -j %s'
 
 # flag for setting the process name, found in '/usr/include/linux/prctl.h'
 
@@ -118,7 +118,7 @@ def is_windows():
   :returns: **bool** to indicate if we're on Windows
   """
 
-  return platform.system() == "Windows"
+  return platform.system() == 'Windows'
 
 
 def is_mac():
@@ -128,7 +128,7 @@ def is_mac():
   :returns: **bool** to indicate if we're on a Mac
   """
 
-  return platform.system() == "Darwin"
+  return platform.system() == 'Darwin'
 
 
 def is_bsd():
@@ -139,7 +139,7 @@ def is_bsd():
   :returns: **bool** to indicate if we're on a BSD OS
   """
 
-  return platform.system() in ("Darwin", "FreeBSD", "OpenBSD")
+  return platform.system() in ('Darwin', 'FreeBSD', 'OpenBSD')
 
 
 def is_available(command, cached=True):
@@ -159,8 +159,8 @@ def is_available(command, cached=True):
     PATH, **False** otherwise
   """
 
-  if " " in command:
-    command = command.split(" ")[0]
+  if ' ' in command:
+    command = command.split(' ')[0]
 
   if command in SHELL_COMMANDS:
     # we can't actually look it up, so hope the shell really provides it...
@@ -170,11 +170,11 @@ def is_available(command, cached=True):
     return CMD_AVAILABLE_CACHE[command]
   else:
     cmd_exists = False
-    for path in os.environ["PATH"].split(os.pathsep):
+    for path in os.environ['PATH'].split(os.pathsep):
       cmd_path = os.path.join(path, command)
 
       if is_windows():
-        cmd_path += ".exe"
+        cmd_path += '.exe'
 
       if os.path.exists(cmd_path) and os.access(cmd_path, os.X_OK):
         cmd_exists = True
@@ -207,7 +207,7 @@ def is_running(command):
   #   -o ucomm= - Shows just the ucomm attribute ("name to be used for
   #               accounting")
 
-  if is_available("ps"):
+  if is_available('ps'):
     if is_bsd():
       primary_resolver = IS_RUNNING_PS_BSD
       secondary_resolver = IS_RUNNING_PS_LINUX
@@ -298,7 +298,7 @@ def get_pid_by_name(process_name, multiple = False):
   #   3283
   #   3392
 
-  if is_available("pgrep"):
+  if is_available('pgrep'):
     results = call(GET_PID_BY_NAME_PGREP % process_name, None)
 
     if results:
@@ -319,7 +319,7 @@ def get_pid_by_name(process_name, multiple = False):
   #   atagar@morrigan:~$ pidof vim
   #   3392 3283
 
-  if is_available("pidof"):
+  if is_available('pidof'):
     results = call(GET_PID_BY_NAME_PIDOF % process_name, None)
 
     if results and len(results) == 1:
@@ -349,7 +349,7 @@ def get_pid_by_name(process_name, multiple = False):
   #      11   ??  Ss     5:47.36 DirectoryService
   #      12   ??  Ss     3:01.44 notifyd
 
-  if is_available("ps"):
+  if is_available('ps'):
     if not is_bsd():
       # linux variant of ps
       results = call(GET_PID_BY_NAME_PS_LINUX % process_name, None)
@@ -371,7 +371,7 @@ def get_pid_by_name(process_name, multiple = False):
 
       if results:
         # filters results to those with our process name
-        results = [r.split()[0] for r in results if r.endswith(" %s" % process_name)]
+        results = [r.split()[0] for r in results if r.endswith(' %s' % process_name)]
 
         try:
           pids = map(int, results)
@@ -397,7 +397,7 @@ def get_pid_by_name(process_name, multiple = False):
   #   2470
   #   2561
 
-  if is_available("lsof"):
+  if is_available('lsof'):
     results = call(GET_PID_BY_NAME_LSOF % process_name, None)
 
     if results:
@@ -454,16 +454,16 @@ def get_pid_by_port(port):
   #   udp        0      0 0.0.0.0:5353            0.0.0.0:*                  -
   #   udp6       0      0 fe80::7ae4:ff:fe2f::123 :::*                       -
 
-  if is_available("netstat"):
+  if is_available('netstat'):
     results = call(GET_PID_BY_PORT_NETSTAT, None)
 
     if results:
       # filters to results with our port
-      results = [r for r in results if "127.0.0.1:%s" % port in r]
+      results = [r for r in results if '127.0.0.1:%s' % port in r]
 
       if len(results) == 1 and len(results[0].split()) == 7:
         results = results[0].split()[6]  # process field (ex. "7184/tor")
-        pid = results[:results.find("/")]
+        pid = results[:results.find('/')]
 
         if pid.isdigit():
           return int(pid)
@@ -487,12 +487,12 @@ def get_pid_by_port(port):
   #   _tor     tor        4397  15 tcp4   51.64.7.84:59374   7.42.1.102:9001
   #   _tor     tor        4397  20 tcp4   51.64.7.84:51946   32.83.7.104:443
 
-  if is_available("sockstat"):
+  if is_available('sockstat'):
     results = call(GET_PID_BY_PORT_SOCKSTAT % port, None)
 
     if results:
       # filters to results where this is the local port
-      results = [r for r in results if (len(r.split()) == 7 and (":%s" % port) in r.split()[5])]
+      results = [r for r in results if (len(r.split()) == 7 and (':%s' % port) in r.split()[5])]
 
       if len(results) == 1:
         pid = results[0].split()[2]
@@ -519,12 +519,12 @@ def get_pid_by_port(port):
   #   COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
   #   tor     1745 atagar    6u  IPv4  14229      0t0  TCP 127.0.0.1:9051 (LISTEN)
 
-  if is_available("lsof"):
+  if is_available('lsof'):
     results = call(GET_PID_BY_PORT_LSOF, None)
 
     if results:
       # filters to results with our port
-      results = [r for r in results if (len(r.split()) == 10 and (":%s" % port) in r.split()[8])]
+      results = [r for r in results if (len(r.split()) == 10 and (':%s' % port) in r.split()[8])]
 
       if len(results) == 1:
         pid = results[0].split()[1]
@@ -561,7 +561,7 @@ def get_pid_by_open_file(path):
   #   atagar@morrigan:~$ lsof -tw /tmp/foo
   #   4762
 
-  if is_available("lsof"):
+  if is_available('lsof'):
     results = call(GET_PID_BY_FILE_LSOF % path, [])
 
     if len(results) == 1:
@@ -591,9 +591,9 @@ def get_cwd(pid):
       pass
 
   # Fall back to a pwdx query. This isn't available on BSD.
-  logging_prefix = "get_cwd(%s):" % pid
+  logging_prefix = 'get_cwd(%s):' % pid
 
-  if is_available("pwdx"):
+  if is_available('pwdx'):
     # pwdx results are of the form:
     # 3799: /home/atagar
     # 5839: No such process
@@ -602,12 +602,12 @@ def get_cwd(pid):
 
     if not results:
       log.debug("%s pwdx didn't return any results" % logging_prefix)
-    elif results[0].endswith("No such process"):
-      log.debug("%s pwdx processes reported for this pid" % logging_prefix)
-    elif len(results) != 1 or results[0].count(" ") != 1 or not results[0].startswith("%s: " % pid):
-      log.debug("%s we got unexpected output from pwdx: %s" % (logging_prefix, results))
+    elif results[0].endswith('No such process'):
+      log.debug('%s pwdx processes reported for this pid' % logging_prefix)
+    elif len(results) != 1 or results[0].count(' ') != 1 or not results[0].startswith('%s: ' % pid):
+      log.debug('%s we got unexpected output from pwdx: %s' % (logging_prefix, results))
     else:
-      return results[0].split(" ", 1)[1].strip()
+      return results[0].split(' ', 1)[1].strip()
 
   # Use lsof as the final fallback. This is available on both Linux and is the
   # only lookup method here that works for BSD...
@@ -624,20 +624,20 @@ def get_cwd(pid):
   #   p75717
   #   n/Users/atagar/tor/src/or
 
-  if is_available("lsof"):
+  if is_available('lsof'):
     results = call(GET_CWD_LSOF % pid, [])
 
-    if len(results) == 2 and results[1].startswith("n/"):
+    if len(results) == 2 and results[1].startswith('n/'):
       lsof_result = results[1][1:].strip()
 
       # If we lack read permissions for the cwd then it returns...
       # p2683
       # n/proc/2683/cwd (readlink: Permission denied)
 
-      if not " " in lsof_result:
+      if not ' ' in lsof_result:
         return lsof_result
     else:
-      log.debug("%s we got unexpected output from lsof: %s" % (logging_prefix, results))
+      log.debug('%s we got unexpected output from lsof: %s' % (logging_prefix, results))
 
   return None  # all queries failed
 
@@ -666,8 +666,8 @@ def get_user(pid):
     except:
       pass
 
-  if is_available("ps"):
-    results = call("ps -o user %s" % pid, [])
+  if is_available('ps'):
+    results = call('ps -o user %s' % pid, [])
 
     if len(results) >= 2:
       return results[1].strip()
@@ -695,7 +695,7 @@ def get_start_time(pid):
       pass
 
   try:
-    ps_results = call("ps -p %s -o etime" % pid, [])
+    ps_results = call('ps -p %s -o etime' % pid, [])
 
     if len(ps_results) >= 2:
       etime = ps_results[1].strip()
@@ -733,10 +733,10 @@ def get_bsd_jail_id(pid):
       return int(jid)
 
   os_name = platform.system()
-  if os_name == "FreeBSD":
-    log.warn("Unable to get the jail id for process %s." % pid)
+  if os_name == 'FreeBSD':
+    log.warn('Unable to get the jail id for process %s.' % pid)
   else:
-    log.debug("get_bsd_jail_id(%s): jail ids do not exist on %s" % (pid, os_name))
+    log.debug('get_bsd_jail_id(%s): jail ids do not exist on %s' % (pid, os_name))
 
   return 0
 
@@ -777,14 +777,14 @@ def expand_path(path, cwd = None):
   """
 
   if is_windows():
-    relative_path = path.replace("/", "\\").rstrip("\\")
+    relative_path = path.replace('/', '\\').rstrip('\\')
   else:
-    relative_path = path.rstrip("/")
+    relative_path = path.rstrip('/')
 
   if not relative_path or os.path.isabs(relative_path):
     # empty or already absolute - nothing to do
     pass
-  elif relative_path.startswith("~"):
+  elif relative_path.startswith('~'):
     # prefixed with a ~ or ~user entry
     relative_path = os.path.expanduser(relative_path)
   else:
@@ -795,12 +795,12 @@ def expand_path(path, cwd = None):
 
     # we'll be dealing with both "my/path/" and "./my/path" entries, so
     # cropping the later
-    if relative_path.startswith("./") or relative_path.startswith(".\\"):
+    if relative_path.startswith('./') or relative_path.startswith('.\\'):
       relative_path = relative_path[2:]
-    elif relative_path == ".":
-      relative_path = ""
+    elif relative_path == '.':
+      relative_path = ''
 
-    if relative_path == "":
+    if relative_path == '':
       relative_path = cwd
     else:
       relative_path = os.path.join(cwd, relative_path)
@@ -848,7 +848,7 @@ def call(command, default = UNDEFINED, ignore_exit_status = False):
   """
 
   try:
-    is_shell_command = command.split(" ")[0] in SHELL_COMMANDS
+    is_shell_command = command.split(' ')[0] in SHELL_COMMANDS
 
     start_time = time.time()
     process = subprocess.Popen(command.split(), stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = is_shell_command)
@@ -857,27 +857,27 @@ def call(command, default = UNDEFINED, ignore_exit_status = False):
     stdout, stderr = stdout.strip(), stderr.strip()
     runtime = time.time() - start_time
 
-    log.debug("System call: %s (runtime: %0.2f)" % (command, runtime))
-    trace_prefix = "Received from system (%s)" % command
+    log.debug('System call: %s (runtime: %0.2f)' % (command, runtime))
+    trace_prefix = 'Received from system (%s)' % command
 
     if stdout and stderr:
-      log.trace(trace_prefix + ", stdout:\n%s\nstderr:\n%s" % (stdout, stderr))
+      log.trace(trace_prefix + ', stdout:\n%s\nstderr:\n%s' % (stdout, stderr))
     elif stdout:
-      log.trace(trace_prefix + ", stdout:\n%s" % stdout)
+      log.trace(trace_prefix + ', stdout:\n%s' % stdout)
     elif stderr:
-      log.trace(trace_prefix + ", stderr:\n%s" % stderr)
+      log.trace(trace_prefix + ', stderr:\n%s' % stderr)
 
     exit_code = process.poll()
 
     if not ignore_exit_status and exit_code != 0:
-      raise OSError("%s returned exit status %i" % (command, exit_code))
+      raise OSError('%s returned exit status %i' % (command, exit_code))
 
     if stdout:
-      return stdout.decode("utf-8", "replace").splitlines()
+      return stdout.decode('utf-8', 'replace').splitlines()
     else:
       return []
   except OSError as exc:
-    log.debug("System call (failed): %s (error: %s)" % (command, exc))
+    log.debug('System call (failed): %s (error: %s)' % (command, exc))
 
     if default != UNDEFINED:
       return default
@@ -900,15 +900,15 @@ def get_process_name():
     #   COMMAND
     #   python run_tests.py --unit
 
-    ps_output = call("ps -p %i -o args" % os.getpid(), [])
+    ps_output = call('ps -p %i -o args' % os.getpid(), [])
 
-    if len(ps_output) == 2 and ps_output[0] in ("COMMAND", "ARGS"):
+    if len(ps_output) == 2 and ps_output[0] in ('COMMAND', 'ARGS'):
       _PROCESS_NAME = ps_output[1]
     else:
       # Falling back on using ctypes to get our argv. Unfortunately the simple
       # method for getting this...
       #
-      #   " ".join(["python"] + sys.argv)
+      #   ' '.join(['python'] + sys.argv)
       #
       # ... doesn't do the trick since this will miss interpretor arguments.
       #
@@ -930,7 +930,7 @@ def get_process_name():
 
         args.append(str(argc[i]))
 
-      _PROCESS_NAME = " ".join(args)
+      _PROCESS_NAME = ' '.join(args)
 
     _MAX_NAME_LENGTH = len(_PROCESS_NAME)
 
@@ -963,16 +963,16 @@ def set_process_name(process_name):
 
   _set_argv(process_name)
 
-  if platform.system() == "Linux":
+  if platform.system() == 'Linux':
     _set_prctl_name(process_name)
-  elif platform.system() in ("Darwin", "FreeBSD", "OpenBSD"):
+  elif platform.system() in ('Darwin', 'FreeBSD', 'OpenBSD'):
     _set_proc_title(process_name)
 
 
 def _set_argv(process_name):
   """
   Overwrites our argv in a similar fashion to how it's done in C with:
-  strcpy(argv[0], "new_name");
+  strcpy(argv[0], 'new_name');
   """
 
   if Py_GetArgcArgv is None:
@@ -1008,7 +1008,7 @@ def _set_prctl_name(process_name):
   http://stackoverflow.com/questions/564695/is-there-a-way-to-change-effective-process-name-in-python/923034#923034
   """
 
-  libc = ctypes.CDLL(ctypes.util.find_library("c"))
+  libc = ctypes.CDLL(ctypes.util.find_library('c'))
   name_buffer = ctypes.create_string_buffer(len(process_name) + 1)
   name_buffer.value = stem.util.str_tools._to_bytes(process_name)
   libc.prctl(PR_SET_NAME, ctypes.byref(name_buffer), 0, 0, 0)
@@ -1021,7 +1021,7 @@ def _set_proc_title(process_name):
   http://www.rootr.net/man/man/setproctitle/3
   """
 
-  libc = ctypes.CDLL(ctypes.util.find_library("c"))
+  libc = ctypes.CDLL(ctypes.util.find_library('c'))
   name_buffer = ctypes.create_string_buffer(len(process_name) + 1)
   name_buffer.value = process_name
 
diff --git a/stem/util/term.py b/stem/util/term.py
index 05b649d..f390cfd 100644
--- a/stem/util/term.py
+++ b/stem/util/term.py
@@ -44,19 +44,19 @@ Utilities for working with the terminal.
 import stem.util.enum
 import stem.util.str_tools
 
-TERM_COLORS = ("BLACK", "RED", "GREEN", "YELLOW", "BLUE", "MAGENTA", "CYAN", "WHITE")
+TERM_COLORS = ('BLACK', 'RED', 'GREEN', 'YELLOW', 'BLUE', 'MAGENTA', 'CYAN', 'WHITE')
 
 Color = stem.util.enum.Enum(*TERM_COLORS)
-BgColor = stem.util.enum.Enum(*["BG_" + color for color in TERM_COLORS])
-Attr = stem.util.enum.Enum("BOLD", "UNDERLINE", "HILIGHT")
+BgColor = stem.util.enum.Enum(*['BG_' + color for color in TERM_COLORS])
+Attr = stem.util.enum.Enum('BOLD', 'UNDERLINE', 'HILIGHT')
 
 # mappings of terminal attribute enums to their ANSI escape encoding
 FG_ENCODING = dict([(list(Color)[i], str(30 + i)) for i in range(8)])
 BG_ENCODING = dict([(list(BgColor)[i], str(40 + i)) for i in range(8)])
-ATTR_ENCODING = {Attr.BOLD: "1", Attr.UNDERLINE: "4", Attr.HILIGHT: "7"}
+ATTR_ENCODING = {Attr.BOLD: '1', Attr.UNDERLINE: '4', Attr.HILIGHT: '7'}
 
-CSI = "\x1B[%sm"
-RESET = CSI % "0"
+CSI = '\x1B[%sm'
+RESET = CSI % '0'
 
 
 def format(msg, *attr):
@@ -72,7 +72,7 @@ def format(msg, *attr):
   :param str msg: string to be formatted
   :param str attr: text attributes, this can be :data:`~stem.util.term.Color`,
     :data:`~stem.util.term.BgColor`, or :data:`~stem.util.term.Attr` enums
-    and are case insensitive (so strings like "red" are fine)
+    and are case insensitive (so strings like 'red' are fine)
 
   :returns: **str** wrapped with ANSI escape encodings, starting with the given
     attributes and ending with a reset
@@ -80,10 +80,12 @@ def format(msg, *attr):
 
   # if we have reset sequences in the message then apply our attributes
   # after each of them
+
   if RESET in msg:
-    return "".join([format(comp, *attr) for comp in msg.split(RESET)])
+    return ''.join([format(comp, *attr) for comp in msg.split(RESET)])
 
   encodings = []
+
   for text_attr in attr:
     text_attr, encoding = stem.util.str_tools._to_camel_case(text_attr), None
     encoding = FG_ENCODING.get(text_attr, encoding)
@@ -94,6 +96,6 @@ def format(msg, *attr):
       encodings.append(encoding)
 
   if encodings:
-    return (CSI % ";".join(encodings)) + msg + RESET
+    return (CSI % ';'.join(encodings)) + msg + RESET
   else:
     return msg
diff --git a/stem/util/test_tools.py b/stem/util/test_tools.py
index f97189a..b95cbd5 100644
--- a/stem/util/test_tools.py
+++ b/stem/util/test_tools.py
@@ -25,10 +25,10 @@ import re
 import stem.util.conf
 import stem.util.system
 
-CONFIG = stem.util.conf.config_dict("test", {
-  "pep8.ignore": [],
-  "pyflakes.ignore": [],
-  "exclude_paths": [],
+CONFIG = stem.util.conf.config_dict('test', {
+  'pep8.ignore': [],
+  'pyflakes.ignore': [],
+  'exclude_paths': [],
 })
 
 
@@ -62,7 +62,7 @@ def clean_orphaned_pyc(paths):
       # with python 3 because it's an exported copy of the python 2 codebase,
       # so skipping. However, we might want to address this for other callers.
 
-      if "__pycache__" in pyc_path:
+      if '__pycache__' in pyc_path:
         continue
 
       if not os.path.exists(pyc_path[:-1]):
@@ -164,7 +164,7 @@ def get_stylistic_issues(paths, check_two_space_indents = False, check_newlines
         code = super(StyleReport, self).error(line_number, offset, text, check)
 
         if code:
-          issues.setdefault(self.filename, []).append((offset + line_number, "%s %s" % (code, text)))
+          issues.setdefault(self.filename, []).append((offset + line_number, '%s %s' % (code, text)))
 
     style_checker = pep8.StyleGuide(ignore = CONFIG['pep8.ignore'], reporter = StyleReport)
     style_checker.check_files(list(_python_files(paths)))
@@ -174,11 +174,11 @@ def get_stylistic_issues(paths, check_two_space_indents = False, check_newlines
       with open(path) as f:
         file_contents = f.read()
 
-      lines, prev_indent = file_contents.split("\n"), 0
+      lines, prev_indent = file_contents.split('\n'), 0
       is_block_comment = False
 
       for index, line in enumerate(lines):
-        whitespace, content = re.match("^(\s*)(.*)$", line).groups()
+        whitespace, content = re.match('^(\s*)(.*)$', line).groups()
 
         # TODO: This does not check that block indentations are two spaces
         # because differentiating source from string blocks ("""foo""") is more
@@ -187,13 +187,13 @@ def get_stylistic_issues(paths, check_two_space_indents = False, check_newlines
         if '"""' in content:
           is_block_comment = not is_block_comment
 
-        if check_two_space_indents and "\t" in whitespace:
-          issues.setdefault(path, []).append((index + 1, "indentation has a tab"))
-        elif check_newlines and "\r" in content:
-          issues.setdefault(path, []).append((index + 1, "contains a windows newline"))
+        if check_two_space_indents and '\t' in whitespace:
+          issues.setdefault(path, []).append((index + 1, 'indentation has a tab'))
+        elif check_newlines and '\r' in content:
+          issues.setdefault(path, []).append((index + 1, 'contains a windows newline'))
         elif check_trailing_whitespace and content != content.rstrip():
-          issues.setdefault(path, []).append((index + 1, "line has trailing whitespace"))
-        elif check_exception_keyword and content.lstrip().startswith("except") and content.endswith(", exc:"):
+          issues.setdefault(path, []).append((index + 1, 'line has trailing whitespace'))
+        elif check_exception_keyword and content.lstrip().startswith('except') and content.endswith(', exc:'):
           # Python 2.6 - 2.7 supports two forms for exceptions...
           #
           #   except ValueError, exc:
@@ -239,8 +239,8 @@ def get_pyflakes_issues(paths):
       def __init__(self):
         self._ignored_issues = {}
 
-        for line in CONFIG["pyflakes.ignore"]:
-          path, issue = line.split("=>")
+        for line in CONFIG['pyflakes.ignore']:
+          path, issue = line.split('=>')
           self._ignored_issues.setdefault(path.strip(), []).append(issue.strip())
 
       def unexpectedError(self, filename, msg):
@@ -279,7 +279,7 @@ def _python_files(paths):
     for file_path in stem.util.system.files_with_suffix(path, '.py'):
       skip = False
 
-      for exclude_path in CONFIG["exclude_paths"]:
+      for exclude_path in CONFIG['exclude_paths']:
         if re.match(exclude_path, file_path):
           skip = True
           break
diff --git a/stem/util/tor_tools.py b/stem/util/tor_tools.py
index 5a194d3..325fcbe 100644
--- a/stem/util/tor_tools.py
+++ b/stem/util/tor_tools.py
@@ -34,10 +34,10 @@ import re
 # case insensitive. Tor doesn't define this in the spec so flipping a coin
 # and going with case insensitive.
 
-HEX_DIGIT = "[0-9a-fA-F]"
-FINGERPRINT_PATTERN = re.compile("^%s{40}$" % HEX_DIGIT)
-NICKNAME_PATTERN = re.compile("^[a-zA-Z0-9]{1,19}$")
-CIRC_ID_PATTERN = re.compile("^[a-zA-Z0-9]{1,16}$")
+HEX_DIGIT = '[0-9a-fA-F]'
+FINGERPRINT_PATTERN = re.compile('^%s{40}$' % HEX_DIGIT)
+NICKNAME_PATTERN = re.compile('^[a-zA-Z0-9]{1,19}$')
+CIRC_ID_PATTERN = re.compile('^[a-zA-Z0-9]{1,16}$')
 
 
 def is_valid_fingerprint(entry, check_prefix = False):
@@ -55,7 +55,7 @@ def is_valid_fingerprint(entry, check_prefix = False):
   if not isinstance(entry, (str, unicode)):
     return False
   elif check_prefix:
-    if not entry or entry[0] != "$":
+    if not entry or entry[0] != '$':
       return False
 
     entry = entry[1:]
@@ -124,4 +124,4 @@ def is_hex_digits(entry, count):
   :returns: **True** if the string matches this number
   """
 
-  return bool(re.match("^%s{%i}$" % (HEX_DIGIT, count), entry))
+  return bool(re.match('^%s{%i}$' % (HEX_DIGIT, count), entry))
diff --git a/test/__init__.py b/test/__init__.py
index 1a71ca8..943abe8 100644
--- a/test/__init__.py
+++ b/test/__init__.py
@@ -6,10 +6,10 @@ Unit and integration tests for the stem library.
 """
 
 __all__ = [
-  "mocking",
-  "network",
-  "output",
-  "prompt",
-  "runner",
-  "utils",
+  'mocking',
+  'network',
+  'output',
+  'prompt',
+  'runner',
+  'utils',
 ]
diff --git a/test/integ/__init__.py b/test/integ/__init__.py
index 5779e3f..886d1c8 100644
--- a/test/integ/__init__.py
+++ b/test/integ/__init__.py
@@ -3,12 +3,12 @@ Integration tests for the stem library.
 """
 
 __all__ = [
-  "connection",
-  "control",
-  "descriptor",
-  "response",
-  "socket",
-  "util",
-  "process",
-  "version",
+  'connection',
+  'control',
+  'descriptor',
+  'response',
+  'socket',
+  'util',
+  'process',
+  'version',
 ]
diff --git a/test/integ/connection/__init__.py b/test/integ/connection/__init__.py
index 134dbe1..e55cfd2 100644
--- a/test/integ/connection/__init__.py
+++ b/test/integ/connection/__init__.py
@@ -2,4 +2,4 @@
 Integration tests for stem.connection.
 """
 
-__all__ = ["authenticate", "connect"]
+__all__ = ['authenticate', 'connect']
diff --git a/test/integ/connection/authentication.py b/test/integ/connection/authentication.py
index 72ed40a..308f18a 100644
--- a/test/integ/connection/authentication.py
+++ b/test/integ/connection/authentication.py
@@ -14,17 +14,17 @@ import test.runner
 # Responses given by tor for various authentication failures. These may change
 # in the future and if they do then this test should be updated.
 
-COOKIE_AUTH_FAIL = "Authentication failed: Wrong length on authentication cookie."
-SAFECOOKIE_AUTH_FAIL = "Authentication failed: Wrong length for safe cookie response."
-PASSWORD_AUTH_FAIL = "Authentication failed: Password did not match HashedControlPassword value from configuration. Maybe you tried a plain text password? If so, the standard requires that you put it in double quotes."
-MULTIPLE_AUTH_FAIL = "Authentication failed: Password did not match HashedControlPassword *or* authentication cookie."
-SAFECOOKIE_AUTHCHALLENGE_FAIL = "Cookie authentication is disabled"
+COOKIE_AUTH_FAIL = 'Authentication failed: Wrong length on authentication cookie.'
+SAFECOOKIE_AUTH_FAIL = 'Authentication failed: Wrong length for safe cookie response.'
+PASSWORD_AUTH_FAIL = 'Authentication failed: Password did not match HashedControlPassword value from configuration. Maybe you tried a plain text password? If so, the standard requires that you put it in double quotes.'
+MULTIPLE_AUTH_FAIL = 'Authentication failed: Password did not match HashedControlPassword *or* authentication cookie.'
+SAFECOOKIE_AUTHCHALLENGE_FAIL = 'Cookie authentication is disabled'
 
 # this only arises in cookie-only or password-only auth when we authenticate
 # with the wrong value
-INCORRECT_COOKIE_FAIL = "Authentication failed: Authentication cookie did not match expected value."
-INCORRECT_SAFECOOKIE_FAIL = "Authentication failed: Safe cookie response did not match expected value."
-INCORRECT_PASSWORD_FAIL = "Authentication failed: Password did not match HashedControlPassword value from configuration"
+INCORRECT_COOKIE_FAIL = 'Authentication failed: Authentication cookie did not match expected value.'
+INCORRECT_SAFECOOKIE_FAIL = 'Authentication failed: Safe cookie response did not match expected value.'
+INCORRECT_PASSWORD_FAIL = 'Authentication failed: Password did not match HashedControlPassword value from configuration'
 
 
 def _can_authenticate(auth_type):
@@ -196,9 +196,9 @@ class TestAuthenticate(unittest.TestCase):
     # tests with the incorrect password
     with runner.get_tor_socket(False) as control_socket:
       if is_password_only:
-        self.assertRaises(stem.connection.IncorrectPassword, stem.connection.authenticate, control_socket, "blarg")
+        self.assertRaises(stem.connection.IncorrectPassword, stem.connection.authenticate, control_socket, 'blarg')
       else:
-        stem.connection.authenticate(control_socket, "blarg", runner.get_chroot())
+        stem.connection.authenticate(control_socket, 'blarg', runner.get_chroot())
         test.runner.exercise_controller(self, control_socket)
 
     # tests with the right password
@@ -267,7 +267,7 @@ class TestAuthenticate(unittest.TestCase):
     # Check with an empty, invalid, and quoted password. These should work if
     # we have no authentication, and fail otherwise.
 
-    for auth_value in ("", "blarg", "this has a \" in it"):
+    for auth_value in ('', 'blarg', 'this has a " in it'):
       if _can_authenticate(stem.connection.AuthMethod.NONE):
         self._check_auth(auth_type, auth_value)
       else:
@@ -311,11 +311,11 @@ class TestAuthenticate(unittest.TestCase):
     if test.runner.require_control(self):
       return
 
-    auth_value = test.runner.get_runner().get_test_dir("fake_cookie")
+    auth_value = test.runner.get_runner().get_test_dir('fake_cookie')
 
     # we need to create a 32 byte cookie file to load from
-    fake_cookie = open(auth_value, "w")
-    fake_cookie.write("0" * 32)
+    fake_cookie = open(auth_value, 'w')
+    fake_cookie.write('0' * 32)
     fake_cookie.close()
 
     for auth_type in self.cookie_auth_methods:
@@ -369,7 +369,7 @@ class TestAuthenticate(unittest.TestCase):
     for auth_type in self.cookie_auth_methods:
       if os.path.getsize(auth_value) == 32:
         # Weird coincidence? Fail so we can pick another file to check against.
-        self.fail("Our torrc is 32 bytes, preventing the test_authenticate_cookie_wrong_size test from running.")
+        self.fail('Our torrc is 32 bytes, preventing the test_authenticate_cookie_wrong_size test from running.')
       else:
         self.assertRaises(stem.connection.IncorrectCookieSize, self._check_auth, auth_type, auth_value, False)
 
diff --git a/test/integ/control/__init__.py b/test/integ/control/__init__.py
index 7e71dad..403bb5f 100644
--- a/test/integ/control/__init__.py
+++ b/test/integ/control/__init__.py
@@ -2,4 +2,4 @@
 Integration tests for stem.control.
 """
 
-__all__ = ["base_controller", "controller"]
+__all__ = ['base_controller', 'controller']
diff --git a/test/integ/control/base_controller.py b/test/integ/control/base_controller.py
index 0226022..96fb75b 100644
--- a/test/integ/control/base_controller.py
+++ b/test/integ/control/base_controller.py
@@ -44,7 +44,7 @@ class TestBaseController(unittest.TestCase):
     if test.runner.require_control(self):
       return
     elif stem.util.system.is_mac():
-      test.runner.skip(self, "(ticket #6235)")
+      test.runner.skip(self, '(ticket #6235)')
       return
 
     with test.runner.get_runner().get_tor_socket() as control_socket:
@@ -76,7 +76,7 @@ class TestBaseController(unittest.TestCase):
 
     with test.runner.get_runner().get_tor_socket() as control_socket:
       controller = stem.control.BaseController(control_socket)
-      response = controller.msg("invalid")
+      response = controller.msg('invalid')
       self.assertEquals('Unrecognized command "invalid"', str(response))
 
   def test_msg_invalid_getinfo(self):
@@ -89,7 +89,7 @@ class TestBaseController(unittest.TestCase):
 
     with test.runner.get_runner().get_tor_socket() as control_socket:
       controller = stem.control.BaseController(control_socket)
-      response = controller.msg("GETINFO blarg")
+      response = controller.msg('GETINFO blarg')
       self.assertEquals('Unrecognized key "blarg"', str(response))
 
   def test_msg_repeatedly(self):
@@ -101,7 +101,7 @@ class TestBaseController(unittest.TestCase):
     if test.runner.require_control(self):
       return
     elif stem.util.system.is_mac():
-      test.runner.skip(self, "(ticket #6235)")
+      test.runner.skip(self, '(ticket #6235)')
       return
 
     with test.runner.get_runner().get_tor_socket() as control_socket:
@@ -110,9 +110,9 @@ class TestBaseController(unittest.TestCase):
       def run_getinfo():
         for _ in xrange(150):
           try:
-            controller.msg("GETINFO version")
-            controller.msg("GETINFO blarg")
-            controller.msg("blarg")
+            controller.msg('GETINFO version')
+            controller.msg('GETINFO blarg')
+            controller.msg('blarg')
           except stem.ControllerError:
             pass
 
@@ -157,7 +157,7 @@ class TestBaseController(unittest.TestCase):
 
     with test.runner.get_runner().get_tor_socket() as control_socket:
       controller = ControlledListener(control_socket)
-      controller.msg("SETEVENTS BW")
+      controller.msg('SETEVENTS BW')
 
       # Wait for a couple events for events to be enqueued. Doing a bunch of
       # GETINFO queries while waiting to better exercise the asynchronous event
@@ -172,7 +172,7 @@ class TestBaseController(unittest.TestCase):
       # thread because it'll block on the event handling, which in turn is
       # currently blocking on the reveive_notice.
 
-      close_thread = threading.Thread(target = controller.close, name = "Closing controller")
+      close_thread = threading.Thread(target = controller.close, name = 'Closing controller')
       close_thread.setDaemon(True)
       close_thread.start()
 
@@ -185,9 +185,9 @@ class TestBaseController(unittest.TestCase):
       self.assertTrue(len(controller.received_events) >= 2)
 
       for bw_event in controller.received_events:
-        self.assertTrue(re.match("BW [0-9]+ [0-9]+", str(bw_event)))
-        self.assertTrue(re.match("650 BW [0-9]+ [0-9]+\r\n", bw_event.raw_content()))
-        self.assertEquals(("650", " "), bw_event.content()[0][:2])
+        self.assertTrue(re.match('BW [0-9]+ [0-9]+', str(bw_event)))
+        self.assertTrue(re.match('650 BW [0-9]+ [0-9]+\r\n', bw_event.raw_content()))
+        self.assertEquals(('650', ' '), bw_event.content()[0][:2])
 
   def test_get_latest_heartbeat(self):
     """
@@ -200,7 +200,7 @@ class TestBaseController(unittest.TestCase):
     # makes a getinfo query, then checks that the heartbeat is close to now
     with test.runner.get_runner().get_tor_socket() as control_socket:
       controller = stem.control.BaseController(control_socket)
-      controller.msg("GETINFO version")
+      controller.msg('GETINFO version')
       self.assertTrue((time.time() - controller.get_latest_heartbeat()) < 5)
 
   def test_status_notifications(self):
@@ -233,8 +233,8 @@ class TestBaseController(unittest.TestCase):
       state_observer.reset()
 
       # cause the socket to shut down without calling close()
-      controller.msg("Blarg!")
-      self.assertRaises(stem.SocketClosed, controller.msg, "blarg")
+      controller.msg('Blarg!')
+      self.assertRaises(stem.SocketClosed, controller.msg, 'blarg')
       self.assertEquals(controller, state_observer.controller)
       self.assertEquals(stem.control.State.CLOSED, state_observer.state)
       self.assertTrue(state_observer.timestamp <= time.time())
diff --git a/test/integ/control/controller.py b/test/integ/control/controller.py
index e8bfe3e..c428f25 100644
--- a/test/integ/control/controller.py
+++ b/test/integ/control/controller.py
@@ -49,7 +49,7 @@ class TestController(unittest.TestCase):
       with stem.control.Controller.from_port(port = test.runner.CONTROL_PORT) as controller:
         self.assertTrue(isinstance(controller, stem.control.Controller))
     else:
-      self.assertRaises(stem.SocketError, stem.control.Controller.from_port, "127.0.0.1", test.runner.CONTROL_PORT)
+      self.assertRaises(stem.SocketError, stem.control.Controller.from_port, '127.0.0.1', test.runner.CONTROL_PORT)
 
   def test_from_socket_file(self):
     """
@@ -103,7 +103,7 @@ class TestController(unittest.TestCase):
       self.assertEqual(State.RESET, state_type)
       self.assertTrue(state_timestamp > before and state_timestamp < after)
 
-      controller.reset_conf("__OwningControllerProcess")
+      controller.reset_conf('__OwningControllerProcess')
 
   def test_event_handling(self):
     """
@@ -257,28 +257,28 @@ class TestController(unittest.TestCase):
       # successful single query
 
       torrc_path = runner.get_torrc_path()
-      self.assertEqual(torrc_path, controller.get_info("config-file"))
-      self.assertEqual(torrc_path, controller.get_info("config-file", "ho hum"))
+      self.assertEqual(torrc_path, controller.get_info('config-file'))
+      self.assertEqual(torrc_path, controller.get_info('config-file', 'ho hum'))
 
-      expected = {"config-file": torrc_path}
-      self.assertEqual(expected, controller.get_info(["config-file"]))
-      self.assertEqual(expected, controller.get_info(["config-file"], "ho hum"))
+      expected = {'config-file': torrc_path}
+      self.assertEqual(expected, controller.get_info(['config-file']))
+      self.assertEqual(expected, controller.get_info(['config-file'], 'ho hum'))
 
       # successful batch query, we don't know the values so just checking for
       # the keys
 
-      getinfo_params = set(["version", "config-file", "config/names"])
-      self.assertEqual(getinfo_params, set(controller.get_info(["version", "config-file", "config/names"]).keys()))
+      getinfo_params = set(['version', 'config-file', 'config/names'])
+      self.assertEqual(getinfo_params, set(controller.get_info(['version', 'config-file', 'config/names']).keys()))
 
       # non-existant option
 
-      self.assertRaises(stem.ControllerError, controller.get_info, "blarg")
-      self.assertEqual("ho hum", controller.get_info("blarg", "ho hum"))
+      self.assertRaises(stem.ControllerError, controller.get_info, 'blarg')
+      self.assertEqual('ho hum', controller.get_info('blarg', 'ho hum'))
 
       # empty input
 
-      self.assertRaises(stem.ControllerError, controller.get_info, "")
-      self.assertEqual("ho hum", controller.get_info("", "ho hum"))
+      self.assertRaises(stem.ControllerError, controller.get_info, '')
+      self.assertEqual('ho hum', controller.get_info('', 'ho hum'))
 
       self.assertEqual({}, controller.get_info([]))
       self.assertEqual({}, controller.get_info([], {}))
@@ -405,55 +405,55 @@ class TestController(unittest.TestCase):
 
       if isinstance(control_socket, stem.socket.ControlPort):
         connection_value = str(control_socket.get_port())
-        config_key = "ControlPort"
+        config_key = 'ControlPort'
       elif isinstance(control_socket, stem.socket.ControlSocketFile):
         connection_value = str(control_socket.get_socket_path())
-        config_key = "ControlSocket"
+        config_key = 'ControlSocket'
 
       # successful single query
       self.assertEqual(connection_value, controller.get_conf(config_key))
-      self.assertEqual(connection_value, controller.get_conf(config_key, "la-di-dah"))
+      self.assertEqual(connection_value, controller.get_conf(config_key, 'la-di-dah'))
 
       # succeessful batch query
       expected = {config_key: [connection_value]}
       self.assertEqual(expected, controller.get_conf_map([config_key]))
-      self.assertEqual(expected, controller.get_conf_map([config_key], "la-di-dah"))
+      self.assertEqual(expected, controller.get_conf_map([config_key], 'la-di-dah'))
 
-      request_params = ["ControlPORT", "dirport", "datadirectory"]
+      request_params = ['ControlPORT', 'dirport', 'datadirectory']
       reply_params = controller.get_conf_map(request_params, multiple=False).keys()
       self.assertEqual(set(request_params), set(reply_params))
 
       # queries an option that is unset
 
-      self.assertEqual(None, controller.get_conf("HTTPSProxy"))
-      self.assertEqual("la-di-dah", controller.get_conf("HTTPSProxy", "la-di-dah"))
-      self.assertEqual([], controller.get_conf("HTTPSProxy", [], multiple = True))
+      self.assertEqual(None, controller.get_conf('HTTPSProxy'))
+      self.assertEqual('la-di-dah', controller.get_conf('HTTPSProxy', 'la-di-dah'))
+      self.assertEqual([], controller.get_conf('HTTPSProxy', [], multiple = True))
 
       # non-existant option(s)
-      self.assertRaises(stem.InvalidArguments, controller.get_conf, "blarg")
-      self.assertEqual("la-di-dah", controller.get_conf("blarg", "la-di-dah"))
-      self.assertRaises(stem.InvalidArguments, controller.get_conf_map, "blarg")
-      self.assertEqual({"blarg": "la-di-dah"}, controller.get_conf_map("blarg", "la-di-dah"))
+      self.assertRaises(stem.InvalidArguments, controller.get_conf, 'blarg')
+      self.assertEqual('la-di-dah', controller.get_conf('blarg', 'la-di-dah'))
+      self.assertRaises(stem.InvalidArguments, controller.get_conf_map, 'blarg')
+      self.assertEqual({'blarg': 'la-di-dah'}, controller.get_conf_map('blarg', 'la-di-dah'))
 
-      self.assertRaises(stem.InvalidRequest, controller.get_conf_map, ["blarg", "huadf"], multiple = True)
-      self.assertEqual({"erfusdj": "la-di-dah", "afiafj": "la-di-dah"}, controller.get_conf_map(["erfusdj", "afiafj"], "la-di-dah", multiple = True))
+      self.assertRaises(stem.InvalidRequest, controller.get_conf_map, ['blarg', 'huadf'], multiple = True)
+      self.assertEqual({'erfusdj': 'la-di-dah', 'afiafj': 'la-di-dah'}, controller.get_conf_map(['erfusdj', 'afiafj'], 'la-di-dah', multiple = True))
 
       # multivalue configuration keys
-      nodefamilies = [("abc", "xyz", "pqrs"), ("mno", "tuv", "wxyz")]
-      controller.msg("SETCONF %s" % " ".join(["nodefamily=\"" + ",".join(x) + "\"" for x in nodefamilies]))
-      self.assertEqual([",".join(n) for n in nodefamilies], controller.get_conf("nodefamily", multiple = True))
-      controller.msg("RESETCONF NodeFamily")
+      nodefamilies = [('abc', 'xyz', 'pqrs'), ('mno', 'tuv', 'wxyz')]
+      controller.msg('SETCONF %s' % ' '.join(['nodefamily="' + ','.join(x) + '"' for x in nodefamilies]))
+      self.assertEqual([','.join(n) for n in nodefamilies], controller.get_conf('nodefamily', multiple = True))
+      controller.msg('RESETCONF NodeFamily')
 
       # empty input
-      self.assertEqual(None, controller.get_conf(""))
+      self.assertEqual(None, controller.get_conf(''))
       self.assertEqual({}, controller.get_conf_map([]))
-      self.assertEqual({}, controller.get_conf_map([""]))
-      self.assertEqual(None, controller.get_conf("          "))
-      self.assertEqual({}, controller.get_conf_map(["    ", "        "]))
+      self.assertEqual({}, controller.get_conf_map(['']))
+      self.assertEqual(None, controller.get_conf('          '))
+      self.assertEqual({}, controller.get_conf_map(['    ', '        ']))
 
-      self.assertEqual("la-di-dah", controller.get_conf("", "la-di-dah"))
-      self.assertEqual({}, controller.get_conf_map("", "la-di-dah"))
-      self.assertEqual({}, controller.get_conf_map([], "la-di-dah"))
+      self.assertEqual('la-di-dah', controller.get_conf('', 'la-di-dah'))
+      self.assertEqual({}, controller.get_conf_map('', 'la-di-dah'))
+      self.assertEqual({}, controller.get_conf_map([], 'la-di-dah'))
 
   def test_set_conf(self):
     """
@@ -470,62 +470,62 @@ class TestController(unittest.TestCase):
     with runner.get_tor_controller() as controller:
       try:
         # successfully set a single option
-        connlimit = int(controller.get_conf("ConnLimit"))
-        controller.set_conf("connlimit", str(connlimit - 1))
-        self.assertEqual(connlimit - 1, int(controller.get_conf("ConnLimit")))
+        connlimit = int(controller.get_conf('ConnLimit'))
+        controller.set_conf('connlimit', str(connlimit - 1))
+        self.assertEqual(connlimit - 1, int(controller.get_conf('ConnLimit')))
 
         # successfully set a single list option
-        exit_policy = ["accept *:7777", "reject *:*"]
-        controller.set_conf("ExitPolicy", exit_policy)
-        self.assertEqual(exit_policy, controller.get_conf("ExitPolicy", multiple = True))
+        exit_policy = ['accept *:7777', 'reject *:*']
+        controller.set_conf('ExitPolicy', exit_policy)
+        self.assertEqual(exit_policy, controller.get_conf('ExitPolicy', multiple = True))
 
         # fail to set a single option
         try:
-          controller.set_conf("invalidkeyboo", "abcde")
+          controller.set_conf('invalidkeyboo', 'abcde')
           self.fail()
         except stem.InvalidArguments as exc:
-          self.assertEqual(["invalidkeyboo"], exc.arguments)
+          self.assertEqual(['invalidkeyboo'], exc.arguments)
 
         # resets configuration parameters
-        controller.reset_conf("ConnLimit", "ExitPolicy")
-        self.assertEqual(connlimit, int(controller.get_conf("ConnLimit")))
-        self.assertEqual(None, controller.get_conf("ExitPolicy"))
+        controller.reset_conf('ConnLimit', 'ExitPolicy')
+        self.assertEqual(connlimit, int(controller.get_conf('ConnLimit')))
+        self.assertEqual(None, controller.get_conf('ExitPolicy'))
 
         # successfully sets multiple config options
         controller.set_options({
-          "connlimit": str(connlimit - 2),
-          "contactinfo": "stem@testing",
+          'connlimit': str(connlimit - 2),
+          'contactinfo': 'stem@testing',
         })
 
-        self.assertEqual(connlimit - 2, int(controller.get_conf("ConnLimit")))
-        self.assertEqual("stem@testing", controller.get_conf("contactinfo"))
+        self.assertEqual(connlimit - 2, int(controller.get_conf('ConnLimit')))
+        self.assertEqual('stem@testing', controller.get_conf('contactinfo'))
 
         # fail to set multiple config options
         try:
           controller.set_options({
-            "contactinfo": "stem@testing",
-            "bombay": "vadapav",
+            'contactinfo': 'stem@testing',
+            'bombay': 'vadapav',
           })
           self.fail()
         except stem.InvalidArguments as exc:
-          self.assertEqual(["bombay"], exc.arguments)
+          self.assertEqual(['bombay'], exc.arguments)
 
         # context-sensitive keys (the only retched things for which order matters)
         controller.set_options((
-          ("HiddenServiceDir", tmpdir),
-          ("HiddenServicePort", "17234 127.0.0.1:17235"),
+          ('HiddenServiceDir', tmpdir),
+          ('HiddenServicePort', '17234 127.0.0.1:17235'),
         ))
 
-        self.assertEqual(tmpdir, controller.get_conf("HiddenServiceDir"))
-        self.assertEqual("17234 127.0.0.1:17235", controller.get_conf("HiddenServicePort"))
+        self.assertEqual(tmpdir, controller.get_conf('HiddenServiceDir'))
+        self.assertEqual('17234 127.0.0.1:17235', controller.get_conf('HiddenServicePort'))
       finally:
         # reverts configuration changes
         controller.set_options((
-          ("ExitPolicy", "reject *:*"),
-          ("ConnLimit", None),
-          ("ContactInfo", None),
-          ("HiddenServiceDir", None),
-          ("HiddenServicePort", None),
+          ('ExitPolicy', 'reject *:*'),
+          ('ConnLimit', None),
+          ('ContactInfo', None),
+          ('HiddenServiceDir', None),
+          ('HiddenServicePort', None),
         ), reset = True)
 
         shutil.rmtree(tmpdir)
@@ -554,22 +554,22 @@ class TestController(unittest.TestCase):
         #   ("/home/atagar/Desktop/stem/test/data"->"/home/atagar/.tor") is not
         #   allowed.
 
-        self.assertRaises(stem.InvalidRequest, controller.load_conf, "ContactInfo confloaded")
+        self.assertRaises(stem.InvalidRequest, controller.load_conf, 'ContactInfo confloaded')
 
         try:
-          controller.load_conf("Blahblah blah")
+          controller.load_conf('Blahblah blah')
           self.fail()
         except stem.InvalidArguments as exc:
-          self.assertEqual(["Blahblah"], exc.arguments)
+          self.assertEqual(['Blahblah'], exc.arguments)
 
         # valid config
 
-        controller.load_conf(runner.get_torrc_contents() + "\nContactInfo confloaded\n")
-        self.assertEqual("confloaded", controller.get_conf("ContactInfo"))
+        controller.load_conf(runner.get_torrc_contents() + '\nContactInfo confloaded\n')
+        self.assertEqual('confloaded', controller.get_conf('ContactInfo'))
       finally:
         # reload original valid config
         controller.load_conf(oldconf)
-        controller.reset_conf("__OwningControllerProcess")
+        controller.reset_conf('__OwningControllerProcess')
 
   def test_saveconf(self):
     if test.runner.require_control(self):
@@ -583,15 +583,15 @@ class TestController(unittest.TestCase):
       oldconf = runner.get_torrc_contents()
 
       try:
-        controller.set_conf("ContactInfo", "confsaved")
+        controller.set_conf('ContactInfo', 'confsaved')
         controller.save_conf()
 
         with open(runner.get_torrc_path()) as torrcfile:
-          self.assertTrue("\nContactInfo confsaved\n" in torrcfile.read())
+          self.assertTrue('\nContactInfo confsaved\n' in torrcfile.read())
       finally:
         controller.load_conf(oldconf)
         controller.save_conf()
-        controller.reset_conf("__OwningControllerProcess")
+        controller.reset_conf('__OwningControllerProcess')
 
   def test_get_ports(self):
     """
@@ -663,10 +663,10 @@ class TestController(unittest.TestCase):
     runner = test.runner.get_runner()
 
     with runner.get_tor_controller() as controller:
-      if not test.runner.require_version(self, stem.version.Version("0.1.2.2-alpha")):
-        controller.enable_feature("VERBOSE_NAMES")
+      if not test.runner.require_version(self, stem.version.Version('0.1.2.2-alpha')):
+        controller.enable_feature('VERBOSE_NAMES')
 
-      self.assertTrue(controller.is_feature_enabled("VERBOSE_NAMES"))
+      self.assertTrue(controller.is_feature_enabled('VERBOSE_NAMES'))
 
       orconn_output = controller.get_info('orconn-status')
 
@@ -675,13 +675,13 @@ class TestController(unittest.TestCase):
         if test.runner.require_online(self):
           return
 
-      self.assertTrue("VERBOSE_NAMES" in controller._enabled_features)
-      self.assertRaises(stem.InvalidArguments, controller.enable_feature, ["NOT", "A", "FEATURE"])
+      self.assertTrue('VERBOSE_NAMES' in controller._enabled_features)
+      self.assertRaises(stem.InvalidArguments, controller.enable_feature, ['NOT', 'A', 'FEATURE'])
 
       try:
-        controller.enable_feature(["NOT", "A", "FEATURE"])
+        controller.enable_feature(['NOT', 'A', 'FEATURE'])
       except stem.InvalidArguments as exc:
-        self.assertEqual(["NOT"], exc.arguments)
+        self.assertEqual(['NOT'], exc.arguments)
       else:
         self.fail()
 
@@ -695,10 +695,10 @@ class TestController(unittest.TestCase):
 
     with test.runner.get_runner().get_tor_controller() as controller:
       # valid signal
-      controller.signal("CLEARDNSCACHE")
+      controller.signal('CLEARDNSCACHE')
 
       # invalid signals
-      self.assertRaises(stem.InvalidArguments, controller.signal, "FOOBAR")
+      self.assertRaises(stem.InvalidArguments, controller.signal, 'FOOBAR')
 
   def test_newnym_availability(self):
     """
@@ -733,9 +733,9 @@ class TestController(unittest.TestCase):
       circuit_id = controller.new_circuit()
       self.assertNotEqual(None, controller.get_circuit(circuit_id, None))
 
-      self.assertRaises(stem.InvalidRequest, controller.extend_circuit, "foo")
-      self.assertRaises(stem.InvalidRequest, controller.extend_circuit, '0', "thisroutershouldntexistbecausestemexists!@##$%#")
-      self.assertRaises(stem.InvalidRequest, controller.extend_circuit, '0', "thisroutershouldntexistbecausestemexists!@##$%#", "foo")
+      self.assertRaises(stem.InvalidRequest, controller.extend_circuit, 'foo')
+      self.assertRaises(stem.InvalidRequest, controller.extend_circuit, '0', 'thisroutershouldntexistbecausestemexists!@##$%#')
+      self.assertRaises(stem.InvalidRequest, controller.extend_circuit, '0', 'thisroutershouldntexistbecausestemexists!@##$%#', 'foo')
 
   def test_repurpose_circuit(self):
     """
@@ -753,16 +753,16 @@ class TestController(unittest.TestCase):
 
     with runner.get_tor_controller() as controller:
       circ_id = controller.new_circuit()
-      controller.repurpose_circuit(circ_id, "CONTROLLER")
+      controller.repurpose_circuit(circ_id, 'CONTROLLER')
       circuit = controller.get_circuit(circ_id)
-      self.assertTrue(circuit.purpose == "CONTROLLER")
+      self.assertTrue(circuit.purpose == 'CONTROLLER')
 
-      controller.repurpose_circuit(circ_id, "GENERAL")
+      controller.repurpose_circuit(circ_id, 'GENERAL')
       circuit = controller.get_circuit(circ_id)
-      self.assertTrue(circuit.purpose == "GENERAL")
+      self.assertTrue(circuit.purpose == 'GENERAL')
 
-      self.assertRaises(stem.InvalidRequest, controller.repurpose_circuit, 'f934h9f3h4', "fooo")
-      self.assertRaises(stem.InvalidRequest, controller.repurpose_circuit, '4', "fooo")
+      self.assertRaises(stem.InvalidRequest, controller.repurpose_circuit, 'f934h9f3h4', 'fooo')
+      self.assertRaises(stem.InvalidRequest, controller.repurpose_circuit, '4', 'fooo')
 
   def test_close_circuit(self):
     """
@@ -781,19 +781,19 @@ class TestController(unittest.TestCase):
     with runner.get_tor_controller() as controller:
       circuit_id = controller.new_circuit()
       controller.close_circuit(circuit_id)
-      circuit_output = controller.get_info("circuit-status")
+      circuit_output = controller.get_info('circuit-status')
       circ = [x.split()[0] for x in circuit_output.splitlines()]
       self.assertFalse(circuit_id in circ)
 
       circuit_id = controller.new_circuit()
-      controller.close_circuit(circuit_id, "IfUnused")
-      circuit_output = controller.get_info("circuit-status")
+      controller.close_circuit(circuit_id, 'IfUnused')
+      circuit_output = controller.get_info('circuit-status')
       circ = [x.split()[0] for x in circuit_output.splitlines()]
       self.assertFalse(circuit_id in circ)
 
       circuit_id = controller.new_circuit()
-      self.assertRaises(stem.InvalidArguments, controller.close_circuit, circuit_id + "1024")
-      self.assertRaises(stem.InvalidRequest, controller.close_circuit, "")
+      self.assertRaises(stem.InvalidArguments, controller.close_circuit, circuit_id + '1024')
+      self.assertRaises(stem.InvalidRequest, controller.close_circuit, '')
 
   def test_get_streams(self):
     """
@@ -805,7 +805,7 @@ class TestController(unittest.TestCase):
     elif test.runner.require_online(self):
       return
 
-    host = "38.229.72.14"   # www.torproject.org
+    host = '38.229.72.14'   # www.torproject.org
     port = 443
 
     runner = test.runner.get_runner()
@@ -821,7 +821,7 @@ class TestController(unittest.TestCase):
     # Because we do not get a stream id when opening a stream,
     #  try to match the target for which we asked a stream.
 
-    self.assertTrue("%s:%s" % (host, port) in [stream.target for stream in streams])
+    self.assertTrue('%s:%s' % (host, port) in [stream.target for stream in streams])
 
   def test_close_stream(self):
     """
@@ -837,22 +837,33 @@ class TestController(unittest.TestCase):
 
     with runner.get_tor_controller() as controller:
       # use the first socks listener
+
       socks_listener = controller.get_socks_listeners()[0]
+
       with test.network.Socks(socks_listener) as s:
         s.settimeout(30)
-        s.connect(("www.torproject.org", 443))
+        s.connect(('www.torproject.org', 443))
+
         # There's only one stream right now.  Right?
+
         built_stream = controller.get_streams()[0]
+
         # Make sure we have the stream for which we asked, otherwise
         # the next assertion would be a false positive.
+
         self.assertEqual([built_stream.id], [stream.id for stream in controller.get_streams()])
+
         # Try to close our stream...
+
         controller.close_stream(built_stream.id)
+
         # ...which means there are zero streams.
+
         self.assertEqual([], controller.get_streams())
 
       # unknown stream
-      self.assertRaises(stem.InvalidArguments, controller.close_stream, "blarg")
+
+      self.assertRaises(stem.InvalidArguments, controller.close_stream, 'blarg')
 
   def test_mapaddress(self):
     if test.runner.require_control(self):
@@ -869,6 +880,7 @@ class TestController(unittest.TestCase):
       response = None
 
       # try up to 10 times to rule out transient network failures
+
       for _ in xrange(10):
         try:
           s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -890,8 +902,8 @@ class TestController(unittest.TestCase):
 
       # everything after the blank line is the 'data' in a HTTP response.
       # The response data for our request for request should be an IP address + '\n'
-      ip_addr = response[response.find(b"\r\n\r\n"):].strip()
 
+      ip_addr = response[response.find(b'\r\n\r\n'):].strip()
       self.assertTrue(stem.util.connection.is_valid_ipv4_address(stem.util.str_tools._to_unicode(ip_addr)))
 
   def test_get_microdescriptor(self):
@@ -907,13 +919,13 @@ class TestController(unittest.TestCase):
     with test.runner.get_runner().get_tor_controller() as controller:
       # we should balk at invalid content
       self.assertRaises(ValueError, controller.get_microdescriptor, None)
-      self.assertRaises(ValueError, controller.get_microdescriptor, "")
+      self.assertRaises(ValueError, controller.get_microdescriptor, '')
       self.assertRaises(ValueError, controller.get_microdescriptor, 5)
-      self.assertRaises(ValueError, controller.get_microdescriptor, "z" * 30)
+      self.assertRaises(ValueError, controller.get_microdescriptor, 'z' * 30)
 
       # try with a relay that doesn't exist
-      self.assertRaises(stem.ControllerError, controller.get_microdescriptor, "blargg")
-      self.assertRaises(stem.ControllerError, controller.get_microdescriptor, "5" * 40)
+      self.assertRaises(stem.ControllerError, controller.get_microdescriptor, 'blargg')
+      self.assertRaises(stem.ControllerError, controller.get_microdescriptor, '5' * 40)
 
       test_relay = self._get_router_status_entry(controller)
 
@@ -931,8 +943,8 @@ class TestController(unittest.TestCase):
 
     if test.runner.require_control(self):
       return
-    elif not os.path.exists(runner.get_test_dir("cached-descriptors")):
-      test.runner.skip(self, "(no cached microdescriptors)")
+    elif not os.path.exists(runner.get_test_dir('cached-descriptors')):
+      test.runner.skip(self, '(no cached microdescriptors)')
       return
 
     with runner.get_tor_controller() as controller:
@@ -955,19 +967,19 @@ class TestController(unittest.TestCase):
     if test.runner.require_control(self):
       return
     elif runner.get_tor_version() >= Requirement.MICRODESCRIPTOR_IS_DEFAULT:
-      test.runner.skip(self, "(requires server descriptors)")
+      test.runner.skip(self, '(requires server descriptors)')
       return
 
     with runner.get_tor_controller() as controller:
       # we should balk at invalid content
       self.assertRaises(ValueError, controller.get_server_descriptor, None)
-      self.assertRaises(ValueError, controller.get_server_descriptor, "")
+      self.assertRaises(ValueError, controller.get_server_descriptor, '')
       self.assertRaises(ValueError, controller.get_server_descriptor, 5)
-      self.assertRaises(ValueError, controller.get_server_descriptor, "z" * 30)
+      self.assertRaises(ValueError, controller.get_server_descriptor, 'z' * 30)
 
       # try with a relay that doesn't exist
-      self.assertRaises(stem.ControllerError, controller.get_server_descriptor, "blargg")
-      self.assertRaises(stem.ControllerError, controller.get_server_descriptor, "5" * 40)
+      self.assertRaises(stem.ControllerError, controller.get_server_descriptor, 'blargg')
+      self.assertRaises(stem.ControllerError, controller.get_server_descriptor, '5' * 40)
 
       test_relay = self._get_router_status_entry(controller)
 
@@ -986,7 +998,7 @@ class TestController(unittest.TestCase):
     if test.runner.require_control(self):
       return
     elif runner.get_tor_version() >= Requirement.MICRODESCRIPTOR_IS_DEFAULT:
-      test.runner.skip(self, "(requires server descriptors)")
+      test.runner.skip(self, '(requires server descriptors)')
       return
 
     with runner.get_tor_controller() as controller:
@@ -1015,13 +1027,13 @@ class TestController(unittest.TestCase):
     with test.runner.get_runner().get_tor_controller() as controller:
       # we should balk at invalid content
       self.assertRaises(ValueError, controller.get_network_status, None)
-      self.assertRaises(ValueError, controller.get_network_status, "")
+      self.assertRaises(ValueError, controller.get_network_status, '')
       self.assertRaises(ValueError, controller.get_network_status, 5)
-      self.assertRaises(ValueError, controller.get_network_status, "z" * 30)
+      self.assertRaises(ValueError, controller.get_network_status, 'z' * 30)
 
       # try with a relay that doesn't exist
-      self.assertRaises(stem.ControllerError, controller.get_network_status, "blargg")
-      self.assertRaises(stem.ControllerError, controller.get_network_status, "5" * 40)
+      self.assertRaises(stem.ControllerError, controller.get_network_status, 'blargg')
+      self.assertRaises(stem.ControllerError, controller.get_network_status, '5' * 40)
 
       test_relay = self._get_router_status_entry(controller)
 
@@ -1050,7 +1062,7 @@ class TestController(unittest.TestCase):
         unrecognized_lines = desc.get_unrecognized_lines()
 
         if unrecognized_lines:
-          self.fail("Unrecognized descriptor content: %s" % unrecognized_lines)
+          self.fail('Unrecognized descriptor content: %s' % unrecognized_lines)
 
         count += 1
         if count > 10:
@@ -1064,20 +1076,20 @@ class TestController(unittest.TestCase):
     elif test.runner.require_version(self, Requirement.EXTENDCIRCUIT_PATH_OPTIONAL):
       return
 
-    host = "38.229.72.14"   # www.torproject.org
+    host = '38.229.72.14'   # www.torproject.org
     port = 80
 
     circuit_id = None
 
     def handle_streamcreated(stream):
-      if stream.status == "NEW" and circuit_id:
+      if stream.status == 'NEW' and circuit_id:
         controller.attach_stream(stream.id, circuit_id)
 
     with test.runner.get_runner().get_tor_controller() as controller:
       # try 10 times to build a circuit we can connect through
       for i in xrange(10):
         controller.add_event_listener(handle_streamcreated, stem.control.EventType.STREAM)
-        controller.set_conf("__LeaveStreamsUnattached", "1")
+        controller.set_conf('__LeaveStreamsUnattached', '1')
 
         try:
           circuit_id = controller.new_circuit(await_build = True)
@@ -1092,7 +1104,7 @@ class TestController(unittest.TestCase):
           continue
         finally:
           controller.remove_event_listener(handle_streamcreated)
-          controller.reset_conf("__LeaveStreamsUnattached")
+          controller.reset_conf('__LeaveStreamsUnattached')
 
     our_stream = [stream for stream in streams if stream.target_address == host][0]
 
@@ -1129,13 +1141,13 @@ class TestController(unittest.TestCase):
 
     if TEST_ROUTER_STATUS_ENTRY is None:
       for desc in controller.get_network_statuses():
-        if desc.nickname != "Unnamed" and Flag.NAMED in desc.flags:
+        if desc.nickname != 'Unnamed' and Flag.NAMED in desc.flags:
           TEST_ROUTER_STATUS_ENTRY = desc
           break
 
       if TEST_ROUTER_STATUS_ENTRY is None:
         # this is only likely to occure if we can't get descriptors
-        test.runner.skip(self, "(no named relays)")
+        test.runner.skip(self, '(no named relays)')
         return
 
     return TEST_ROUTER_STATUS_ENTRY
diff --git a/test/integ/descriptor/__init__.py b/test/integ/descriptor/__init__.py
index 57083e9..3a0f156 100644
--- a/test/integ/descriptor/__init__.py
+++ b/test/integ/descriptor/__init__.py
@@ -3,17 +3,17 @@ Integration tests for stem.descriptor.* contents.
 """
 
 __all__ = [
-  "reader",
-  "extrainfo_descriptor",
-  "microdescriptor",
-  "server_descriptor",
-  "get_resource",
-  "open_desc",
+  'reader',
+  'extrainfo_descriptor',
+  'microdescriptor',
+  'server_descriptor',
+  'get_resource',
+  'open_desc',
 ]
 
 import os
 
-DESCRIPTOR_TEST_DATA = os.path.join(os.path.dirname(__file__), "data")
+DESCRIPTOR_TEST_DATA = os.path.join(os.path.dirname(__file__), 'data')
 
 
 def get_resource(filename):
diff --git a/test/integ/descriptor/extrainfo_descriptor.py b/test/integ/descriptor/extrainfo_descriptor.py
index 35faec9..377173a 100644
--- a/test/integ/descriptor/extrainfo_descriptor.py
+++ b/test/integ/descriptor/extrainfo_descriptor.py
@@ -19,7 +19,7 @@ class TestExtraInfoDescriptor(unittest.TestCase):
     Parses and checks our results against an extrainfo descriptor from metrics.
     """
 
-    descriptor_file = open(get_resource("extrainfo_relay_descriptor"), 'rb')
+    descriptor_file = open(get_resource('extrainfo_relay_descriptor'), 'rb')
 
     expected_signature = """-----BEGIN SIGNATURE-----
 K5FSywk7qvw/boA4DQcqkls6Ize5vcBYfhQ8JnOeRQC9+uDxbnpm3qaYN9jZ8myj
@@ -27,9 +27,9 @@ k0d2aofcVbHr4fPQOSST0LXDrhFl5Fqo5um296zpJGvRUeO6S44U/EfJAGShtqWw
 7LZqklu+gVvhMKREpchVqlAwXkWR44VENm24Hs+mT3M=
 -----END SIGNATURE-----"""
 
-    desc = next(stem.descriptor.parse_file(descriptor_file, "extra-info 1.0"))
-    self.assertEquals("NINJA", desc.nickname)
-    self.assertEquals("B2289C3EAB83ECD6EB916A2F481A02E6B76A0A48", desc.fingerprint)
+    desc = next(stem.descriptor.parse_file(descriptor_file, 'extra-info 1.0'))
+    self.assertEquals('NINJA', desc.nickname)
+    self.assertEquals('B2289C3EAB83ECD6EB916A2F481A02E6B76A0A48', desc.fingerprint)
     self.assertEquals(datetime.datetime(2012, 5, 5, 17, 3, 50), desc.published)
     self.assertEquals(datetime.datetime(2012, 5, 5, 17, 2, 45), desc.read_history_end)
     self.assertEquals(900, desc.read_history_interval)
@@ -40,7 +40,7 @@ k0d2aofcVbHr4fPQOSST0LXDrhFl5Fqo5um296zpJGvRUeO6S44U/EfJAGShtqWw
     self.assertEquals(datetime.datetime(2012, 5, 5, 17, 2, 45), desc.dir_write_history_end)
     self.assertEquals(900, desc.dir_write_history_interval)
     self.assertEquals(expected_signature, desc.signature)
-    self.assertEquals("00A57A9AAB5EA113898E2DD02A755E31AFC27227", desc.digest())
+    self.assertEquals('00A57A9AAB5EA113898E2DD02A755E31AFC27227', desc.digest())
     self.assertEquals([], desc.get_unrecognized_lines())
 
     # The read-history, write-history, dirreq-read-history, and
@@ -65,7 +65,7 @@ k0d2aofcVbHr4fPQOSST0LXDrhFl5Fqo5um296zpJGvRUeO6S44U/EfJAGShtqWw
     metrics.
     """
 
-    descriptor_file = open(get_resource("extrainfo_bridge_descriptor"), 'rb')
+    descriptor_file = open(get_resource('extrainfo_bridge_descriptor'), 'rb')
 
     expected_dir_v2_responses = {
       DirResponse.OK: 0,
@@ -84,9 +84,9 @@ k0d2aofcVbHr4fPQOSST0LXDrhFl5Fqo5um296zpJGvRUeO6S44U/EfJAGShtqWw
       DirResponse.BUSY: 0,
     }
 
-    desc = next(stem.descriptor.parse_file(descriptor_file, "bridge-extra-info 1.0"))
-    self.assertEquals("ec2bridgereaac65a3", desc.nickname)
-    self.assertEquals("1EC248422B57D9C0BD751892FE787585407479A4", desc.fingerprint)
+    desc = next(stem.descriptor.parse_file(descriptor_file, 'bridge-extra-info 1.0'))
+    self.assertEquals('ec2bridgereaac65a3', desc.nickname)
+    self.assertEquals('1EC248422B57D9C0BD751892FE787585407479A4', desc.fingerprint)
     self.assertEquals(datetime.datetime(2012, 6, 8, 2, 21, 27), desc.published)
     self.assertEquals(datetime.datetime(2012, 6, 8, 2, 10, 38), desc.read_history_end)
     self.assertEquals(900, desc.read_history_interval)
@@ -96,7 +96,7 @@ k0d2aofcVbHr4fPQOSST0LXDrhFl5Fqo5um296zpJGvRUeO6S44U/EfJAGShtqWw
     self.assertEquals(900, desc.dir_read_history_interval)
     self.assertEquals(datetime.datetime(2012, 6, 8, 2, 10, 38), desc.dir_write_history_end)
     self.assertEquals(900, desc.dir_write_history_interval)
-    self.assertEquals("00A2AECCEAD3FEE033CFE29893387143146728EC", desc.digest())
+    self.assertEquals('00A2AECCEAD3FEE033CFE29893387143146728EC', desc.digest())
     self.assertEquals([], desc.get_unrecognized_lines())
 
     read_values_start = [337920, 437248, 3995648, 48726016]
@@ -129,29 +129,29 @@ k0d2aofcVbHr4fPQOSST0LXDrhFl5Fqo5um296zpJGvRUeO6S44U/EfJAGShtqWw
 
     # lengthy test and uneffected by targets, so only run once
 
-    if test.runner.only_run_once(self, "test_cached_descriptor"):
+    if test.runner.only_run_once(self, 'test_cached_descriptor'):
       return
 
-    descriptor_path = test.runner.get_runner().get_test_dir("cached-extrainfo")
+    descriptor_path = test.runner.get_runner().get_test_dir('cached-extrainfo')
 
     if not os.path.exists(descriptor_path):
-      test.runner.skip(self, "(no cached descriptors)")
+      test.runner.skip(self, '(no cached descriptors)')
       return
 
     with open(descriptor_path, 'rb') as descriptor_file:
-      for desc in stem.descriptor.parse_file(descriptor_file, "extra-info 1.0"):
+      for desc in stem.descriptor.parse_file(descriptor_file, 'extra-info 1.0'):
         unrecognized_lines = desc.get_unrecognized_lines()
 
         if desc.dir_v2_responses_unknown:
-          self.fail("Unrecognized statuses on dirreq-v2-resp lines: %s" % desc.dir_v2_responses_unknown)
+          self.fail('Unrecognized statuses on dirreq-v2-resp lines: %s' % desc.dir_v2_responses_unknown)
         elif desc.dir_v3_responses_unknown:
-          self.fail("Unrecognized statuses on dirreq-v3-resp lines: %s" % desc.dir_v3_responses_unknown)
+          self.fail('Unrecognized statuses on dirreq-v3-resp lines: %s' % desc.dir_v3_responses_unknown)
         elif desc.dir_v2_direct_dl_unknown:
-          self.fail("Unrecognized stats on dirreq-v2-direct-dl lines: %s" % desc.dir_v2_direct_dl_unknown)
+          self.fail('Unrecognized stats on dirreq-v2-direct-dl lines: %s' % desc.dir_v2_direct_dl_unknown)
         elif desc.dir_v3_direct_dl_unknown:
-          self.fail("Unrecognized stats on dirreq-v3-direct-dl lines: %s" % desc.dir_v2_direct_dl_unknown)
+          self.fail('Unrecognized stats on dirreq-v3-direct-dl lines: %s' % desc.dir_v2_direct_dl_unknown)
         elif desc.dir_v2_tunneled_dl_unknown:
-          self.fail("Unrecognized stats on dirreq-v2-tunneled-dl lines: %s" % desc.dir_v2_tunneled_dl_unknown)
+          self.fail('Unrecognized stats on dirreq-v2-tunneled-dl lines: %s' % desc.dir_v2_tunneled_dl_unknown)
         elif unrecognized_lines:
           # TODO: This isn't actually a problem, and rather than failing we
           # should alert the user about these entries at the end of the tests
@@ -159,4 +159,4 @@ k0d2aofcVbHr4fPQOSST0LXDrhFl5Fqo5um296zpJGvRUeO6S44U/EfJAGShtqWw
           # there doesn't seem to be anything in practice to trigger this so
           # failing to get our attention if it does.
 
-          self.fail("Unrecognized descriptor content: %s" % unrecognized_lines)
+          self.fail('Unrecognized descriptor content: %s' % unrecognized_lines)
diff --git a/test/integ/descriptor/microdescriptor.py b/test/integ/descriptor/microdescriptor.py
index 65e47e3..f7dadfd 100644
--- a/test/integ/descriptor/microdescriptor.py
+++ b/test/integ/descriptor/microdescriptor.py
@@ -44,55 +44,55 @@ class TestMicrodescriptor(unittest.TestCase):
     descriptor additions.
     """
 
-    if test.runner.only_run_once(self, "test_cached_microdescriptors"):
+    if test.runner.only_run_once(self, 'test_cached_microdescriptors'):
       return
 
-    descriptor_path = test.runner.get_runner().get_test_dir("cached-microdescs")
+    descriptor_path = test.runner.get_runner().get_test_dir('cached-microdescs')
 
     if not os.path.exists(descriptor_path):
-      test.runner.skip(self, "(no cached microdescriptors)")
+      test.runner.skip(self, '(no cached microdescriptors)')
       return
 
     with open(descriptor_path, 'rb') as descriptor_file:
-      for desc in stem.descriptor.parse_file(descriptor_file, "microdescriptor 1.0"):
+      for desc in stem.descriptor.parse_file(descriptor_file, 'microdescriptor 1.0'):
         unrecognized_lines = desc.get_unrecognized_lines()
 
         if unrecognized_lines:
-          self.fail("Unrecognized microdescriptor content: %s" % unrecognized_lines)
+          self.fail('Unrecognized microdescriptor content: %s' % unrecognized_lines)
 
   def test_local_microdescriptors(self):
     """
     Checks a small microdescriptor file with known contents.
     """
 
-    descriptor_path = get_resource("cached-microdescs")
+    descriptor_path = get_resource('cached-microdescs')
 
     with open(descriptor_path, 'rb') as descriptor_file:
-      descriptors = stem.descriptor.parse_file(descriptor_file, "microdescriptor 1.0")
+      descriptors = stem.descriptor.parse_file(descriptor_file, 'microdescriptor 1.0')
 
       router = next(descriptors)
       self.assertEquals(FIRST_ONION_KEY, router.onion_key)
       self.assertEquals(None, router.ntor_onion_key)
       self.assertEquals([], router.or_addresses)
       self.assertEquals([], router.family)
-      self.assertEquals(stem.exit_policy.MicroExitPolicy("reject 1-65535"), router.exit_policy)
-      self.assertEquals({b"@last-listed": b"2013-02-24 00:18:36"}, router.get_annotations())
-      self.assertEquals([b"@last-listed 2013-02-24 00:18:36"], router.get_annotation_lines())
+      self.assertEquals(stem.exit_policy.MicroExitPolicy('reject 1-65535'), router.exit_policy)
+      self.assertEquals({b'@last-listed': b'2013-02-24 00:18:36'}, router.get_annotations())
+      self.assertEquals([b'@last-listed 2013-02-24 00:18:36'], router.get_annotation_lines())
 
       router = next(descriptors)
       self.assertEquals(SECOND_ONION_KEY, router.onion_key)
       self.assertEquals(u'r5572HzD+PMPBbXlZwBhsm6YEbxnYgis8vhZ1jmdI2k=', router.ntor_onion_key)
       self.assertEquals([], router.or_addresses)
-      self.assertEquals(["$6141629FA0D15A6AEAEF3A1BEB76E64C767B3174"], router.family)
-      self.assertEquals(stem.exit_policy.MicroExitPolicy("reject 1-65535"), router.exit_policy)
-      self.assertEquals({b"@last-listed": b"2013-02-24 00:18:37"}, router.get_annotations())
-      self.assertEquals([b"@last-listed 2013-02-24 00:18:37"], router.get_annotation_lines())
+      self.assertEquals(['$6141629FA0D15A6AEAEF3A1BEB76E64C767B3174'], router.family)
+      self.assertEquals(stem.exit_policy.MicroExitPolicy('reject 1-65535'), router.exit_policy)
+      self.assertEquals({b'@last-listed': b'2013-02-24 00:18:37'}, router.get_annotations())
+      self.assertEquals([b'@last-listed 2013-02-24 00:18:37'], router.get_annotation_lines())
 
       router = next(descriptors)
       self.assertEquals(THIRD_ONION_KEY, router.onion_key)
       self.assertEquals(None, router.ntor_onion_key)
-      self.assertEquals([(u"2001:6b0:7:125::242", 9001, True)], router.or_addresses)
+      self.assertEquals([(u'2001:6b0:7:125::242', 9001, True)], router.or_addresses)
       self.assertEquals([], router.family)
-      self.assertEquals(stem.exit_policy.MicroExitPolicy("accept 80,443"), router.exit_policy)
-      self.assertEquals({b"@last-listed": b"2013-02-24 00:18:36"}, router.get_annotations())
-      self.assertEquals([b"@last-listed 2013-02-24 00:18:36"], router.get_annotation_lines())
+      self.assertEquals(stem.exit_policy.MicroExitPolicy('accept 80,443'), router.exit_policy)
+      self.assertEquals({b'@last-listed': b'2013-02-24 00:18:36'}, router.get_annotations())
+      self.assertEquals([b'@last-listed 2013-02-24 00:18:36'], router.get_annotation_lines())
diff --git a/test/integ/descriptor/networkstatus.py b/test/integ/descriptor/networkstatus.py
index 5209f51..3054eea 100644
--- a/test/integ/descriptor/networkstatus.py
+++ b/test/integ/descriptor/networkstatus.py
@@ -23,24 +23,24 @@ class TestNetworkStatus(unittest.TestCase):
 
     # lengthy test and uneffected by targets, so only run once
 
-    if test.runner.only_run_once(self, "test_cached_consensus"):
+    if test.runner.only_run_once(self, 'test_cached_consensus'):
       return
 
-    consensus_path = test.runner.get_runner().get_test_dir("cached-consensus")
+    consensus_path = test.runner.get_runner().get_test_dir('cached-consensus')
 
     if not os.path.exists(consensus_path):
-      test.runner.skip(self, "(no cached-consensus)")
+      test.runner.skip(self, '(no cached-consensus)')
       return
     elif stem.util.system.is_windows():
       # Unable to check memory usage on windows, so can't prevent hanging the
       # system if things go bad.
 
-      test.runner.skip(self, "(unavailable on windows)")
+      test.runner.skip(self, '(unavailable on windows)')
       return
 
     count = 0
     with open(consensus_path, 'rb') as descriptor_file:
-      for router in stem.descriptor.parse_file(descriptor_file, "network-status-consensus-3 1.0"):
+      for router in stem.descriptor.parse_file(descriptor_file, 'network-status-consensus-3 1.0'):
         count += 1
 
         # check if there's any unknown flags
@@ -48,12 +48,12 @@ class TestNetworkStatus(unittest.TestCase):
         # failing the tests
         for flag in router.flags:
           if not flag in stem.Flag:
-            raise ValueError("Unrecognized flag type: %s, found on relay %s (%s)" % (flag, router.fingerprint, router.nickname))
+            raise ValueError('Unrecognized flag type: %s, found on relay %s (%s)' % (flag, router.fingerprint, router.nickname))
 
         unrecognized_lines = router.get_unrecognized_lines()
 
         if unrecognized_lines:
-          self.fail("Unrecognized descriptor content: %s" % unrecognized_lines)
+          self.fail('Unrecognized descriptor content: %s' % unrecognized_lines)
 
     # Sanity test that there's at least a hundred relays. If that's not the
     # case then this probably isn't a real, complete tor consensus.
@@ -67,21 +67,21 @@ class TestNetworkStatus(unittest.TestCase):
 
     # lengthy test and uneffected by targets, so only run once
 
-    if test.runner.only_run_once(self, "test_cached_microdesc_consensus"):
+    if test.runner.only_run_once(self, 'test_cached_microdesc_consensus'):
       return
 
-    consensus_path = test.runner.get_runner().get_test_dir("cached-microdesc-consensus")
+    consensus_path = test.runner.get_runner().get_test_dir('cached-microdesc-consensus')
 
     if not os.path.exists(consensus_path):
-      test.runner.skip(self, "(no cached-microdesc-consensus)")
+      test.runner.skip(self, '(no cached-microdesc-consensus)')
       return
     elif stem.util.system.is_windows():
-      test.runner.skip(self, "(unavailable on windows)")
+      test.runner.skip(self, '(unavailable on windows)')
       return
 
     count = 0
     with open(consensus_path, 'rb') as descriptor_file:
-      for router in stem.descriptor.parse_file(descriptor_file, "network-status-microdesc-consensus-3 1.0"):
+      for router in stem.descriptor.parse_file(descriptor_file, 'network-status-microdesc-consensus-3 1.0'):
         count += 1
 
         # check if there's any unknown flags
@@ -89,12 +89,12 @@ class TestNetworkStatus(unittest.TestCase):
         # failing the tests
         for flag in router.flags:
           if not flag in stem.Flag:
-            raise ValueError("Unrecognized flag type: %s, found on microdescriptor relay %s (%s)" % (flag, router.fingerprint, router.nickname))
+            raise ValueError('Unrecognized flag type: %s, found on microdescriptor relay %s (%s)' % (flag, router.fingerprint, router.nickname))
 
         unrecognized_lines = router.get_unrecognized_lines()
 
         if unrecognized_lines:
-          self.fail("Unrecognized descriptor content: %s" % unrecognized_lines)
+          self.fail('Unrecognized descriptor content: %s' % unrecognized_lines)
 
     self.assertTrue(count > 100)
 
@@ -103,21 +103,21 @@ class TestNetworkStatus(unittest.TestCase):
     Checks if consensus documents from Metrics are parsed properly.
     """
 
-    consensus_path = get_resource("metrics_consensus")
+    consensus_path = get_resource('metrics_consensus')
 
     for specify_type in (True, False):
       with open(consensus_path, 'rb') as descriptor_file:
         if specify_type:
-          descriptors = stem.descriptor.parse_file(descriptor_file, "network-status-consensus-3 1.0")
+          descriptors = stem.descriptor.parse_file(descriptor_file, 'network-status-consensus-3 1.0')
         else:
           descriptors = stem.descriptor.parse_file(descriptor_file)
 
         router = next(descriptors)
-        self.assertEquals("sumkledi", router.nickname)
-        self.assertEquals("0013D22389CD50D0B784A3E4061CB31E8CE8CEB5", router.fingerprint)
-        self.assertEquals("F260ABF1297B445E04354E236F4159140FF7768F", router.digest)
+        self.assertEquals('sumkledi', router.nickname)
+        self.assertEquals('0013D22389CD50D0B784A3E4061CB31E8CE8CEB5', router.fingerprint)
+        self.assertEquals('F260ABF1297B445E04354E236F4159140FF7768F', router.digest)
         self.assertEquals(datetime.datetime(2012, 7, 12, 4, 1, 55), router.published)
-        self.assertEquals("178.218.213.229", router.address)
+        self.assertEquals('178.218.213.229', router.address)
         self.assertEquals(80, router.or_port)
         self.assertEquals(None, router.dir_port)
 
@@ -126,15 +126,15 @@ class TestNetworkStatus(unittest.TestCase):
     Checks if the bridge documents from Metrics are parsed properly.
     """
 
-    consensus_path = get_resource("bridge_network_status")
+    consensus_path = get_resource('bridge_network_status')
 
     with open(consensus_path, 'rb') as descriptor_file:
       router = next(stem.descriptor.parse_file(descriptor_file))
-      self.assertEquals("Unnamed", router.nickname)
-      self.assertEquals("0014A2055278DB3EB0E59EA701741416AF185558", router.fingerprint)
-      self.assertEquals("148EF8685B8D259650AE0967D1FF8E6A870C7743", router.digest)
+      self.assertEquals('Unnamed', router.nickname)
+      self.assertEquals('0014A2055278DB3EB0E59EA701741416AF185558', router.fingerprint)
+      self.assertEquals('148EF8685B8D259650AE0967D1FF8E6A870C7743', router.digest)
       self.assertEquals(datetime.datetime(2012, 5, 31, 15, 57, 0), router.published)
-      self.assertEquals("10.97.236.247", router.address)
+      self.assertEquals('10.97.236.247', router.address)
       self.assertEquals(443, router.or_port)
       self.assertEquals(None, router.dir_port)
 
@@ -172,14 +172,14 @@ RY22NXCwrJvSMEwiy7acC8FGysqwHRyE356+Rw6TB43g3Tno9KaHEK7MHXjSHwNs
 GM9hAsAMRX9Ogqhq5UjDNqEsvDKuyVeyh7unSZEOip9Zr6K/+7VsVPNb8vfBRBjo
 -----END SIGNATURE-----"""
 
-    cert_path = get_resource("metrics_cert")
+    cert_path = get_resource('metrics_cert')
 
     with open(cert_path, 'rb') as cert_file:
       cert = next(stem.descriptor.parse_file(cert_file))
       self.assertEquals(3, cert.version)
       self.assertEquals(None, cert.address)
       self.assertEquals(None, cert.dir_port)
-      self.assertEquals("14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4", cert.fingerprint)
+      self.assertEquals('14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4', cert.fingerprint)
       self.assertEquals(expected_identity_key, cert.identity_key)
       self.assertEquals(datetime.datetime(2008, 5, 9, 21, 13, 26), cert.published)
       self.assertEquals(datetime.datetime(2009, 5, 9, 21, 13, 26), cert.expires)
@@ -195,30 +195,30 @@ GM9hAsAMRX9Ogqhq5UjDNqEsvDKuyVeyh7unSZEOip9Zr6K/+7VsVPNb8vfBRBjo
 
     # the document's expected client and server versions are the same
     expected_versions = [stem.version.Version(v) for v in (
-      "0.2.2.35",
-      "0.2.2.36",
-      "0.2.2.37",
-      "0.2.3.10-alpha",
-      "0.2.3.11-alpha",
-      "0.2.3.12-alpha",
-      "0.2.3.13-alpha",
-      "0.2.3.14-alpha",
-      "0.2.3.15-alpha",
-      "0.2.3.16-alpha",
-      "0.2.3.17-beta",
-      "0.2.3.18-rc",
-      "0.2.3.19-rc",
+      '0.2.2.35',
+      '0.2.2.36',
+      '0.2.2.37',
+      '0.2.3.10-alpha',
+      '0.2.3.11-alpha',
+      '0.2.3.12-alpha',
+      '0.2.3.13-alpha',
+      '0.2.3.14-alpha',
+      '0.2.3.15-alpha',
+      '0.2.3.16-alpha',
+      '0.2.3.17-beta',
+      '0.2.3.18-rc',
+      '0.2.3.19-rc',
     )]
 
     expected_flags = set(
-      ["Authority", "BadExit", "Exit", "Fast", "Guard", "HSDir",
-       "Named", "Running", "Stable", "Unnamed", "V2Dir", "Valid"])
+      ['Authority', 'BadExit', 'Exit', 'Fast', 'Guard', 'HSDir',
+       'Named', 'Running', 'Stable', 'Unnamed', 'V2Dir', 'Valid'])
 
     expected_bandwidth_weights = {
-      "Wbd": 3335, "Wbe": 0, "Wbg": 3536, "Wbm": 10000, "Wdb": 10000,
-      "Web": 10000, "Wed": 3329, "Wee": 10000, "Weg": 3329, "Wem": 10000,
-      "Wgb": 10000, "Wgd": 3335, "Wgg": 6464, "Wgm": 6464, "Wmb": 10000,
-      "Wmd": 3335, "Wme": 0, "Wmg": 3536, "Wmm": 10000
+      'Wbd': 3335, 'Wbe': 0, 'Wbg': 3536, 'Wbm': 10000, 'Wdb': 10000,
+      'Web': 10000, 'Wed': 3329, 'Wee': 10000, 'Weg': 3329, 'Wem': 10000,
+      'Wgb': 10000, 'Wgd': 3335, 'Wgg': 6464, 'Wgm': 6464, 'Wmb': 10000,
+      'Wmd': 3335, 'Wme': 0, 'Wmg': 3536, 'Wmm': 10000
     }
 
     expected_signature = """-----BEGIN SIGNATURE-----
@@ -227,7 +227,7 @@ mfWcW0b+jsrXcJoCxV5IrwCDF3u1aC3diwZY6yiG186pwWbOwE41188XI2DeYPwE
 I/TJmV928na7RLZe2mGHCAW3VQOvV+QkCfj05VZ8CsY=
 -----END SIGNATURE-----"""
 
-    with open(get_resource("cached-consensus"), 'rb') as descriptor_file:
+    with open(get_resource('cached-consensus'), 'rb') as descriptor_file:
       document = stem.descriptor.networkstatus.NetworkStatusDocumentV3(descriptor_file.read(), default_params = False)
 
       self.assertEquals(3, document.version)
@@ -243,7 +243,7 @@ I/TJmV928na7RLZe2mGHCAW3VQOvV+QkCfj05VZ8CsY=
       self.assertEquals(expected_versions, document.client_versions)
       self.assertEquals(expected_versions, document.server_versions)
       self.assertEquals(expected_flags, set(document.known_flags))
-      self.assertEquals({"CircuitPriorityHalflifeMsec": 30000, "bwauthpid": 1}, document.params)
+      self.assertEquals({'CircuitPriorityHalflifeMsec': 30000, 'bwauthpid': 1}, document.params)
 
       self.assertEquals(12, document.consensus_method)
       self.assertEquals(expected_bandwidth_weights, document.bandwidth_weights)
@@ -251,34 +251,34 @@ I/TJmV928na7RLZe2mGHCAW3VQOvV+QkCfj05VZ8CsY=
       self.assertEquals(None, document.published)
       self.assertEquals([], document.get_unrecognized_lines())
 
-      router = document.routers["0013D22389CD50D0B784A3E4061CB31E8CE8CEB5"]
-      self.assertEquals("sumkledi", router.nickname)
-      self.assertEquals("0013D22389CD50D0B784A3E4061CB31E8CE8CEB5", router.fingerprint)
-      self.assertEquals("F260ABF1297B445E04354E236F4159140FF7768F", router.digest)
+      router = document.routers['0013D22389CD50D0B784A3E4061CB31E8CE8CEB5']
+      self.assertEquals('sumkledi', router.nickname)
+      self.assertEquals('0013D22389CD50D0B784A3E4061CB31E8CE8CEB5', router.fingerprint)
+      self.assertEquals('F260ABF1297B445E04354E236F4159140FF7768F', router.digest)
       self.assertEquals(datetime.datetime(2012, 7, 12, 4, 1, 55), router.published)
-      self.assertEquals("178.218.213.229", router.address)
+      self.assertEquals('178.218.213.229', router.address)
       self.assertEquals(80, router.or_port)
       self.assertEquals(None, router.dir_port)
-      self.assertEquals(set(["Exit", "Fast", "Named", "Running", "Valid"]), set(router.flags))
+      self.assertEquals(set(['Exit', 'Fast', 'Named', 'Running', 'Valid']), set(router.flags))
 
       authority = document.directory_authorities[0]
       self.assertEquals(8, len(document.directory_authorities))
-      self.assertEquals("tor26", authority.nickname)
-      self.assertEquals("14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4", authority.fingerprint)
-      self.assertEquals("86.59.21.38", authority.hostname)
-      self.assertEquals("86.59.21.38", authority.address)
+      self.assertEquals('tor26', authority.nickname)
+      self.assertEquals('14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4', authority.fingerprint)
+      self.assertEquals('86.59.21.38', authority.hostname)
+      self.assertEquals('86.59.21.38', authority.address)
       self.assertEquals(80, authority.dir_port)
       self.assertEquals(443, authority.or_port)
-      self.assertEquals("Peter Palfrader", authority.contact)
-      self.assertEquals("0B6D1E9A300B895AA2D0B427F92917B6995C3C1C", authority.vote_digest)
+      self.assertEquals('Peter Palfrader', authority.contact)
+      self.assertEquals('0B6D1E9A300B895AA2D0B427F92917B6995C3C1C', authority.vote_digest)
       self.assertEquals(None, authority.legacy_dir_key)
       self.assertEquals(None, authority.key_certificate)
 
       signature = document.signatures[0]
       self.assertEquals(8, len(document.signatures))
-      self.assertEquals("sha1", signature.method)
-      self.assertEquals("14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4", signature.identity)
-      self.assertEquals("BF112F1C6D5543CFD0A32215ACABD4197B5279AD", signature.key_digest)
+      self.assertEquals('sha1', signature.method)
+      self.assertEquals('14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4', signature.identity)
+      self.assertEquals('BF112F1C6D5543CFD0A32215ACABD4197B5279AD', signature.key_digest)
       self.assertEquals(expected_signature, signature.signature)
 
   def test_consensus_v2(self):
@@ -298,80 +298,80 @@ nTA+fD8JQqpPtb8b0SnG9kwy75eS//sRu7TErie2PzGMxrf9LH0LAgMBAAE=
 TpQQk3nNQF8z6UIvdlvP+DnJV4izWVkQEZgUZgIVM0E=
 -----END SIGNATURE-----"""
 
-    with open(get_resource("cached-consensus-v2"), 'rb') as descriptor_file:
+    with open(get_resource('cached-consensus-v2'), 'rb') as descriptor_file:
       descriptor_file.readline()  # strip header
       document = stem.descriptor.networkstatus.NetworkStatusDocumentV2(descriptor_file.read())
 
       self.assertEquals(2, document.version)
-      self.assertEquals("18.244.0.114", document.hostname)
-      self.assertEquals("18.244.0.114", document.address)
+      self.assertEquals('18.244.0.114', document.hostname)
+      self.assertEquals('18.244.0.114', document.address)
       self.assertEquals(80, document.dir_port)
-      self.assertEquals("719BE45DE224B607C53707D0E2143E2D423E74CF", document.fingerprint)
-      self.assertEquals("arma at mit dot edu", document.contact)
+      self.assertEquals('719BE45DE224B607C53707D0E2143E2D423E74CF', document.fingerprint)
+      self.assertEquals('arma at mit dot edu', document.contact)
       self.assertEquals(expected_signing_key, document.signing_key)
 
       self.assertEquals(67, len(document.client_versions))
-      self.assertEquals("0.0.9rc2", document.client_versions[0])
-      self.assertEquals("0.1.1.10-alpha-cvs", document.client_versions[-1])
+      self.assertEquals('0.0.9rc2', document.client_versions[0])
+      self.assertEquals('0.1.1.10-alpha-cvs', document.client_versions[-1])
 
       self.assertEquals(67, len(document.server_versions))
-      self.assertEquals("0.0.9rc2", document.server_versions[0])
-      self.assertEquals("0.1.1.10-alpha-cvs", document.server_versions[-1])
+      self.assertEquals('0.0.9rc2', document.server_versions[0])
+      self.assertEquals('0.1.1.10-alpha-cvs', document.server_versions[-1])
 
       self.assertEquals(datetime.datetime(2005, 12, 16, 0, 13, 46), document.published)
-      self.assertEquals(["Names", "Versions"], document.options)
-      self.assertEquals("moria2", document.signing_authority)
+      self.assertEquals(['Names', 'Versions'], document.options)
+      self.assertEquals('moria2', document.signing_authority)
       self.assertEquals(expected_signature, document.signature)
       self.assertEquals([], document.get_unrecognized_lines())
 
       self.assertEqual(3, len(document.routers))
 
-      router1 = document.routers["719BE45DE224B607C53707D0E2143E2D423E74CF"]
-      self.assertEquals("moria2", router1.nickname)
-      self.assertEquals("719BE45DE224B607C53707D0E2143E2D423E74CF", router1.fingerprint)
-      self.assertEquals("B7F3F0975B87889DD1285FD57A1B1BB617F65432", router1.digest)
+      router1 = document.routers['719BE45DE224B607C53707D0E2143E2D423E74CF']
+      self.assertEquals('moria2', router1.nickname)
+      self.assertEquals('719BE45DE224B607C53707D0E2143E2D423E74CF', router1.fingerprint)
+      self.assertEquals('B7F3F0975B87889DD1285FD57A1B1BB617F65432', router1.digest)
       self.assertEquals(datetime.datetime(2005, 12, 15, 6, 57, 18), router1.published)
-      self.assertEquals("18.244.0.114", router1.address)
+      self.assertEquals('18.244.0.114', router1.address)
       self.assertEquals(443, router1.or_port)
       self.assertEquals(80, router1.dir_port)
-      self.assertEquals(set(["Authority", "Fast", "Named", "Running", "Valid", "V2Dir"]), set(router1.flags))
+      self.assertEquals(set(['Authority', 'Fast', 'Named', 'Running', 'Valid', 'V2Dir']), set(router1.flags))
 
-      router2 = document.routers["0928BA467056C4A689FEE4EF5D71482B6289C3D5"]
-      self.assertEquals("stnv", router2.nickname)
-      self.assertEquals("0928BA467056C4A689FEE4EF5D71482B6289C3D5", router2.fingerprint)
-      self.assertEquals("22D1A7ED4199BDA7ED6C416EECD769C18E1F2A5A", router2.digest)
+      router2 = document.routers['0928BA467056C4A689FEE4EF5D71482B6289C3D5']
+      self.assertEquals('stnv', router2.nickname)
+      self.assertEquals('0928BA467056C4A689FEE4EF5D71482B6289C3D5', router2.fingerprint)
+      self.assertEquals('22D1A7ED4199BDA7ED6C416EECD769C18E1F2A5A', router2.digest)
       self.assertEquals(datetime.datetime(2005, 12, 15, 16, 24, 42), router2.published)
-      self.assertEquals("84.16.236.173", router2.address)
+      self.assertEquals('84.16.236.173', router2.address)
       self.assertEquals(9001, router2.or_port)
       self.assertEquals(None, router2.dir_port)
-      self.assertEquals(set(["Named", "Valid"]), set(router2.flags))
+      self.assertEquals(set(['Named', 'Valid']), set(router2.flags))
 
-      router3 = document.routers["09E8582FF0E6F85E2B8E41C0DC0B9C9DC46E6968"]
-      self.assertEquals("nggrplz", router3.nickname)
-      self.assertEquals("09E8582FF0E6F85E2B8E41C0DC0B9C9DC46E6968", router3.fingerprint)
-      self.assertEquals("B302C2B01C94F398E3EF38939526B0651F824DD6", router3.digest)
+      router3 = document.routers['09E8582FF0E6F85E2B8E41C0DC0B9C9DC46E6968']
+      self.assertEquals('nggrplz', router3.nickname)
+      self.assertEquals('09E8582FF0E6F85E2B8E41C0DC0B9C9DC46E6968', router3.fingerprint)
+      self.assertEquals('B302C2B01C94F398E3EF38939526B0651F824DD6', router3.digest)
       self.assertEquals(datetime.datetime(2005, 12, 15, 23, 25, 50), router3.published)
-      self.assertEquals("194.109.109.109", router3.address)
+      self.assertEquals('194.109.109.109', router3.address)
       self.assertEquals(9001, router3.or_port)
       self.assertEquals(None, router3.dir_port)
-      self.assertEquals(set(["Fast", "Stable", "Running", "Valid"]), set(router3.flags))
+      self.assertEquals(set(['Fast', 'Stable', 'Running', 'Valid']), set(router3.flags))
 
   def test_metrics_vote(self):
     """
     Checks if vote documents from Metrics are parsed properly.
     """
 
-    vote_path = get_resource("metrics_vote")
+    vote_path = get_resource('metrics_vote')
 
     with open(vote_path, 'rb') as descriptor_file:
       descriptors = stem.descriptor.parse_file(descriptor_file)
 
       router = next(descriptors)
-      self.assertEquals("sumkledi", router.nickname)
-      self.assertEquals("0013D22389CD50D0B784A3E4061CB31E8CE8CEB5", router.fingerprint)
-      self.assertEquals("0799F806200B005F01E40A9A7F1A21C988AE8FB1", router.digest)
+      self.assertEquals('sumkledi', router.nickname)
+      self.assertEquals('0013D22389CD50D0B784A3E4061CB31E8CE8CEB5', router.fingerprint)
+      self.assertEquals('0799F806200B005F01E40A9A7F1A21C988AE8FB1', router.digest)
       self.assertEquals(datetime.datetime(2012, 7, 11, 4, 22, 53), router.published)
-      self.assertEquals("178.218.213.229", router.address)
+      self.assertEquals('178.218.213.229', router.address)
       self.assertEquals(80, router.or_port)
       self.assertEquals(None, router.dir_port)
 
@@ -381,8 +381,8 @@ TpQQk3nNQF8z6UIvdlvP+DnJV4izWVkQEZgUZgIVM0E=
     """
 
     expected_flags = set(
-      ["Authority", "BadExit", "Exit", "Fast", "Guard", "HSDir",
-       "Running", "Stable", "V2Dir", "Valid"])
+      ['Authority', 'BadExit', 'Exit', 'Fast', 'Guard', 'HSDir',
+       'Running', 'Stable', 'V2Dir', 'Valid'])
 
     expected_identity_key = """-----BEGIN RSA PUBLIC KEY-----
 MIIBigKCAYEA6uSmsoxj2MiJ3qyZq0qYXlRoG8o82SNqg+22m+t1c7MlQOZWPJYn
@@ -425,7 +425,7 @@ JZ/1HL9sHyZfo6bwaC6YSM9PNiiY6L7rnGpS7UkHiFI+M96VCMorvjm5YPs3FioJ
 DnN5aFtYKiTc19qIC7Nmo+afPdDEf0MlJvEOP5EWl3w=
 -----END SIGNATURE-----"""
 
-    with open(get_resource("vote"), 'rb') as descriptor_file:
+    with open(get_resource('vote'), 'rb') as descriptor_file:
       document = stem.descriptor.networkstatus.NetworkStatusDocumentV3(descriptor_file.read(), default_params = False)
 
       self.assertEquals(3, document.version)
@@ -441,7 +441,7 @@ DnN5aFtYKiTc19qIC7Nmo+afPdDEf0MlJvEOP5EWl3w=
       self.assertEquals([], document.client_versions)
       self.assertEquals([], document.server_versions)
       self.assertEquals(expected_flags, set(document.known_flags))
-      self.assertEquals({"CircuitPriorityHalflifeMsec": 30000, "bwauthpid": 1}, document.params)
+      self.assertEquals({'CircuitPriorityHalflifeMsec': 30000, 'bwauthpid': 1}, document.params)
 
       self.assertEquals(None, document.consensus_method)
       self.assertEquals({}, document.bandwidth_weights)
@@ -449,24 +449,24 @@ DnN5aFtYKiTc19qIC7Nmo+afPdDEf0MlJvEOP5EWl3w=
       self.assertEquals(datetime.datetime(2012, 7, 11, 23, 50, 1), document.published)
       self.assertEquals([], document.get_unrecognized_lines())
 
-      router = document.routers["0013D22389CD50D0B784A3E4061CB31E8CE8CEB5"]
-      self.assertEquals("sumkledi", router.nickname)
-      self.assertEquals("0013D22389CD50D0B784A3E4061CB31E8CE8CEB5", router.fingerprint)
-      self.assertEquals("0799F806200B005F01E40A9A7F1A21C988AE8FB1", router.digest)
+      router = document.routers['0013D22389CD50D0B784A3E4061CB31E8CE8CEB5']
+      self.assertEquals('sumkledi', router.nickname)
+      self.assertEquals('0013D22389CD50D0B784A3E4061CB31E8CE8CEB5', router.fingerprint)
+      self.assertEquals('0799F806200B005F01E40A9A7F1A21C988AE8FB1', router.digest)
       self.assertEquals(datetime.datetime(2012, 7, 11, 4, 22, 53), router.published)
-      self.assertEquals("178.218.213.229", router.address)
+      self.assertEquals('178.218.213.229', router.address)
       self.assertEquals(80, router.or_port)
       self.assertEquals(None, router.dir_port)
 
       authority = document.directory_authorities[0]
       self.assertEquals(1, len(document.directory_authorities))
-      self.assertEquals("turtles", authority.nickname)
-      self.assertEquals("27B6B5996C426270A5C95488AA5BCEB6BCC86956", authority.fingerprint)
-      self.assertEquals("76.73.17.194", authority.hostname)
-      self.assertEquals("76.73.17.194", authority.address)
+      self.assertEquals('turtles', authority.nickname)
+      self.assertEquals('27B6B5996C426270A5C95488AA5BCEB6BCC86956', authority.fingerprint)
+      self.assertEquals('76.73.17.194', authority.hostname)
+      self.assertEquals('76.73.17.194', authority.address)
       self.assertEquals(9030, authority.dir_port)
       self.assertEquals(9090, authority.or_port)
-      self.assertEquals("Mike Perry <email>", authority.contact)
+      self.assertEquals('Mike Perry <email>', authority.contact)
       self.assertEquals(None, authority.vote_digest)
       self.assertEquals(None, authority.legacy_dir_key)
 
@@ -474,7 +474,7 @@ DnN5aFtYKiTc19qIC7Nmo+afPdDEf0MlJvEOP5EWl3w=
       self.assertEquals(3, certificate.version)
       self.assertEquals(None, certificate.address)
       self.assertEquals(None, certificate.dir_port)
-      self.assertEquals("27B6B5996C426270A5C95488AA5BCEB6BCC86956", certificate.fingerprint)
+      self.assertEquals('27B6B5996C426270A5C95488AA5BCEB6BCC86956', certificate.fingerprint)
       self.assertEquals(expected_identity_key, certificate.identity_key)
       self.assertEquals(datetime.datetime(2011, 11, 28, 21, 51, 4), certificate.published)
       self.assertEquals(datetime.datetime(2012, 11, 28, 21, 51, 4), certificate.expires)
@@ -484,7 +484,7 @@ DnN5aFtYKiTc19qIC7Nmo+afPdDEf0MlJvEOP5EWl3w=
 
       signature = document.signatures[0]
       self.assertEquals(1, len(document.signatures))
-      self.assertEquals("sha1", signature.method)
-      self.assertEquals("27B6B5996C426270A5C95488AA5BCEB6BCC86956", signature.identity)
-      self.assertEquals("D5C30C15BB3F1DA27669C2D88439939E8F418FCF", signature.key_digest)
+      self.assertEquals('sha1', signature.method)
+      self.assertEquals('27B6B5996C426270A5C95488AA5BCEB6BCC86956', signature.identity)
+      self.assertEquals('D5C30C15BB3F1DA27669C2D88439939E8F418FCF', signature.key_digest)
       self.assertEquals(expected_signature, signature.signature)
diff --git a/test/integ/descriptor/reader.py b/test/integ/descriptor/reader.py
index 99ce78d..7791f3e 100644
--- a/test/integ/descriptor/reader.py
+++ b/test/integ/descriptor/reader.py
@@ -22,13 +22,13 @@ BASIC_LISTING = """
 """
 
 my_dir = os.path.dirname(__file__)
-DESCRIPTOR_TEST_DATA = os.path.join(my_dir, "data")
+DESCRIPTOR_TEST_DATA = os.path.join(my_dir, 'data')
 
 TAR_DESCRIPTORS = None
 
 
 def _get_processed_files_path():
-  return test.runner.get_runner().get_test_dir("descriptor_processed_files")
+  return test.runner.get_runner().get_test_dir('descriptor_processed_files')
 
 
 def _make_processed_files_listing(contents):
@@ -39,7 +39,7 @@ def _make_processed_files_listing(contents):
 
   test_listing_path = _get_processed_files_path()
 
-  test_listing_file = open(test_listing_path, "w")
+  test_listing_file = open(test_listing_path, 'w')
   test_listing_file.write(contents)
   test_listing_file.close()
 
@@ -50,7 +50,7 @@ def _get_raw_tar_descriptors():
   global TAR_DESCRIPTORS
 
   if not TAR_DESCRIPTORS:
-    test_path = os.path.join(DESCRIPTOR_TEST_DATA, "descriptor_archive.tar")
+    test_path = os.path.join(DESCRIPTOR_TEST_DATA, 'descriptor_archive.tar')
     raw_descriptors = []
 
     # TODO: revert to using the 'with' keyword for this when dropping python
@@ -65,7 +65,7 @@ def _get_raw_tar_descriptors():
         if tar_entry.isfile():
           entry = tar_file.extractfile(tar_entry)
           entry.readline()  # strip header
-          raw_descriptors.append(entry.read().decode("utf-8", "replace"))
+          raw_descriptors.append(entry.read().decode('utf-8', 'replace'))
           entry.close()
     finally:
       if tar_file:
@@ -101,9 +101,9 @@ class TestDescriptorReader(unittest.TestCase):
     loaded_listing = stem.descriptor.reader.load_processed_files(test_listing_path)
 
     expected_listing = {
-      "/tmp": 123,
-      "/bin/grep": 4567,
-      "/file with spaces/and \\ stuff": 890,
+      '/tmp': 123,
+      '/bin/grep': 4567,
+      '/file with spaces/and \\ stuff': 890,
     }
 
     self.assertEquals(expected_listing, loaded_listing)
@@ -113,7 +113,7 @@ class TestDescriptorReader(unittest.TestCase):
     Tests the load_processed_files() function with a file that doesn't exist.
     """
 
-    self.assertRaises(IOError, stem.descriptor.reader.load_processed_files, "/non-existant/path")
+    self.assertRaises(IOError, stem.descriptor.reader.load_processed_files, '/non-existant/path')
 
   def test_load_processed_files_permissions(self):
     """
@@ -124,7 +124,7 @@ class TestDescriptorReader(unittest.TestCase):
     # test relies on being unable to read a file
 
     if getpass.getuser() == 'root':
-      test.runner.skip(self, "(running as root)")
+      test.runner.skip(self, '(running as root)')
       return
 
     # Skip the test on windows, since you can only set the file's
@@ -132,7 +132,7 @@ class TestDescriptorReader(unittest.TestCase):
     # http://docs.python.org/library/os.html#os.chmod
 
     if system.is_windows():
-      test.runner.skip(self, "(chmod not functional)")
+      test.runner.skip(self, '(chmod not functional)')
 
     test_listing_path = _make_processed_files_listing(BASIC_LISTING)
     os.chmod(test_listing_path, 0077)  # remove read permissions
@@ -144,9 +144,9 @@ class TestDescriptorReader(unittest.TestCase):
     """
 
     initial_listing = {
-      "/tmp": 123,
-      "/bin/grep": 4567,
-      "/file with spaces/and \\ stuff": 890,
+      '/tmp': 123,
+      '/bin/grep': 4567,
+      '/file with spaces/and \\ stuff': 890,
     }
 
     # saves the initial_listing to a file then reloads it
@@ -161,18 +161,18 @@ class TestDescriptorReader(unittest.TestCase):
     Tests the save_processed_files() function with malformed data.
     """
 
-    missing_filename = {"": 123}
-    relative_filename = {"foobar": 123}
-    string_timestamp = {"/tmp": "123a"}
+    missing_filename = {'': 123}
+    relative_filename = {'foobar': 123}
+    string_timestamp = {'/tmp': '123a'}
 
     for listing in (missing_filename, relative_filename, string_timestamp):
-      self.assertRaises(TypeError, stem.descriptor.reader.save_processed_files, "/tmp/foo", listing)
+      self.assertRaises(TypeError, stem.descriptor.reader.save_processed_files, '/tmp/foo', listing)
 
     # Though our attempts to save the processed files fail we'll write an empty
     # file. Cleaning it up.
 
     try:
-      os.remove("/tmp/foo")
+      os.remove('/tmp/foo')
     except:
       pass
 
@@ -187,12 +187,14 @@ class TestDescriptorReader(unittest.TestCase):
 
     descriptor_entries = []
 
-    descriptor_path = os.path.join(DESCRIPTOR_TEST_DATA, "example_descriptor")
+    descriptor_path = os.path.join(DESCRIPTOR_TEST_DATA, 'example_descriptor')
+
     with open(descriptor_path) as descriptor_file:
       descriptor_file.readline()  # strip header
       descriptor_entries.append(descriptor_file.read())
 
     # running this test multiple times to flush out concurrency issues
+
     for _ in xrange(15):
       remaining_entries = list(descriptor_entries)
 
@@ -215,7 +217,7 @@ class TestDescriptorReader(unittest.TestCase):
     making sure that it can be used repeatedly.
     """
 
-    descriptor_path = os.path.join(DESCRIPTOR_TEST_DATA, "example_descriptor")
+    descriptor_path = os.path.join(DESCRIPTOR_TEST_DATA, 'example_descriptor')
     reader = stem.descriptor.reader.DescriptorReader(descriptor_path)
 
     with reader:
@@ -255,7 +257,7 @@ class TestDescriptorReader(unittest.TestCase):
     """
 
     persistence_path = _get_processed_files_path()
-    descriptor_path = os.path.join(DESCRIPTOR_TEST_DATA, "example_descriptor")
+    descriptor_path = os.path.join(DESCRIPTOR_TEST_DATA, 'example_descriptor')
 
     # First run where the persistence_path doesn't yet exist. This just tests
     # the saving functionality.
@@ -287,12 +289,12 @@ class TestDescriptorReader(unittest.TestCase):
     """
 
     expected_archive_paths = (
-      "descriptor_archive/0/2/02c311d3d789f3f55c0880b5c85f3c196343552c",
-      "descriptor_archive/1/b/1bb798cae15e21479db0bc700767eee4733e9d4a",
-      "descriptor_archive/1/b/1ef75fef564180d8b3f72c6f8635ff0cd855f92c",
+      'descriptor_archive/0/2/02c311d3d789f3f55c0880b5c85f3c196343552c',
+      'descriptor_archive/1/b/1bb798cae15e21479db0bc700767eee4733e9d4a',
+      'descriptor_archive/1/b/1ef75fef564180d8b3f72c6f8635ff0cd855f92c',
     )
 
-    test_path = os.path.join(DESCRIPTOR_TEST_DATA, "descriptor_archive.tar")
+    test_path = os.path.join(DESCRIPTOR_TEST_DATA, 'descriptor_archive.tar')
 
     with stem.descriptor.reader.DescriptorReader(test_path) as reader:
       for desc in reader:
@@ -305,7 +307,7 @@ class TestDescriptorReader(unittest.TestCase):
     """
 
     expected_results = _get_raw_tar_descriptors()
-    test_path = os.path.join(DESCRIPTOR_TEST_DATA, "descriptor_archive.tar")
+    test_path = os.path.join(DESCRIPTOR_TEST_DATA, 'descriptor_archive.tar')
 
     with stem.descriptor.reader.DescriptorReader(test_path) as reader:
       read_descriptors = [str(desc) for desc in list(reader)]
@@ -317,7 +319,7 @@ class TestDescriptorReader(unittest.TestCase):
     """
 
     expected_results = _get_raw_tar_descriptors()
-    test_path = os.path.join(DESCRIPTOR_TEST_DATA, "descriptor_archive.tar.gz")
+    test_path = os.path.join(DESCRIPTOR_TEST_DATA, 'descriptor_archive.tar.gz')
 
     with stem.descriptor.reader.DescriptorReader(test_path) as reader:
       read_descriptors = [str(desc) for desc in list(reader)]
@@ -329,7 +331,7 @@ class TestDescriptorReader(unittest.TestCase):
     """
 
     expected_results = _get_raw_tar_descriptors()
-    test_path = os.path.join(DESCRIPTOR_TEST_DATA, "descriptor_archive.tar.bz2")
+    test_path = os.path.join(DESCRIPTOR_TEST_DATA, 'descriptor_archive.tar.bz2')
 
     with stem.descriptor.reader.DescriptorReader(test_path) as reader:
       read_descriptors = [str(desc) for desc in list(reader)]
@@ -344,10 +346,10 @@ class TestDescriptorReader(unittest.TestCase):
     # Skip on windows since SIGALRM is unavailable
 
     if system.is_windows():
-      test.runner.skip(self, "(SIGALRM unavailable)")
+      test.runner.skip(self, '(SIGALRM unavailable)')
 
     is_test_running = True
-    reader = stem.descriptor.reader.DescriptorReader("/usr")
+    reader = stem.descriptor.reader.DescriptorReader('/usr')
 
     # Fails the test after a couple seconds if we don't finish successfully.
     # Depending on what we're blocked on this might not work when the test
@@ -396,24 +398,24 @@ class TestDescriptorReader(unittest.TestCase):
     reader = stem.descriptor.reader.DescriptorReader(DESCRIPTOR_TEST_DATA)
     reader.register_skip_listener(skip_listener.listener)
 
-    expected_skip_files = ("riddle", "tiny.png", "vote", "new_metrics_type")
+    expected_skip_files = ('riddle', 'tiny.png', 'vote', 'new_metrics_type')
 
     with reader:
       list(reader)  # iterates over all of the descriptors
 
     # strip anything with a .swp suffix (vim tmp files)
 
-    skip_listener.results = [(path, exc) for (path, exc) in skip_listener.results if not path.endswith(".swp")]
+    skip_listener.results = [(path, exc) for (path, exc) in skip_listener.results if not path.endswith('.swp')]
 
     if len(skip_listener.results) != len(expected_skip_files):
-      expected_label = ",\n  ".join(expected_skip_files)
-      results_label = ",\n  ".join(["%s (%s)" % (path, exc) for (path, exc) in skip_listener.results])
+      expected_label = ',\n  '.join(expected_skip_files)
+      results_label = ',\n  '.join(['%s (%s)' % (path, exc) for (path, exc) in skip_listener.results])
 
-      self.fail("Skipped files that we should have been able to parse.\n\nExpected:\n  %s\n\nResult:\n  %s" % (expected_label, results_label))
+      self.fail('Skipped files that we should have been able to parse.\n\nExpected:\n  %s\n\nResult:\n  %s' % (expected_label, results_label))
 
     for skip_path, skip_exception in skip_listener.results:
       if not os.path.basename(skip_path) in expected_skip_files:
-        self.fail("Unexpected non-descriptor content: %s" % skip_path)
+        self.fail('Unexpected non-descriptor content: %s' % skip_path)
 
       self.assertTrue(isinstance(skip_exception, stem.descriptor.reader.UnrecognizedType))
 
@@ -425,7 +427,8 @@ class TestDescriptorReader(unittest.TestCase):
     """
 
     # path that we want the DescriptorReader to skip
-    test_path = os.path.join(DESCRIPTOR_TEST_DATA, "example_descriptor")
+
+    test_path = os.path.join(DESCRIPTOR_TEST_DATA, 'example_descriptor')
     initial_processed_files = {test_path: sys.maxint}
 
     skip_listener = SkipListener()
@@ -453,11 +456,11 @@ class TestDescriptorReader(unittest.TestCase):
     # types are solely based on file extensions so making something that looks
     # like an png image
 
-    test_path = test.runner.get_runner().get_test_dir("test.png")
+    test_path = test.runner.get_runner().get_test_dir('test.png')
 
     try:
-      test_file = open(test_path, "w")
-      test_file.write("test data for test_skip_listener_unrecognized_type()")
+      test_file = open(test_path, 'w')
+      test_file.write('test data for test_skip_listener_unrecognized_type()')
       test_file.close()
 
       skip_listener = SkipListener()
@@ -472,7 +475,7 @@ class TestDescriptorReader(unittest.TestCase):
       skipped_path, skip_exception = skip_listener.results[0]
       self.assertEqual(test_path, skipped_path)
       self.assertTrue(isinstance(skip_exception, stem.descriptor.reader.UnrecognizedType))
-      self.assertTrue(skip_exception.mime_type in (("image/png", None), ("image/x-png", None)))
+      self.assertTrue(skip_exception.mime_type in (('image/png', None), ('image/x-png', None)))
     finally:
       if os.path.exists(test_path):
         os.remove(test_path)
@@ -485,17 +488,17 @@ class TestDescriptorReader(unittest.TestCase):
     # test relies on being unable to read a file
 
     if getpass.getuser() == 'root':
-      test.runner.skip(self, "(running as root)")
+      test.runner.skip(self, '(running as root)')
       return
     elif system.is_windows():
-      test.runner.skip(self, "(chmod not functional)")
+      test.runner.skip(self, '(chmod not functional)')
       return
 
-    test_path = test.runner.get_runner().get_test_dir("secret_file")
+    test_path = test.runner.get_runner().get_test_dir('secret_file')
 
     try:
-      test_file = open(test_path, "w")
-      test_file.write("test data for test_skip_listener_unrecognized_type()")
+      test_file = open(test_path, 'w')
+      test_file.write('test data for test_skip_listener_unrecognized_type()')
       test_file.close()
 
       os.chmod(test_path, 0077)  # remove read permissions
@@ -522,7 +525,7 @@ class TestDescriptorReader(unittest.TestCase):
     Listens for a file that's skipped because the file doesn't exist.
     """
 
-    test_path = "/non-existant/path"
+    test_path = '/non-existant/path'
 
     skip_listener = SkipListener()
     reader = stem.descriptor.reader.DescriptorReader(test_path)
@@ -542,7 +545,7 @@ class TestDescriptorReader(unittest.TestCase):
     Parses a file that has a valid metrics header, but an unrecognized type.
     """
 
-    test_path = test.integ.descriptor.get_resource("new_metrics_type")
+    test_path = test.integ.descriptor.get_resource('new_metrics_type')
 
     skip_listener = SkipListener()
     reader = stem.descriptor.reader.DescriptorReader(test_path)
diff --git a/test/integ/descriptor/remote.py b/test/integ/descriptor/remote.py
index 27062ea..d1a377c 100644
--- a/test/integ/descriptor/remote.py
+++ b/test/integ/descriptor/remote.py
@@ -26,7 +26,7 @@ class TestDescriptorDownloader(unittest.TestCase):
 
     if test.runner.require_online(self):
       return
-    elif test.runner.only_run_once(self, "test_using_authorities"):
+    elif test.runner.only_run_once(self, 'test_using_authorities'):
       return
 
     queries = []
@@ -43,7 +43,7 @@ class TestDescriptorDownloader(unittest.TestCase):
       try:
         descriptors = list(query.run())
       except Exception as exc:
-        self.fail("Unable to use %s (%s:%s, %s): %s" % (authority.nickname, authority.address, authority.dir_port, type(exc), exc))
+        self.fail('Unable to use %s (%s:%s, %s): %s' % (authority.nickname, authority.address, authority.dir_port, type(exc), exc))
 
       self.assertEqual(1, len(descriptors))
       self.assertEqual('moria1', descriptors[0].nickname)
@@ -55,7 +55,7 @@ class TestDescriptorDownloader(unittest.TestCase):
 
     if test.runner.require_online(self):
       return
-    elif test.runner.only_run_once(self, "test_use_directory_mirrors"):
+    elif test.runner.only_run_once(self, 'test_use_directory_mirrors'):
       return
 
     downloader = stem.descriptor.remote.DescriptorDownloader()
@@ -69,7 +69,7 @@ class TestDescriptorDownloader(unittest.TestCase):
 
     if test.runner.require_online(self):
       return
-    elif test.runner.only_run_once(self, "test_get_server_descriptors"):
+    elif test.runner.only_run_once(self, 'test_get_server_descriptors'):
       return
 
     downloader = stem.descriptor.remote.DescriptorDownloader()
@@ -105,7 +105,7 @@ class TestDescriptorDownloader(unittest.TestCase):
 
     if test.runner.require_online(self):
       return
-    elif test.runner.only_run_once(self, "test_get_extrainfo_descriptors"):
+    elif test.runner.only_run_once(self, 'test_get_extrainfo_descriptors'):
       return
 
     downloader = stem.descriptor.remote.DescriptorDownloader()
@@ -139,7 +139,7 @@ class TestDescriptorDownloader(unittest.TestCase):
 
     if test.runner.require_online(self):
       return
-    elif test.runner.only_run_once(self, "test_get_microdescriptors"):
+    elif test.runner.only_run_once(self, 'test_get_microdescriptors'):
       return
 
     downloader = stem.descriptor.remote.DescriptorDownloader()
@@ -168,7 +168,7 @@ class TestDescriptorDownloader(unittest.TestCase):
 
     if test.runner.require_online(self):
       return
-    elif test.runner.only_run_once(self, "test_get_consensus"):
+    elif test.runner.only_run_once(self, 'test_get_consensus'):
       return
 
     downloader = stem.descriptor.remote.DescriptorDownloader()
@@ -187,7 +187,7 @@ class TestDescriptorDownloader(unittest.TestCase):
 
     if test.runner.require_online(self):
       return
-    elif test.runner.only_run_once(self, "test_get_key_certificates"):
+    elif test.runner.only_run_once(self, 'test_get_key_certificates'):
       return
 
     downloader = stem.descriptor.remote.DescriptorDownloader()
diff --git a/test/integ/descriptor/server_descriptor.py b/test/integ/descriptor/server_descriptor.py
index 4b837f7..7b4645c 100644
--- a/test/integ/descriptor/server_descriptor.py
+++ b/test/integ/descriptor/server_descriptor.py
@@ -22,17 +22,17 @@ class TestServerDescriptor(unittest.TestCase):
     Parses and checks our results against a server descriptor from metrics.
     """
 
-    descriptor_file = open(get_resource("example_descriptor"), 'rb')
+    descriptor_file = open(get_resource('example_descriptor'), 'rb')
 
     expected_family = set([
-      "$0CE3CFB1E9CC47B63EA8869813BF6FAB7D4540C1",
-      "$1FD187E8F69A9B74C9202DC16A25B9E7744AB9F6",
-      "$74FB5EFA6A46DE4060431D515DC9A790E6AD9A7C",
-      "$77001D8DA9BF445B0F81AA427A675F570D222E6A",
-      "$B6D83EC2D9E18B0A7A33428F8CFA9C536769E209",
-      "$D2F37F46182C23AB747787FD657E680B34EAF892",
-      "$E0BD57A11F00041A9789577C53A1B784473669E4",
-      "$E5E3E9A472EAF7BE9682B86E92305DB4C71048EF",
+      '$0CE3CFB1E9CC47B63EA8869813BF6FAB7D4540C1',
+      '$1FD187E8F69A9B74C9202DC16A25B9E7744AB9F6',
+      '$74FB5EFA6A46DE4060431D515DC9A790E6AD9A7C',
+      '$77001D8DA9BF445B0F81AA427A675F570D222E6A',
+      '$B6D83EC2D9E18B0A7A33428F8CFA9C536769E209',
+      '$D2F37F46182C23AB747787FD657E680B34EAF892',
+      '$E0BD57A11F00041A9789577C53A1B784473669E4',
+      '$E5E3E9A472EAF7BE9682B86E92305DB4C71048EF',
     ])
 
     expected_onion_key = """-----BEGIN RSA PUBLIC KEY-----
@@ -53,70 +53,70 @@ dskLSPz8beUW7bzwDjR6EVNGpyoZde83Ejvau+5F2c6cGnlu91fiZN3suE88iE6e
 Qlx9HNCqCY877ztFRC624ja2ql6A2hBcuoYMbkHjcQ4=
 -----END SIGNATURE-----"""
 
-    desc = next(stem.descriptor.parse_file(descriptor_file, "server-descriptor 1.0"))
-    self.assertEquals("caerSidi", desc.nickname)
-    self.assertEquals("A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB", desc.fingerprint)
-    self.assertEquals("71.35.133.197", desc.address)
+    desc = next(stem.descriptor.parse_file(descriptor_file, 'server-descriptor 1.0'))
+    self.assertEquals('caerSidi', desc.nickname)
+    self.assertEquals('A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB', desc.fingerprint)
+    self.assertEquals('71.35.133.197', desc.address)
     self.assertEquals(9001, desc.or_port)
     self.assertEquals(None, desc.socks_port)
     self.assertEquals(None, desc.dir_port)
-    self.assertEquals(b"Tor 0.2.1.30 on Linux x86_64", desc.platform)
-    self.assertEquals(stem.version.Version("0.2.1.30"), desc.tor_version)
-    self.assertEquals("Linux x86_64", desc.operating_system)
+    self.assertEquals(b'Tor 0.2.1.30 on Linux x86_64', desc.platform)
+    self.assertEquals(stem.version.Version('0.2.1.30'), desc.tor_version)
+    self.assertEquals('Linux x86_64', desc.operating_system)
     self.assertEquals(588217, desc.uptime)
     self.assertEquals(datetime.datetime(2012, 3, 1, 17, 15, 27), desc.published)
-    self.assertEquals(b"www.atagar.com/contact", desc.contact)
-    self.assertEquals(["1", "2"], desc.link_protocols)
-    self.assertEquals(["1"], desc.circuit_protocols)
+    self.assertEquals(b'www.atagar.com/contact', desc.contact)
+    self.assertEquals(['1', '2'], desc.link_protocols)
+    self.assertEquals(['1'], desc.circuit_protocols)
     self.assertEquals(False, desc.hibernating)
     self.assertEquals(False, desc.allow_single_hop_exits)
     self.assertEquals(False, desc.extra_info_cache)
-    self.assertEquals("D225B728768D7EA4B5587C13A7A9D22EBBEE6E66", desc.extra_info_digest)
-    self.assertEquals(["2"], desc.hidden_service_dir)
+    self.assertEquals('D225B728768D7EA4B5587C13A7A9D22EBBEE6E66', desc.extra_info_digest)
+    self.assertEquals(['2'], desc.hidden_service_dir)
     self.assertEquals(expected_family, desc.family)
     self.assertEquals(153600, desc.average_bandwidth)
     self.assertEquals(256000, desc.burst_bandwidth)
     self.assertEquals(104590, desc.observed_bandwidth)
-    self.assertEquals(stem.exit_policy.ExitPolicy("reject *:*"), desc.exit_policy)
+    self.assertEquals(stem.exit_policy.ExitPolicy('reject *:*'), desc.exit_policy)
     self.assertEquals(expected_onion_key, desc.onion_key)
     self.assertEquals(expected_signing_key, desc.signing_key)
     self.assertEquals(expected_signature, desc.signature)
     self.assertEquals([], desc.get_unrecognized_lines())
-    self.assertEquals("2C7B27BEAB04B4E2459D89CA6D5CD1CC5F95A689", desc.digest())
+    self.assertEquals('2C7B27BEAB04B4E2459D89CA6D5CD1CC5F95A689', desc.digest())
 
   def test_metrics_descriptor_multiple(self):
     """
     Parses and checks our results against a server descriptor from metrics.
     """
 
-    with open(get_resource("metrics_server_desc_multiple"), 'rb') as descriptor_file:
-      descriptors = list(stem.descriptor.parse_file(descriptor_file, "server-descriptor 1.0"))
+    with open(get_resource('metrics_server_desc_multiple'), 'rb') as descriptor_file:
+      descriptors = list(stem.descriptor.parse_file(descriptor_file, 'server-descriptor 1.0'))
 
       self.assertEquals(2, len(descriptors))
 
-      self.assertEquals("anonion", descriptors[0].nickname)
-      self.assertEquals("9A5EC5BB866517E53962AF4D3E776536694B069E", descriptors[0].fingerprint)
+      self.assertEquals('anonion', descriptors[0].nickname)
+      self.assertEquals('9A5EC5BB866517E53962AF4D3E776536694B069E', descriptors[0].fingerprint)
 
-      self.assertEquals("Unnamed", descriptors[1].nickname)
-      self.assertEquals("5366F1D198759F8894EA6E5FF768C667F59AFD24", descriptors[1].fingerprint)
+      self.assertEquals('Unnamed', descriptors[1].nickname)
+      self.assertEquals('5366F1D198759F8894EA6E5FF768C667F59AFD24', descriptors[1].fingerprint)
 
   def test_old_descriptor(self):
     """
     Parses a relay server descriptor from 2005.
     """
 
-    descriptor_file = open(get_resource("old_descriptor"), 'rb')
+    descriptor_file = open(get_resource('old_descriptor'), 'rb')
 
-    desc = next(stem.descriptor.parse_file(descriptor_file, "server-descriptor 1.0"))
-    self.assertEquals("krypton", desc.nickname)
-    self.assertEquals("3E2F63E2356F52318B536A12B6445373808A5D6C", desc.fingerprint)
-    self.assertEquals("212.37.39.59", desc.address)
+    desc = next(stem.descriptor.parse_file(descriptor_file, 'server-descriptor 1.0'))
+    self.assertEquals('krypton', desc.nickname)
+    self.assertEquals('3E2F63E2356F52318B536A12B6445373808A5D6C', desc.fingerprint)
+    self.assertEquals('212.37.39.59', desc.address)
     self.assertEquals(8000, desc.or_port)
     self.assertEquals(None, desc.socks_port)
     self.assertEquals(None, desc.dir_port)
-    self.assertEquals(b"Tor 0.1.0.14 on FreeBSD i386", desc.platform)
-    self.assertEquals(stem.version.Version("0.1.0.14"), desc.tor_version)
-    self.assertEquals("FreeBSD i386", desc.operating_system)
+    self.assertEquals(b'Tor 0.1.0.14 on FreeBSD i386', desc.platform)
+    self.assertEquals(stem.version.Version('0.1.0.14'), desc.tor_version)
+    self.assertEquals('FreeBSD i386', desc.operating_system)
     self.assertEquals(64820, desc.uptime)
     self.assertEquals(datetime.datetime(2005, 12, 16, 18, 1, 3), desc.published)
     self.assertEquals(None, desc.contact)
@@ -155,17 +155,17 @@ Qlx9HNCqCY877ztFRC624ja2ql6A2hBcuoYMbkHjcQ4=
 
     # lengthy test and uneffected by targets, so only run once
 
-    if test.runner.only_run_once(self, "test_cached_descriptor"):
+    if test.runner.only_run_once(self, 'test_cached_descriptor'):
       return
 
-    descriptor_path = test.runner.get_runner().get_test_dir("cached-descriptors")
+    descriptor_path = test.runner.get_runner().get_test_dir('cached-descriptors')
 
     if not os.path.exists(descriptor_path):
-      test.runner.skip(self, "(no cached descriptors)")
+      test.runner.skip(self, '(no cached descriptors)')
       return
 
     with open(descriptor_path, 'rb') as descriptor_file:
-      for desc in stem.descriptor.parse_file(descriptor_file, "server-descriptor 1.0"):
+      for desc in stem.descriptor.parse_file(descriptor_file, 'server-descriptor 1.0'):
         # the following attributes should be deprecated, and not appear in the wild
         self.assertEquals(None, desc.read_history_end)
         self.assertEquals(None, desc.write_history_end)
@@ -181,42 +181,42 @@ Qlx9HNCqCY877ztFRC624ja2ql6A2hBcuoYMbkHjcQ4=
           # there doesn't seem to be anything in practice to trigger this so
           # failing to get our attention if it does.
 
-          self.fail("Unrecognized descriptor content: %s" % unrecognized_lines)
+          self.fail('Unrecognized descriptor content: %s' % unrecognized_lines)
 
   def test_non_ascii_descriptor(self):
     """
     Parses a descriptor with non-ascii content.
     """
 
-    descriptor_file = open(get_resource("non-ascii_descriptor"), 'rb')
+    descriptor_file = open(get_resource('non-ascii_descriptor'), 'rb')
 
-    expected_contact = b"1024D/04D2E818 L\xc3\xa9na\xc3\xafc Huard <lenaic dot huard AT laposte dot net>"
+    expected_contact = b'1024D/04D2E818 L\xc3\xa9na\xc3\xafc Huard <lenaic dot huard AT laposte dot net>'
 
-    desc = next(stem.descriptor.parse_file(descriptor_file, "server-descriptor 1.0"))
-    self.assertEquals("Coruscant", desc.nickname)
-    self.assertEquals("0B9821545C48E496AEED9ECC0DB506C49FF8158D", desc.fingerprint)
-    self.assertEquals("88.182.161.122", desc.address)
+    desc = next(stem.descriptor.parse_file(descriptor_file, 'server-descriptor 1.0'))
+    self.assertEquals('Coruscant', desc.nickname)
+    self.assertEquals('0B9821545C48E496AEED9ECC0DB506C49FF8158D', desc.fingerprint)
+    self.assertEquals('88.182.161.122', desc.address)
     self.assertEquals(9001, desc.or_port)
     self.assertEquals(None, desc.socks_port)
     self.assertEquals(9030, desc.dir_port)
-    self.assertEquals(b"Tor 0.2.3.25 on Linux", desc.platform)
-    self.assertEquals(stem.version.Version("0.2.3.25"), desc.tor_version)
-    self.assertEquals("Linux", desc.operating_system)
+    self.assertEquals(b'Tor 0.2.3.25 on Linux', desc.platform)
+    self.assertEquals(stem.version.Version('0.2.3.25'), desc.tor_version)
+    self.assertEquals('Linux', desc.operating_system)
     self.assertEquals(259738, desc.uptime)
     self.assertEquals(datetime.datetime(2013, 5, 18, 11, 16, 19), desc.published)
     self.assertEquals(expected_contact, desc.contact)
-    self.assertEquals(["1", "2"], desc.link_protocols)
-    self.assertEquals(["1"], desc.circuit_protocols)
+    self.assertEquals(['1', '2'], desc.link_protocols)
+    self.assertEquals(['1'], desc.circuit_protocols)
     self.assertEquals(False, desc.hibernating)
     self.assertEquals(False, desc.allow_single_hop_exits)
     self.assertEquals(False, desc.extra_info_cache)
-    self.assertEquals("56403D838DE152421CD401B8E57DAD4483A3D56B", desc.extra_info_digest)
-    self.assertEquals(["2"], desc.hidden_service_dir)
+    self.assertEquals('56403D838DE152421CD401B8E57DAD4483A3D56B', desc.extra_info_digest)
+    self.assertEquals(['2'], desc.hidden_service_dir)
     self.assertEquals(set(), desc.family)
     self.assertEquals(102400, desc.average_bandwidth)
     self.assertEquals(204800, desc.burst_bandwidth)
     self.assertEquals(122818, desc.observed_bandwidth)
-    self.assertEquals(stem.exit_policy.ExitPolicy("reject *:*"), desc.exit_policy)
+    self.assertEquals(stem.exit_policy.ExitPolicy('reject *:*'), desc.exit_policy)
     self.assertEquals([], desc.get_unrecognized_lines())
 
     # Make sure that we can get a string representation for this descriptor
@@ -232,18 +232,18 @@ Qlx9HNCqCY877ztFRC624ja2ql6A2hBcuoYMbkHjcQ4=
     returns ('\r' entries).
     """
 
-    descriptor_file = open(get_resource("cr_in_contact_line"), 'rb')
-    desc = next(stem.descriptor.parse_file(descriptor_file, "server-descriptor 1.0"))
+    descriptor_file = open(get_resource('cr_in_contact_line'), 'rb')
+    desc = next(stem.descriptor.parse_file(descriptor_file, 'server-descriptor 1.0'))
 
-    self.assertEquals("pogonip", desc.nickname)
-    self.assertEquals("6DABD62BC65D4E6FE620293157FC76968DAB9C9B", desc.fingerprint)
-    self.assertEquals("75.5.248.48", desc.address)
+    self.assertEquals('pogonip', desc.nickname)
+    self.assertEquals('6DABD62BC65D4E6FE620293157FC76968DAB9C9B', desc.fingerprint)
+    self.assertEquals('75.5.248.48', desc.address)
 
     # the contact info block is huge so just checking the start and end,
     # including some of the embedded carriage returns
 
-    contact_start = b"jie1 at pacbell dot net -----BEGIN PGP PUBLIC KEY BLOCK-----\rVersion:"
-    contact_end = b"YFRk3NhCY=\r=Xaw3\r-----END PGP PUBLIC KEY BLOCK-----"
+    contact_start = b'jie1 at pacbell dot net -----BEGIN PGP PUBLIC KEY BLOCK-----\rVersion:'
+    contact_end = b'YFRk3NhCY=\r=Xaw3\r-----END PGP PUBLIC KEY BLOCK-----'
 
     self.assertTrue(desc.contact.startswith(contact_start))
     self.assertTrue(desc.contact.endswith(contact_end))
@@ -254,17 +254,17 @@ Qlx9HNCqCY877ztFRC624ja2ql6A2hBcuoYMbkHjcQ4=
     where we shouldn't be.
     """
 
-    descriptor_file = open(get_resource("negative_uptime"), 'rb')
-    desc = next(stem.descriptor.parse_file(descriptor_file, "server-descriptor 1.0"))
+    descriptor_file = open(get_resource('negative_uptime'), 'rb')
+    desc = next(stem.descriptor.parse_file(descriptor_file, 'server-descriptor 1.0'))
 
-    self.assertEquals("TipTor", desc.nickname)
-    self.assertEquals("137962D4931DBF08A24E843288B8A155D6D2AEDD", desc.fingerprint)
-    self.assertEquals("62.99.247.83", desc.address)
+    self.assertEquals('TipTor', desc.nickname)
+    self.assertEquals('137962D4931DBF08A24E843288B8A155D6D2AEDD', desc.fingerprint)
+    self.assertEquals('62.99.247.83', desc.address)
 
     # modify the relay version so it's after when the negative uptime bug
     # should appear
 
-    descriptor_contents = str(desc).replace("Tor 0.1.1.25", "Tor 0.1.2.7")
+    descriptor_contents = str(desc).replace('Tor 0.1.1.25', 'Tor 0.1.2.7')
     self.assertRaises(ValueError, stem.descriptor.server_descriptor.RelayDescriptor, descriptor_contents)
 
   def test_bridge_descriptor(self):
@@ -272,38 +272,38 @@ Qlx9HNCqCY877ztFRC624ja2ql6A2hBcuoYMbkHjcQ4=
     Parses a bridge descriptor.
     """
 
-    descriptor_file = open(get_resource("bridge_descriptor"), 'rb')
+    descriptor_file = open(get_resource('bridge_descriptor'), 'rb')
 
     expected_family = set([
-      "$CE396C72A3D0880F74C064FEA79D68C15BD380B9",
-      "$AB8B00C00B1347BA80A88E548FAC9EDF701D7D0E",
-      "$8C8A470D7C23151665A7B84E75E89FCC205A3304",
+      '$CE396C72A3D0880F74C064FEA79D68C15BD380B9',
+      '$AB8B00C00B1347BA80A88E548FAC9EDF701D7D0E',
+      '$8C8A470D7C23151665A7B84E75E89FCC205A3304',
     ])
 
-    desc = next(stem.descriptor.parse_file(descriptor_file, "bridge-server-descriptor 1.0"))
-    self.assertEquals("Unnamed", desc.nickname)
-    self.assertEquals("AE54E28ED069CDF45F3009F963EE3B3D6FA26A2E", desc.fingerprint)
-    self.assertEquals("10.45.227.253", desc.address)
+    desc = next(stem.descriptor.parse_file(descriptor_file, 'bridge-server-descriptor 1.0'))
+    self.assertEquals('Unnamed', desc.nickname)
+    self.assertEquals('AE54E28ED069CDF45F3009F963EE3B3D6FA26A2E', desc.fingerprint)
+    self.assertEquals('10.45.227.253', desc.address)
     self.assertEquals(9001, desc.or_port)
     self.assertEquals(None, desc.socks_port)
     self.assertEquals(None, desc.dir_port)
-    self.assertEquals(b"Tor 0.2.3.12-alpha (git-800942b4176ca31c) on Linux x86_64", desc.platform)
-    self.assertEquals(stem.version.Version("0.2.3.12-alpha"), desc.tor_version)
-    self.assertEquals("Linux x86_64", desc.operating_system)
+    self.assertEquals(b'Tor 0.2.3.12-alpha (git-800942b4176ca31c) on Linux x86_64', desc.platform)
+    self.assertEquals(stem.version.Version('0.2.3.12-alpha'), desc.tor_version)
+    self.assertEquals('Linux x86_64', desc.operating_system)
     self.assertEquals(186, desc.uptime)
     self.assertEquals(datetime.datetime(2012, 3, 22, 17, 34, 38), desc.published)
-    self.assertEquals(b"somebody", desc.contact)
-    self.assertEquals(["1", "2"], desc.link_protocols)
-    self.assertEquals(["1"], desc.circuit_protocols)
+    self.assertEquals(b'somebody', desc.contact)
+    self.assertEquals(['1', '2'], desc.link_protocols)
+    self.assertEquals(['1'], desc.circuit_protocols)
     self.assertEquals(False, desc.hibernating)
     self.assertEquals(False, desc.allow_single_hop_exits)
     self.assertEquals(False, desc.extra_info_cache)
-    self.assertEquals("134F81F7A0D270B85FCD481DD10CEA34BA7B15C9", desc.extra_info_digest)
-    self.assertEquals(["2"], desc.hidden_service_dir)
+    self.assertEquals('134F81F7A0D270B85FCD481DD10CEA34BA7B15C9', desc.extra_info_digest)
+    self.assertEquals(['2'], desc.hidden_service_dir)
     self.assertEquals(expected_family, desc.family)
     self.assertEquals(409600, desc.average_bandwidth)
     self.assertEquals(819200, desc.burst_bandwidth)
     self.assertEquals(5120, desc.observed_bandwidth)
-    self.assertEquals(stem.exit_policy.ExitPolicy("reject *:*"), desc.exit_policy)
-    self.assertEquals("006FD96BA35E7785A6A3B8B75FE2E2435A13BDB4", desc.digest())
+    self.assertEquals(stem.exit_policy.ExitPolicy('reject *:*'), desc.exit_policy)
+    self.assertEquals('006FD96BA35E7785A6A3B8B75FE2E2435A13BDB4', desc.digest())
     self.assertEquals([], desc.get_unrecognized_lines())
diff --git a/test/integ/process.py b/test/integ/process.py
index 0f309c8..d87dda4 100644
--- a/test/integ/process.py
+++ b/test/integ/process.py
@@ -34,7 +34,7 @@ class TestProcess(unittest.TestCase):
     Exercises launch_tor_with_config.
     """
 
-    if test.runner.only_run_once(self, "test_launch_tor_with_config"):
+    if test.runner.only_run_once(self, 'test_launch_tor_with_config'):
       return
 
     # Launch tor without a torrc, but with a control port. Confirms that this
@@ -57,9 +57,9 @@ class TestProcess(unittest.TestCase):
       stem.connection.authenticate(control_socket, chroot_path = runner.get_chroot())
 
       # exercises the socket
-      control_socket.send("GETCONF ControlPort")
+      control_socket.send('GETCONF ControlPort')
       getconf_response = control_socket.recv()
-      self.assertEquals("ControlPort=2778", str(getconf_response))
+      self.assertEquals('ControlPort=2778', str(getconf_response))
     finally:
       if control_socket:
         control_socket.close()
@@ -72,7 +72,7 @@ class TestProcess(unittest.TestCase):
     Runs launch_tor where it times out before completing.
     """
 
-    if test.runner.only_run_once(self, "test_launch_tor_with_timeout"):
+    if test.runner.only_run_once(self, 'test_launch_tor_with_timeout'):
       return
 
     runner = test.runner.get_runner()
@@ -82,7 +82,7 @@ class TestProcess(unittest.TestCase):
     runtime = time.time() - start_time
 
     if not (runtime > 2 and runtime < 3):
-      self.fail("Test should have taken 2-3 seconds, took %i instead" % runtime)
+      self.fail('Test should have taken 2-3 seconds, took %i instead' % runtime)
 
   @patch('os.getpid')
   def test_take_ownership_via_pid(self, getpid_mock):
@@ -91,10 +91,10 @@ class TestProcess(unittest.TestCase):
     test this we spawn a process and trick tor into thinking that it is us.
     """
 
-    if not stem.util.system.is_available("sleep"):
+    if not stem.util.system.is_available('sleep'):
       test.runner.skip(self, "('sleep' command is unavailable)")
       return
-    elif test.runner.only_run_once(self, "test_take_ownership_via_pid"):
+    elif test.runner.only_run_once(self, 'test_take_ownership_via_pid'):
       return
     elif test.runner.require_version(self, stem.version.Requirement.TAKEOWNERSHIP):
       return
@@ -135,7 +135,7 @@ class TestProcess(unittest.TestCase):
     connects, then disconnects..
     """
 
-    if test.runner.only_run_once(self, "test_take_ownership_via_controller"):
+    if test.runner.only_run_once(self, 'test_take_ownership_via_controller'):
       return
     elif test.runner.require_version(self, stem.version.Requirement.TAKEOWNERSHIP):
       return
diff --git a/test/integ/response/__init__.py b/test/integ/response/__init__.py
index d44f035..2471b66 100644
--- a/test/integ/response/__init__.py
+++ b/test/integ/response/__init__.py
@@ -2,4 +2,4 @@
 Integration tests for stem.response.
 """
 
-__all__ = ["protocolinfo"]
+__all__ = ['protocolinfo']
diff --git a/test/integ/response/protocolinfo.py b/test/integ/response/protocolinfo.py
index 6469b8d..c9ca97d 100644
--- a/test/integ/response/protocolinfo.py
+++ b/test/integ/response/protocolinfo.py
@@ -31,9 +31,9 @@ class TestProtocolInfo(unittest.TestCase):
       return
 
     control_socket = test.runner.get_runner().get_tor_socket(False)
-    control_socket.send("PROTOCOLINFO 1")
+    control_socket.send('PROTOCOLINFO 1')
     protocolinfo_response = control_socket.recv()
-    stem.response.convert("PROTOCOLINFO", protocolinfo_response)
+    stem.response.convert('PROTOCOLINFO', protocolinfo_response)
     control_socket.close()
 
     # according to the control spec the following _could_ differ or be
@@ -64,17 +64,17 @@ class TestProtocolInfo(unittest.TestCase):
     if test.runner.Torrc.PORT in test.runner.get_runner().get_options():
       lookup_prefixes = (
         stem.util.system.GET_PID_BY_PORT_NETSTAT,
-        stem.util.system.GET_PID_BY_PORT_SOCKSTAT % "",
+        stem.util.system.GET_PID_BY_PORT_SOCKSTAT % '',
         stem.util.system.GET_PID_BY_PORT_LSOF,
-        stem.util.system.GET_CWD_PWDX % "",
-        "lsof -a -p ")
+        stem.util.system.GET_CWD_PWDX % '',
+        'lsof -a -p ')
 
       control_socket = stem.socket.ControlPort(port = test.runner.CONTROL_PORT)
     else:
       lookup_prefixes = (
-        stem.util.system.GET_PID_BY_FILE_LSOF % "",
-        stem.util.system.GET_CWD_PWDX % "",
-        "lsof -a -p ")
+        stem.util.system.GET_PID_BY_FILE_LSOF % '',
+        stem.util.system.GET_CWD_PWDX % '',
+        'lsof -a -p ')
 
       control_socket = stem.socket.ControlSocketFile(test.runner.CONTROL_SOCKET_PATH)
 
@@ -116,10 +116,10 @@ class TestProtocolInfo(unittest.TestCase):
 
     with test.runner.get_runner().get_tor_socket(False) as control_socket:
       # makes a couple protocolinfo queries outside of get_protocolinfo first
-      control_socket.send("PROTOCOLINFO 1")
+      control_socket.send('PROTOCOLINFO 1')
       control_socket.recv()
 
-      control_socket.send("PROTOCOLINFO 1")
+      control_socket.send('PROTOCOLINFO 1')
       control_socket.recv()
 
       protocolinfo_response = stem.connection.get_protocolinfo(control_socket)
diff --git a/test/integ/socket/__init__.py b/test/integ/socket/__init__.py
index ec37503..3e51aa6 100644
--- a/test/integ/socket/__init__.py
+++ b/test/integ/socket/__init__.py
@@ -2,4 +2,4 @@
 Integration tests for stem.socket.
 """
 
-__all__ = ["control_message", "control_socket"]
+__all__ = ['control_message', 'control_socket']
diff --git a/test/integ/socket/control_message.py b/test/integ/socket/control_message.py
index 607d2a4..bdebb11 100644
--- a/test/integ/socket/control_message.py
+++ b/test/integ/socket/control_message.py
@@ -24,13 +24,13 @@ class TestControlMessage(unittest.TestCase):
     # hang up.
 
     control_socket = test.runner.get_runner().get_tor_socket(False)
-    control_socket.send("GETINFO version")
+    control_socket.send('GETINFO version')
 
     auth_required_response = control_socket.recv()
-    self.assertEquals("Authentication required.", str(auth_required_response))
-    self.assertEquals(["Authentication required."], list(auth_required_response))
-    self.assertEquals("514 Authentication required.\r\n", auth_required_response.raw_content())
-    self.assertEquals([("514", " ", "Authentication required.")], auth_required_response.content())
+    self.assertEquals('Authentication required.', str(auth_required_response))
+    self.assertEquals(['Authentication required.'], list(auth_required_response))
+    self.assertEquals('514 Authentication required.\r\n', auth_required_response.raw_content())
+    self.assertEquals([('514', ' ', 'Authentication required.')], auth_required_response.content())
 
     # The socket's broken but doesn't realize it yet. These use cases are
     # checked in more depth by the ControlSocket integ tests.
@@ -42,7 +42,7 @@ class TestControlMessage(unittest.TestCase):
     # Additional socket usage should fail, and pulling more responses will fail
     # with more closed exceptions.
 
-    self.assertRaises(stem.SocketError, control_socket.send, "GETINFO version")
+    self.assertRaises(stem.SocketError, control_socket.send, 'GETINFO version')
     self.assertRaises(stem.SocketClosed, control_socket.recv)
     self.assertRaises(stem.SocketClosed, control_socket.recv)
     self.assertRaises(stem.SocketClosed, control_socket.recv)
@@ -51,7 +51,7 @@ class TestControlMessage(unittest.TestCase):
     # an impact.
 
     control_socket.close()
-    self.assertRaises(stem.SocketClosed, control_socket.send, "GETINFO version")
+    self.assertRaises(stem.SocketClosed, control_socket.send, 'GETINFO version')
     self.assertRaises(stem.SocketClosed, control_socket.recv)
 
   def test_invalid_command(self):
@@ -63,7 +63,7 @@ class TestControlMessage(unittest.TestCase):
       return
 
     with test.runner.get_runner().get_tor_socket() as control_socket:
-      control_socket.send("blarg")
+      control_socket.send('blarg')
       unrecognized_command_response = control_socket.recv()
       self.assertEquals('Unrecognized command "blarg"', str(unrecognized_command_response))
       self.assertEquals(['Unrecognized command "blarg"'], list(unrecognized_command_response))
@@ -79,7 +79,7 @@ class TestControlMessage(unittest.TestCase):
       return
 
     with test.runner.get_runner().get_tor_socket() as control_socket:
-      control_socket.send("GETINFO blarg")
+      control_socket.send('GETINFO blarg')
       unrecognized_key_response = control_socket.recv()
       self.assertEquals('Unrecognized key "blarg"', str(unrecognized_key_response))
       self.assertEquals(['Unrecognized key "blarg"'], list(unrecognized_key_response))
@@ -98,12 +98,12 @@ class TestControlMessage(unittest.TestCase):
     torrc_dst = runner.get_torrc_path()
 
     with runner.get_tor_socket() as control_socket:
-      control_socket.send("GETINFO config-file")
+      control_socket.send('GETINFO config-file')
       config_file_response = control_socket.recv()
-      self.assertEquals("config-file=%s\nOK" % torrc_dst, str(config_file_response))
-      self.assertEquals(["config-file=%s" % torrc_dst, "OK"], list(config_file_response))
-      self.assertEquals("250-config-file=%s\r\n250 OK\r\n" % torrc_dst, config_file_response.raw_content())
-      self.assertEquals([("250", "-", "config-file=%s" % torrc_dst), ("250", " ", "OK")], config_file_response.content())
+      self.assertEquals('config-file=%s\nOK' % torrc_dst, str(config_file_response))
+      self.assertEquals(['config-file=%s' % torrc_dst, 'OK'], list(config_file_response))
+      self.assertEquals('250-config-file=%s\r\n250 OK\r\n' % torrc_dst, config_file_response.raw_content())
+      self.assertEquals([('250', '-', 'config-file=%s' % torrc_dst), ('250', ' ', 'OK')], config_file_response.content())
 
   def test_getinfo_config_text(self):
     """
@@ -128,27 +128,27 @@ class TestControlMessage(unittest.TestCase):
     for line in runner.get_torrc_contents().splitlines():
       line = line.strip()
 
-      if line and not line.startswith("#"):
+      if line and not line.startswith('#'):
         torrc_contents.append(line)
 
     with runner.get_tor_socket() as control_socket:
-      control_socket.send("GETINFO config-text")
+      control_socket.send('GETINFO config-text')
       config_text_response = control_socket.recv()
 
       # the response should contain two entries, the first being a data response
       self.assertEqual(2, len(list(config_text_response)))
-      self.assertEqual("OK", list(config_text_response)[1])
-      self.assertEqual(("250", " ", "OK"), config_text_response.content()[1])
-      self.assertTrue(config_text_response.raw_content().startswith("250+config-text=\r\n"))
-      self.assertTrue(config_text_response.raw_content().endswith("\r\n.\r\n250 OK\r\n"))
-      self.assertTrue(str(config_text_response).startswith("config-text=\n"))
-      self.assertTrue(str(config_text_response).endswith("\nOK"))
+      self.assertEqual('OK', list(config_text_response)[1])
+      self.assertEqual(('250', ' ', 'OK'), config_text_response.content()[1])
+      self.assertTrue(config_text_response.raw_content().startswith('250+config-text=\r\n'))
+      self.assertTrue(config_text_response.raw_content().endswith('\r\n.\r\n250 OK\r\n'))
+      self.assertTrue(str(config_text_response).startswith('config-text=\n'))
+      self.assertTrue(str(config_text_response).endswith('\nOK'))
 
       for torrc_entry in torrc_contents:
-        self.assertTrue("\n%s\n" % torrc_entry in str(config_text_response))
+        self.assertTrue('\n%s\n' % torrc_entry in str(config_text_response))
         self.assertTrue(torrc_entry in list(config_text_response)[0])
-        self.assertTrue("%s\r\n" % torrc_entry in config_text_response.raw_content())
-        self.assertTrue("%s" % torrc_entry in config_text_response.content()[0][2])
+        self.assertTrue('%s\r\n' % torrc_entry in config_text_response.raw_content())
+        self.assertTrue('%s' % torrc_entry in config_text_response.content()[0][2])
 
   def test_bw_event(self):
     """
@@ -159,17 +159,17 @@ class TestControlMessage(unittest.TestCase):
       return
 
     with test.runner.get_runner().get_tor_socket() as control_socket:
-      control_socket.send("SETEVENTS BW")
+      control_socket.send('SETEVENTS BW')
       setevents_response = control_socket.recv()
-      self.assertEquals("OK", str(setevents_response))
-      self.assertEquals(["OK"], list(setevents_response))
-      self.assertEquals("250 OK\r\n", setevents_response.raw_content())
-      self.assertEquals([("250", " ", "OK")], setevents_response.content())
+      self.assertEquals('OK', str(setevents_response))
+      self.assertEquals(['OK'], list(setevents_response))
+      self.assertEquals('250 OK\r\n', setevents_response.raw_content())
+      self.assertEquals([('250', ' ', 'OK')], setevents_response.content())
 
       # Tor will emit a BW event once per second. Parsing two of them.
 
       for _ in range(2):
         bw_event = control_socket.recv()
-        self.assertTrue(re.match("BW [0-9]+ [0-9]+", str(bw_event)))
-        self.assertTrue(re.match("650 BW [0-9]+ [0-9]+\r\n", bw_event.raw_content()))
-        self.assertEquals(("650", " "), bw_event.content()[0][:2])
+        self.assertTrue(re.match('BW [0-9]+ [0-9]+', str(bw_event)))
+        self.assertTrue(re.match('650 BW [0-9]+ [0-9]+\r\n', bw_event.raw_content()))
+        self.assertEquals(('650', ' '), bw_event.content()[0][:2])
diff --git a/test/integ/socket/control_socket.py b/test/integ/socket/control_socket.py
index a716eea..7d7b84f 100644
--- a/test/integ/socket/control_socket.py
+++ b/test/integ/socket/control_socket.py
@@ -30,12 +30,12 @@ class TestControlSocket(unittest.TestCase):
 
     with runner.get_tor_socket() as control_socket:
       for _ in range(100):
-        control_socket.send("GETINFO version")
+        control_socket.send('GETINFO version')
 
       for _ in range(100):
         response = control_socket.recv()
-        self.assertTrue(str(response).startswith("version=%s" % tor_version))
-        self.assertTrue(str(response).endswith("\nOK"))
+        self.assertTrue(str(response).startswith('version=%s' % tor_version))
+        self.assertTrue(str(response).endswith('\nOK'))
 
   def test_send_closed(self):
     """
@@ -50,7 +50,7 @@ class TestControlSocket(unittest.TestCase):
       control_socket.close()
       self.assertFalse(control_socket.is_alive())
 
-      self.assertRaises(stem.SocketClosed, control_socket.send, "blarg")
+      self.assertRaises(stem.SocketClosed, control_socket.send, 'blarg')
 
   def test_send_disconnected(self):
     """
@@ -66,18 +66,18 @@ class TestControlSocket(unittest.TestCase):
       return
 
     with test.runner.get_runner().get_tor_socket() as control_socket:
-      control_socket.send("QUIT")
-      self.assertEquals("closing connection", str(control_socket.recv()))
+      control_socket.send('QUIT')
+      self.assertEquals('closing connection', str(control_socket.recv()))
       self.assertTrue(control_socket.is_alive())
 
       # If we send another message to a port based socket then it will seem to
       # succeed. However, a file based socket should report a failure.
 
       if isinstance(control_socket, stem.socket.ControlPort):
-        control_socket.send("blarg")
+        control_socket.send('blarg')
         self.assertTrue(control_socket.is_alive())
       else:
-        self.assertRaises(stem.SocketClosed, control_socket.send, "blarg")
+        self.assertRaises(stem.SocketClosed, control_socket.send, 'blarg')
         self.assertFalse(control_socket.is_alive())
 
   def test_recv_closed(self):
@@ -105,8 +105,8 @@ class TestControlSocket(unittest.TestCase):
       return
 
     with test.runner.get_runner().get_tor_socket() as control_socket:
-      control_socket.send("QUIT")
-      self.assertEquals("closing connection", str(control_socket.recv()))
+      control_socket.send('QUIT')
+      self.assertEquals('closing connection', str(control_socket.recv()))
 
       # Neither a port or file based socket will know that tor has hung up on
       # the connection at this point. We should know after calling recv(),
@@ -130,5 +130,5 @@ class TestControlSocket(unittest.TestCase):
         stem.connection.get_protocolinfo(control_socket)
 
         control_socket.close()
-        self.assertRaises(stem.SocketClosed, control_socket.send, "PROTOCOLINFO 1")
+        self.assertRaises(stem.SocketClosed, control_socket.send, 'PROTOCOLINFO 1')
         control_socket.connect()
diff --git a/test/integ/util/__init__.py b/test/integ/util/__init__.py
index 2371a4e..7b978d2 100644
--- a/test/integ/util/__init__.py
+++ b/test/integ/util/__init__.py
@@ -2,4 +2,4 @@
 Integration tests for stem.util.* contents.
 """
 
-__all__ = ["conf", "connection", "proc", "system"]
+__all__ = ['conf', 'connection', 'proc', 'system']
diff --git a/test/integ/util/conf.py b/test/integ/util/conf.py
index 99f3acb..2a50129 100644
--- a/test/integ/util/conf.py
+++ b/test/integ/util/conf.py
@@ -47,7 +47,7 @@ coming my way?!?"""
 
 
 def _get_test_config_path():
-  return test.runner.get_runner().get_test_dir("integ_test_cfg")
+  return test.runner.get_runner().get_test_dir('integ_test_cfg')
 
 
 def _make_config(contents):
@@ -57,7 +57,7 @@ def _make_config(contents):
 
   test_config_path = _get_test_config_path()
 
-  test_conf_file = open(test_config_path, "w")
+  test_conf_file = open(test_config_path, 'w')
   test_conf_file.write(CONF_HEADER)
   test_conf_file.write(contents)
   test_conf_file.close()
@@ -68,7 +68,7 @@ def _make_config(contents):
 class TestConf(unittest.TestCase):
   def tearDown(self):
     # clears the config contents
-    test_config = stem.util.conf.get_config("integ_testing")
+    test_config = stem.util.conf.get_config('integ_testing')
     test_config.clear()
     test_config.clear_listeners()
 
@@ -83,23 +83,23 @@ class TestConf(unittest.TestCase):
     Checks that the pydoc example is correct.
     """
 
-    ssh_config = stem.util.conf.config_dict("integ_testing", {
-      "login.user": "atagar",
-      "login.password": "pepperjack_is_awesome!",
-      "destination.ip": "127.0.0.1",
-      "destination.port": 22,
-      "startup.run": [],
+    ssh_config = stem.util.conf.config_dict('integ_testing', {
+      'login.user': 'atagar',
+      'login.password': 'pepperjack_is_awesome!',
+      'destination.ip': '127.0.0.1',
+      'destination.port': 22,
+      'startup.run': [],
     })
 
     test_config_path = _make_config(EXAMPLE_CONF)
-    user_config = stem.util.conf.get_config("integ_testing")
+    user_config = stem.util.conf.get_config('integ_testing')
     user_config.load(test_config_path)
 
-    self.assertEquals("atagar", ssh_config["login.user"])
-    self.assertEquals("pepperjack_is_awesome!", ssh_config["login.password"])
-    self.assertEquals("1.2.3.4", ssh_config["destination.ip"])
-    self.assertEquals(22, ssh_config["destination.port"])
-    self.assertEquals(["export PATH=$PATH:~/bin", "alias l=ls"], ssh_config["startup.run"])
+    self.assertEquals('atagar', ssh_config['login.user'])
+    self.assertEquals('pepperjack_is_awesome!', ssh_config['login.password'])
+    self.assertEquals('1.2.3.4', ssh_config['destination.ip'])
+    self.assertEquals(22, ssh_config['destination.port'])
+    self.assertEquals(['export PATH=$PATH:~/bin', 'alias l=ls'], ssh_config['startup.run'])
 
   def test_load_multiline(self):
     """
@@ -107,13 +107,13 @@ class TestConf(unittest.TestCase):
     """
 
     test_config_path = _make_config(MULTILINE_CONF)
-    test_config = stem.util.conf.get_config("integ_testing")
+    test_config = stem.util.conf.get_config('integ_testing')
     test_config.load(test_config_path)
 
-    for entry in ("simple", "leading_whitespace", "squashed_top", "squashed_bottom"):
-      self.assertEquals("la de da\nand a ho hum", test_config.get("multiline.entry.%s" % entry))
+    for entry in ('simple', 'leading_whitespace', 'squashed_top', 'squashed_bottom'):
+      self.assertEquals('la de da\nand a ho hum', test_config.get('multiline.entry.%s' % entry))
 
-    self.assertEquals("", test_config.get("multiline.entry.empty"))
+    self.assertEquals('', test_config.get('multiline.entry.empty'))
 
   def test_save(self):
     """
@@ -121,18 +121,18 @@ class TestConf(unittest.TestCase):
     """
 
     # makes a configuration with a variety of types
-    test_config = stem.util.conf.get_config("integ_testing")
+    test_config = stem.util.conf.get_config('integ_testing')
 
-    test_config.set("single_value", "yup, I'm there")
-    test_config.set("multiple_values", "a", False)
-    test_config.set("multiple_values", "b", False)
-    test_config.set("multiple_values", "c", False)
-    test_config.set("multiline_value", HERALD_POEM)
+    test_config.set('single_value', "yup, I'm there")
+    test_config.set('multiple_values', 'a', False)
+    test_config.set('multiple_values', 'b', False)
+    test_config.set('multiple_values', 'c', False)
+    test_config.set('multiline_value', HERALD_POEM)
 
     test_config.save(_get_test_config_path())
     test_config.clear()
     test_config.load()
 
-    self.assertEquals("yup, I'm there", test_config.get_value("single_value"))
-    self.assertEquals(["a", "b", "c"], test_config.get_value("multiple_values", multiple = True))
-    self.assertEquals(HERALD_POEM, test_config.get_value("multiline_value"))
+    self.assertEquals("yup, I'm there", test_config.get_value('single_value'))
+    self.assertEquals(['a', 'b', 'c'], test_config.get_value('multiple_values', multiple = True))
+    self.assertEquals(HERALD_POEM, test_config.get_value('multiline_value'))
diff --git a/test/integ/util/connection.py b/test/integ/util/connection.py
index 70ad7f9..4c05f74 100644
--- a/test/integ/util/connection.py
+++ b/test/integ/util/connection.py
@@ -15,10 +15,10 @@ class TestConnection(unittest.TestCase):
     runner = test.runner.get_runner()
 
     if not test.runner.Torrc.PORT in runner.get_options():
-      test.runner.skip(self, "(no control port)")
+      test.runner.skip(self, '(no control port)')
       return
     elif not test.runner.get_runner().is_ptraceable():
-      test.runner.skip(self, "(DisableDebuggerAttachment is set)")
+      test.runner.skip(self, '(DisableDebuggerAttachment is set)')
       return
 
     for resolver in get_system_resolvers():
@@ -30,4 +30,4 @@ class TestConnection(unittest.TestCase):
           if conn.local_address == '127.0.0.1' and conn.local_port == test.runner.CONTROL_PORT:
             return
 
-        self.fail("Unable to find localhost connection with %s:\n%s" % (resolver, '\n'.join(connections)))
+        self.fail('Unable to find localhost connection with %s:\n%s' % (resolver, '\n'.join(connections)))
diff --git a/test/integ/util/proc.py b/test/integ/util/proc.py
index 24bb805..4a43e84 100644
--- a/test/integ/util/proc.py
+++ b/test/integ/util/proc.py
@@ -18,10 +18,10 @@ class TestProc(unittest.TestCase):
     """
 
     if not proc.is_available():
-      test.runner.skip(self, "(proc unavailable)")
+      test.runner.skip(self, '(proc unavailable)')
       return
     elif not test.runner.get_runner().is_ptraceable():
-      test.runner.skip(self, "(DisableDebuggerAttachment is set)")
+      test.runner.skip(self, '(DisableDebuggerAttachment is set)')
       return
 
     runner = test.runner.get_runner()
@@ -34,7 +34,7 @@ class TestProc(unittest.TestCase):
     """
 
     if not proc.is_available():
-      test.runner.skip(self, "(proc unavailable)")
+      test.runner.skip(self, '(proc unavailable)')
       return
 
     tor_pid = test.runner.get_runner().get_pid()
@@ -46,7 +46,7 @@ class TestProc(unittest.TestCase):
     """
 
     if not proc.is_available():
-      test.runner.skip(self, "(proc unavailable)")
+      test.runner.skip(self, '(proc unavailable)')
       return
 
     tor_pid = test.runner.get_runner().get_pid()
@@ -62,7 +62,7 @@ class TestProc(unittest.TestCase):
     """
 
     if not proc.is_available():
-      test.runner.skip(self, "(proc unavailable)")
+      test.runner.skip(self, '(proc unavailable)')
       return
 
     tor_pid = test.runner.get_runner().get_pid()
@@ -82,13 +82,13 @@ class TestProc(unittest.TestCase):
     runner = test.runner.get_runner()
 
     if not proc.is_available():
-      test.runner.skip(self, "(proc unavailable)")
+      test.runner.skip(self, '(proc unavailable)')
       return
     elif not test.runner.Torrc.PORT in runner.get_options():
-      test.runner.skip(self, "(no control port)")
+      test.runner.skip(self, '(no control port)')
       return
     elif not test.runner.get_runner().is_ptraceable():
-      test.runner.skip(self, "(DisableDebuggerAttachment is set)")
+      test.runner.skip(self, '(DisableDebuggerAttachment is set)')
       return
 
     # making a controller connection so that we have something to query for
@@ -96,7 +96,7 @@ class TestProc(unittest.TestCase):
       tor_pid = test.runner.get_runner().get_pid()
 
       for conn in proc.get_connections(tor_pid):
-        if ("127.0.0.1", test.runner.CONTROL_PORT) == conn[:2]:
+        if ('127.0.0.1', test.runner.CONTROL_PORT) == conn[:2]:
           return
 
       self.fail()
diff --git a/test/integ/util/system.py b/test/integ/util/system.py
index 0f37e90..69b7c78 100644
--- a/test/integ/util/system.py
+++ b/test/integ/util/system.py
@@ -54,25 +54,27 @@ class TestSystem(unittest.TestCase):
     """
 
     # I have yet to see a platform without 'ls'
+
     if stem.util.system.is_windows():
-      self.assertTrue(stem.util.system.is_available("dir"))
+      self.assertTrue(stem.util.system.is_available('dir'))
     else:
-      self.assertTrue(stem.util.system.is_available("ls"))
+      self.assertTrue(stem.util.system.is_available('ls'))
 
     # but it would be kinda weird if this did...
-    self.assertFalse(stem.util.system.is_available("blarg_and_stuff"))
+
+    self.assertFalse(stem.util.system.is_available('blarg_and_stuff'))
 
   def test_is_running(self):
     """
     Checks the stem.util.system.is_running function.
     """
 
-    if not stem.util.system.is_available("ps"):
-      test.runner.skip(self, "(ps unavailable)")
+    if not stem.util.system.is_available('ps'):
+      test.runner.skip(self, '(ps unavailable)')
       return
 
-    self.assertTrue(stem.util.system.is_running("tor"))
-    self.assertFalse(stem.util.system.is_running("blarg_and_stuff"))
+    self.assertTrue(stem.util.system.is_running('tor'))
+    self.assertFalse(stem.util.system.is_running('blarg_and_stuff'))
 
   def test_get_pid_by_name(self):
     """
@@ -81,15 +83,15 @@ class TestSystem(unittest.TestCase):
     """
 
     if stem.util.system.is_windows():
-      test.runner.skip(self, "(unavailable on windows)")
+      test.runner.skip(self, '(unavailable on windows)')
       return
     elif self._is_extra_tor_running():
-      test.runner.skip(self, "(multiple tor instances)")
+      test.runner.skip(self, '(multiple tor instances)')
       return
 
     tor_pid = test.runner.get_runner().get_pid()
-    self.assertEquals(tor_pid, stem.util.system.get_pid_by_name("tor"))
-    self.assertEquals(None, stem.util.system.get_pid_by_name("blarg_and_stuff"))
+    self.assertEquals(tor_pid, stem.util.system.get_pid_by_name('tor'))
+    self.assertEquals(None, stem.util.system.get_pid_by_name('blarg_and_stuff'))
 
   def test_get_pid_by_name_pgrep(self):
     """
@@ -97,13 +99,13 @@ class TestSystem(unittest.TestCase):
     """
 
     if self._is_extra_tor_running():
-      test.runner.skip(self, "(multiple tor instances)")
+      test.runner.skip(self, '(multiple tor instances)')
       return
-    elif not stem.util.system.is_available("pgrep"):
-      test.runner.skip(self, "(pgrep unavailable)")
+    elif not stem.util.system.is_available('pgrep'):
+      test.runner.skip(self, '(pgrep unavailable)')
       return
 
-    pgrep_prefix = stem.util.system.GET_PID_BY_NAME_PGREP % ""
+    pgrep_prefix = stem.util.system.GET_PID_BY_NAME_PGREP % ''
 
     call_replacement = filter_system_call([pgrep_prefix])
 
@@ -111,7 +113,7 @@ class TestSystem(unittest.TestCase):
       call_mock.side_effect = call_replacement
 
       tor_pid = test.runner.get_runner().get_pid()
-      self.assertEquals(tor_pid, stem.util.system.get_pid_by_name("tor"))
+      self.assertEquals(tor_pid, stem.util.system.get_pid_by_name('tor'))
 
   def test_get_pid_by_name_pidof(self):
     """
@@ -119,13 +121,13 @@ class TestSystem(unittest.TestCase):
     """
 
     if self._is_extra_tor_running():
-      test.runner.skip(self, "(multiple tor instances)")
+      test.runner.skip(self, '(multiple tor instances)')
       return
-    elif not stem.util.system.is_available("pidof"):
-      test.runner.skip(self, "(pidof unavailable)")
+    elif not stem.util.system.is_available('pidof'):
+      test.runner.skip(self, '(pidof unavailable)')
       return
 
-    pidof_prefix = stem.util.system.GET_PID_BY_NAME_PIDOF % ""
+    pidof_prefix = stem.util.system.GET_PID_BY_NAME_PIDOF % ''
 
     call_replacement = filter_system_call([pidof_prefix])
 
@@ -133,7 +135,7 @@ class TestSystem(unittest.TestCase):
       call_mock.side_effect = call_replacement
 
       tor_pid = test.runner.get_runner().get_pid()
-      self.assertEquals(tor_pid, stem.util.system.get_pid_by_name("tor"))
+      self.assertEquals(tor_pid, stem.util.system.get_pid_by_name('tor'))
 
   def test_get_pid_by_name_ps_linux(self):
     """
@@ -141,16 +143,16 @@ class TestSystem(unittest.TestCase):
     """
 
     if self._is_extra_tor_running():
-      test.runner.skip(self, "(multiple tor instances)")
+      test.runner.skip(self, '(multiple tor instances)')
       return
-    elif not stem.util.system.is_available("ps"):
-      test.runner.skip(self, "(ps unavailable)")
+    elif not stem.util.system.is_available('ps'):
+      test.runner.skip(self, '(ps unavailable)')
       return
     elif stem.util.system.is_bsd():
-      test.runner.skip(self, "(linux only)")
+      test.runner.skip(self, '(linux only)')
       return
 
-    ps_prefix = stem.util.system.GET_PID_BY_NAME_PS_LINUX % ""
+    ps_prefix = stem.util.system.GET_PID_BY_NAME_PS_LINUX % ''
 
     call_replacement = filter_system_call([ps_prefix])
 
@@ -158,7 +160,7 @@ class TestSystem(unittest.TestCase):
       call_mock.side_effect = call_replacement
 
       tor_pid = test.runner.get_runner().get_pid()
-      self.assertEquals(tor_pid, stem.util.system.get_pid_by_name("tor"))
+      self.assertEquals(tor_pid, stem.util.system.get_pid_by_name('tor'))
 
   def test_get_pid_by_name_ps_bsd(self):
     """
@@ -166,13 +168,13 @@ class TestSystem(unittest.TestCase):
     """
 
     if self._is_extra_tor_running():
-      test.runner.skip(self, "(multiple tor instances)")
+      test.runner.skip(self, '(multiple tor instances)')
       return
-    elif not stem.util.system.is_available("ps"):
-      test.runner.skip(self, "(ps unavailable)")
+    elif not stem.util.system.is_available('ps'):
+      test.runner.skip(self, '(ps unavailable)')
       return
     elif not stem.util.system.is_bsd():
-      test.runner.skip(self, "(bsd only)")
+      test.runner.skip(self, '(bsd only)')
       return
 
     ps_prefix = stem.util.system.GET_PID_BY_NAME_PS_BSD
@@ -183,7 +185,7 @@ class TestSystem(unittest.TestCase):
       call_mock.side_effect = call_replacement
 
       tor_pid = test.runner.get_runner().get_pid()
-      self.assertEquals(tor_pid, stem.util.system.get_pid_by_name("tor"))
+      self.assertEquals(tor_pid, stem.util.system.get_pid_by_name('tor'))
 
   def test_get_pid_by_name_lsof(self):
     """
@@ -192,16 +194,16 @@ class TestSystem(unittest.TestCase):
 
     runner = test.runner.get_runner()
     if self._is_extra_tor_running():
-      test.runner.skip(self, "(multiple tor instances)")
+      test.runner.skip(self, '(multiple tor instances)')
       return
-    elif not stem.util.system.is_available("lsof"):
-      test.runner.skip(self, "(lsof unavailable)")
+    elif not stem.util.system.is_available('lsof'):
+      test.runner.skip(self, '(lsof unavailable)')
       return
     elif not runner.is_ptraceable():
-      test.runner.skip(self, "(DisableDebuggerAttachment is set)")
+      test.runner.skip(self, '(DisableDebuggerAttachment is set)')
       return
 
-    lsof_prefix = stem.util.system.GET_PID_BY_NAME_LSOF % ""
+    lsof_prefix = stem.util.system.GET_PID_BY_NAME_LSOF % ''
 
     call_replacement = filter_system_call([lsof_prefix])
 
@@ -209,7 +211,7 @@ class TestSystem(unittest.TestCase):
       call_mock.side_effect = call_replacement
 
       our_tor_pid = test.runner.get_runner().get_pid()
-      all_tor_pids = stem.util.system.get_pid_by_name("tor", multiple = True)
+      all_tor_pids = stem.util.system.get_pid_by_name('tor', multiple = True)
 
       if len(all_tor_pids) == 1:
         self.assertEquals(our_tor_pid, all_tor_pids[0])
@@ -221,21 +223,21 @@ class TestSystem(unittest.TestCase):
 
     runner = test.runner.get_runner()
     if stem.util.system.is_windows():
-      test.runner.skip(self, "(unavailable on windows)")
+      test.runner.skip(self, '(unavailable on windows)')
       return
     elif not _has_port():
-      test.runner.skip(self, "(test instance has no port)")
+      test.runner.skip(self, '(test instance has no port)')
       return
     elif stem.util.system.is_mac():
-      test.runner.skip(self, "(resolvers unavailable)")
+      test.runner.skip(self, '(resolvers unavailable)')
       return
     elif not runner.is_ptraceable():
-      test.runner.skip(self, "(DisableDebuggerAttachment is set)")
+      test.runner.skip(self, '(DisableDebuggerAttachment is set)')
       return
-    elif not (stem.util.system.is_available("netstat") or
-              stem.util.system.is_available("sockstat") or
-              stem.util.system.is_available("lsof")):
-      test.runner.skip(self, "(connection resolvers unavailable)")
+    elif not (stem.util.system.is_available('netstat') or
+              stem.util.system.is_available('sockstat') or
+              stem.util.system.is_available('lsof')):
+      test.runner.skip(self, '(connection resolvers unavailable)')
       return
 
     tor_pid, tor_port = runner.get_pid(), test.runner.CONTROL_PORT
@@ -249,16 +251,16 @@ class TestSystem(unittest.TestCase):
 
     runner = test.runner.get_runner()
     if not _has_port():
-      test.runner.skip(self, "(test instance has no port)")
+      test.runner.skip(self, '(test instance has no port)')
       return
-    elif not stem.util.system.is_available("netstat"):
-      test.runner.skip(self, "(netstat unavailable)")
+    elif not stem.util.system.is_available('netstat'):
+      test.runner.skip(self, '(netstat unavailable)')
       return
     elif stem.util.system.is_bsd() or stem.util.system.is_windows():
-      test.runner.skip(self, "(linux only)")
+      test.runner.skip(self, '(linux only)')
       return
     elif not runner.is_ptraceable():
-      test.runner.skip(self, "(DisableDebuggerAttachment is set)")
+      test.runner.skip(self, '(DisableDebuggerAttachment is set)')
       return
 
     netstat_prefix = stem.util.system.GET_PID_BY_PORT_NETSTAT
@@ -278,19 +280,19 @@ class TestSystem(unittest.TestCase):
 
     runner = test.runner.get_runner()
     if not _has_port():
-      test.runner.skip(self, "(test instance has no port)")
+      test.runner.skip(self, '(test instance has no port)')
       return
-    elif not stem.util.system.is_available("sockstat"):
-      test.runner.skip(self, "(sockstat unavailable)")
+    elif not stem.util.system.is_available('sockstat'):
+      test.runner.skip(self, '(sockstat unavailable)')
       return
     elif not stem.util.system.is_bsd():
-      test.runner.skip(self, "(bsd only)")
+      test.runner.skip(self, '(bsd only)')
       return
     elif not runner.is_ptraceable():
-      test.runner.skip(self, "(DisableDebuggerAttachment is set)")
+      test.runner.skip(self, '(DisableDebuggerAttachment is set)')
       return
 
-    sockstat_prefix = stem.util.system.GET_PID_BY_PORT_SOCKSTAT % ""
+    sockstat_prefix = stem.util.system.GET_PID_BY_PORT_SOCKSTAT % ''
 
     call_replacement = filter_system_call([sockstat_prefix])
 
@@ -307,16 +309,16 @@ class TestSystem(unittest.TestCase):
 
     runner = test.runner.get_runner()
     if not _has_port():
-      test.runner.skip(self, "(test instance has no port)")
+      test.runner.skip(self, '(test instance has no port)')
       return
-    elif not stem.util.system.is_available("lsof"):
-      test.runner.skip(self, "(lsof unavailable)")
+    elif not stem.util.system.is_available('lsof'):
+      test.runner.skip(self, '(lsof unavailable)')
       return
     elif stem.util.system.is_mac():
-      test.runner.skip(self, "(resolvers unavailable)")
+      test.runner.skip(self, '(resolvers unavailable)')
       return
     elif not runner.is_ptraceable():
-      test.runner.skip(self, "(DisableDebuggerAttachment is set)")
+      test.runner.skip(self, '(DisableDebuggerAttachment is set)')
       return
 
     lsof_prefix = stem.util.system.GET_PID_BY_PORT_LSOF
@@ -350,10 +352,10 @@ class TestSystem(unittest.TestCase):
     runner = test.runner.get_runner()
 
     if stem.util.system.is_windows():
-      test.runner.skip(self, "(unavailable on windows)")
+      test.runner.skip(self, '(unavailable on windows)')
       return
     elif not runner.is_ptraceable():
-      test.runner.skip(self, "(DisableDebuggerAttachment is set)")
+      test.runner.skip(self, '(DisableDebuggerAttachment is set)')
       return
 
     runner_pid, tor_cwd = runner.get_pid(), runner.get_tor_cwd()
@@ -366,15 +368,17 @@ class TestSystem(unittest.TestCase):
     """
 
     runner = test.runner.get_runner()
-    if not stem.util.system.is_available("pwdx"):
-      test.runner.skip(self, "(pwdx unavailable)")
+
+    if not stem.util.system.is_available('pwdx'):
+      test.runner.skip(self, '(pwdx unavailable)')
       return
     elif not runner.is_ptraceable():
-      test.runner.skip(self, "(DisableDebuggerAttachment is set)")
+      test.runner.skip(self, '(DisableDebuggerAttachment is set)')
       return
 
     # filter the call function to only allow this command
-    pwdx_prefix = stem.util.system.GET_CWD_PWDX % ""
+
+    pwdx_prefix = stem.util.system.GET_CWD_PWDX % ''
 
     call_replacement = filter_system_call([pwdx_prefix])
 
@@ -390,15 +394,17 @@ class TestSystem(unittest.TestCase):
     """
 
     runner = test.runner.get_runner()
-    if not stem.util.system.is_available("lsof"):
-      test.runner.skip(self, "(lsof unavailable)")
+
+    if not stem.util.system.is_available('lsof'):
+      test.runner.skip(self, '(lsof unavailable)')
       return
     elif not runner.is_ptraceable():
-      test.runner.skip(self, "(DisableDebuggerAttachment is set)")
+      test.runner.skip(self, '(DisableDebuggerAttachment is set)')
       return
 
     # filter the call function to only allow this command
-    lsof_prefix = "lsof -a -p "
+
+    lsof_prefix = 'lsof -a -p '
 
     call_replacement = filter_system_call([lsof_prefix])
 
@@ -423,7 +429,7 @@ class TestSystem(unittest.TestCase):
     """
 
     if not stem.util.proc.is_available():
-      test.runner.skip(self, "(proc unavailable)")
+      test.runner.skip(self, '(proc unavailable)')
       return
 
     call_replacement = filter_system_call(['ps '])
@@ -442,8 +448,8 @@ class TestSystem(unittest.TestCase):
     Tests the get_user function with a ps response.
     """
 
-    if not stem.util.system.is_available("ps"):
-      test.runner.skip(self, "(ps unavailable)")
+    if not stem.util.system.is_available('ps'):
+      test.runner.skip(self, '(ps unavailable)')
       return
 
     pid = test.runner.get_runner().get_pid()
@@ -464,7 +470,7 @@ class TestSystem(unittest.TestCase):
     """
 
     if not stem.util.proc.is_available():
-      test.runner.skip(self, "(proc unavailable)")
+      test.runner.skip(self, '(proc unavailable)')
       return
 
     call_replacement = filter_system_call(['ps '])
@@ -481,8 +487,8 @@ class TestSystem(unittest.TestCase):
     Tests the get_start_time function with a ps response.
     """
 
-    if not stem.util.system.is_available("ps"):
-      test.runner.skip(self, "(ps unavailable)")
+    if not stem.util.system.is_available('ps'):
+      test.runner.skip(self, '(ps unavailable)')
       return
 
     pid = test.runner.get_runner().get_pid()
@@ -505,25 +511,25 @@ class TestSystem(unittest.TestCase):
     # Some of the following tests get confused when ran as root. For instance,
     # in my case...
     #
-    #   >>> os.path.expanduser("~")
+    #   >>> os.path.expanduser('~')
     #   '/home/atagar'
     #
-    #   >>> os.path.expanduser("~root")
+    #   >>> os.path.expanduser('~root')
     #   '/root'
 
     if getpass.getuser() == 'root':
-      test.runner.skip(self, "(running as root)")
+      test.runner.skip(self, '(running as root)')
       return
 
-    self.assertEquals(os.getcwd(), stem.util.system.expand_path("."))
-    self.assertEquals(os.getcwd(), stem.util.system.expand_path("./"))
-    self.assertEquals(os.path.join(os.getcwd(), "foo"), stem.util.system.expand_path("./foo"))
+    self.assertEquals(os.getcwd(), stem.util.system.expand_path('.'))
+    self.assertEquals(os.getcwd(), stem.util.system.expand_path('./'))
+    self.assertEquals(os.path.join(os.getcwd(), 'foo'), stem.util.system.expand_path('./foo'))
 
-    home_dir, username = os.path.expanduser("~"), getpass.getuser()
-    self.assertEquals(home_dir, stem.util.system.expand_path("~"))
-    self.assertEquals(home_dir, stem.util.system.expand_path("~/"))
-    self.assertEquals(home_dir, stem.util.system.expand_path("~%s" % username))
-    self.assertEquals(os.path.join(home_dir, "foo"), stem.util.system.expand_path("~%s/foo" % username))
+    home_dir, username = os.path.expanduser('~'), getpass.getuser()
+    self.assertEquals(home_dir, stem.util.system.expand_path('~'))
+    self.assertEquals(home_dir, stem.util.system.expand_path('~/'))
+    self.assertEquals(home_dir, stem.util.system.expand_path('~%s' % username))
+    self.assertEquals(os.path.join(home_dir, 'foo'), stem.util.system.expand_path('~%s/foo' % username))
 
   def test_set_process_name(self):
     """
@@ -531,11 +537,11 @@ class TestSystem(unittest.TestCase):
     """
 
     initial_name = stem.util.system.get_process_name()
-    self.assertTrue("run_tests.py" in initial_name)
+    self.assertTrue('run_tests.py' in initial_name)
 
     try:
-      stem.util.system.set_process_name("stem_integ")
-      self.assertEqual("stem_integ", stem.util.system.get_process_name())
+      stem.util.system.set_process_name('stem_integ')
+      self.assertEqual('stem_integ', stem.util.system.get_process_name())
     finally:
       stem.util.system.set_process_name(initial_name)
 
@@ -552,11 +558,11 @@ class TestSystem(unittest.TestCase):
         # TODO: not sure how to check for this on windows
         IS_EXTRA_TOR_RUNNING = False
       elif not stem.util.system.is_bsd():
-        pgrep_results = stem.util.system.call(stem.util.system.GET_PID_BY_NAME_PGREP % "tor")
+        pgrep_results = stem.util.system.call(stem.util.system.GET_PID_BY_NAME_PGREP % 'tor')
         IS_EXTRA_TOR_RUNNING = len(pgrep_results) > 1
       else:
         ps_results = stem.util.system.call(stem.util.system.GET_PID_BY_NAME_PS_BSD)
-        results = [r for r in ps_results if r.endswith(" tor")]
+        results = [r for r in ps_results if r.endswith(' tor')]
         IS_EXTRA_TOR_RUNNING = len(results) > 1
 
     return IS_EXTRA_TOR_RUNNING
diff --git a/test/integ/version.py b/test/integ/version.py
index f3f3fc1..7269ab1 100644
--- a/test/integ/version.py
+++ b/test/integ/version.py
@@ -16,7 +16,7 @@ class TestVersion(unittest.TestCase):
     Basic verification checks for the get_system_tor_version() function.
     """
 
-    if not stem.util.system.is_available("tor"):
+    if not stem.util.system.is_available('tor'):
       test.runner.skip(self, "(tor isn't in our path)")
       return
 
@@ -27,10 +27,10 @@ class TestVersion(unittest.TestCase):
     stem.version.get_system_tor_version()
 
     # try running against a command that exists, but isn't tor
-    self.assertRaises(IOError, stem.version.get_system_tor_version, "ls")
+    self.assertRaises(IOError, stem.version.get_system_tor_version, 'ls')
 
     # try running against a command that doesn't exist
-    self.assertRaises(IOError, stem.version.get_system_tor_version, "blarg")
+    self.assertRaises(IOError, stem.version.get_system_tor_version, 'blarg')
 
   def test_get_system_tor_version_value(self):
     """
@@ -55,7 +55,7 @@ class TestVersion(unittest.TestCase):
       return
 
     control_socket = test.runner.get_runner().get_tor_socket()
-    control_socket.send("GETINFO version")
+    control_socket.send('GETINFO version')
     version_response = control_socket.recv()
     control_socket.close()
 
diff --git a/test/mocking.py b/test/mocking.py
index 2b73b9f..bfd68f6 100644
--- a/test/mocking.py
+++ b/test/mocking.py
@@ -55,120 +55,120 @@ WPi4Fl2qryzTb3QO5r5x7T8OsG2IBUET1bLQzmtbC560SYR49IvVAgMBAAE=
 """
 
 DOC_SIG = stem.descriptor.networkstatus.DocumentSignature(
-  "sha1",
-  "14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4",
-  "BF112F1C6D5543CFD0A32215ACABD4197B5279AD",
-  "-----BEGIN SIGNATURE-----%s-----END SIGNATURE-----" % CRYPTO_BLOB)
+  'sha1',
+  '14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4',
+  'BF112F1C6D5543CFD0A32215ACABD4197B5279AD',
+  '-----BEGIN SIGNATURE-----%s-----END SIGNATURE-----' % CRYPTO_BLOB)
 
 RELAY_SERVER_HEADER = (
-  ("router", "caerSidi 71.35.133.197 9001 0 0"),
-  ("published", "2012-03-01 17:15:27"),
-  ("bandwidth", "153600 256000 104590"),
-  ("reject", "*:*"),
-  ("onion-key", "\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----" % CRYPTO_BLOB),
-  ("signing-key", "\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----" % CRYPTO_BLOB),
+  ('router', 'caerSidi 71.35.133.197 9001 0 0'),
+  ('published', '2012-03-01 17:15:27'),
+  ('bandwidth', '153600 256000 104590'),
+  ('reject', '*:*'),
+  ('onion-key', '\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----' % CRYPTO_BLOB),
+  ('signing-key', '\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----' % CRYPTO_BLOB),
 )
 
 RELAY_SERVER_FOOTER = (
-  ("router-signature", "\n-----BEGIN SIGNATURE-----%s-----END SIGNATURE-----" % CRYPTO_BLOB),
+  ('router-signature', '\n-----BEGIN SIGNATURE-----%s-----END SIGNATURE-----' % CRYPTO_BLOB),
 )
 
 BRIDGE_SERVER_HEADER = (
-  ("router", "Unnamed 10.45.227.253 9001 0 0"),
-  ("router-digest", "006FD96BA35E7785A6A3B8B75FE2E2435A13BDB4"),
-  ("published", "2012-03-22 17:34:38"),
-  ("bandwidth", "409600 819200 5120"),
-  ("reject", "*:*"),
+  ('router', 'Unnamed 10.45.227.253 9001 0 0'),
+  ('router-digest', '006FD96BA35E7785A6A3B8B75FE2E2435A13BDB4'),
+  ('published', '2012-03-22 17:34:38'),
+  ('bandwidth', '409600 819200 5120'),
+  ('reject', '*:*'),
 )
 
 RELAY_EXTRAINFO_HEADER = (
-  ("extra-info", "ninja B2289C3EAB83ECD6EB916A2F481A02E6B76A0A48"),
-  ("published", "2012-05-05 17:03:50"),
+  ('extra-info', 'ninja B2289C3EAB83ECD6EB916A2F481A02E6B76A0A48'),
+  ('published', '2012-05-05 17:03:50'),
 )
 
 RELAY_EXTRAINFO_FOOTER = (
-  ("router-signature", "\n-----BEGIN SIGNATURE-----%s-----END SIGNATURE-----" % CRYPTO_BLOB),
+  ('router-signature', '\n-----BEGIN SIGNATURE-----%s-----END SIGNATURE-----' % CRYPTO_BLOB),
 )
 
 BRIDGE_EXTRAINFO_HEADER = (
-  ("extra-info", "ec2bridgereaac65a3 1EC248422B57D9C0BD751892FE787585407479A4"),
-  ("published", "2012-05-05 17:03:50"),
+  ('extra-info', 'ec2bridgereaac65a3 1EC248422B57D9C0BD751892FE787585407479A4'),
+  ('published', '2012-05-05 17:03:50'),
 )
 
 BRIDGE_EXTRAINFO_FOOTER = (
-  ("router-digest", "006FD96BA35E7785A6A3B8B75FE2E2435A13BDB4"),
+  ('router-digest', '006FD96BA35E7785A6A3B8B75FE2E2435A13BDB4'),
 )
 
 MICRODESCRIPTOR = (
-  ("onion-key", "\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----" % CRYPTO_BLOB),
+  ('onion-key', '\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----' % CRYPTO_BLOB),
 )
 
 ROUTER_STATUS_ENTRY_V2_HEADER = (
-  ("r", "caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0"),
+  ('r', 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0'),
 )
 
 ROUTER_STATUS_ENTRY_V3_HEADER = (
-  ("r", "caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0"),
-  ("s", "Fast Named Running Stable Valid"),
+  ('r', 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0'),
+  ('s', 'Fast Named Running Stable Valid'),
 )
 
 ROUTER_STATUS_ENTRY_MICRO_V3_HEADER = (
-  ("r", "Konata ARIJF2zbqirB9IwsW0mQznccWww 2012-09-24 13:40:40 69.64.48.168 9001 9030"),
-  ("m", "aiUklwBrua82obG5AsTX+iEpkjQA2+AQHxZ7GwMfY70"),
-  ("s", "Fast Guard HSDir Named Running Stable V2Dir Valid"),
+  ('r', 'Konata ARIJF2zbqirB9IwsW0mQznccWww 2012-09-24 13:40:40 69.64.48.168 9001 9030'),
+  ('m', 'aiUklwBrua82obG5AsTX+iEpkjQA2+AQHxZ7GwMfY70'),
+  ('s', 'Fast Guard HSDir Named Running Stable V2Dir Valid'),
 )
 
 AUTHORITY_HEADER = (
-  ("dir-source", "turtles 27B6B5996C426270A5C95488AA5BCEB6BCC86956 no.place.com 76.73.17.194 9030 9090"),
-  ("contact", "Mike Perry <email>"),
+  ('dir-source', 'turtles 27B6B5996C426270A5C95488AA5BCEB6BCC86956 no.place.com 76.73.17.194 9030 9090'),
+  ('contact', 'Mike Perry <email>'),
 )
 
 KEY_CERTIFICATE_HEADER = (
-  ("dir-key-certificate-version", "3"),
-  ("fingerprint", "27B6B5996C426270A5C95488AA5BCEB6BCC86956"),
-  ("dir-key-published", "2011-11-28 21:51:04"),
-  ("dir-key-expires", "2012-11-28 21:51:04"),
-  ("dir-identity-key", "\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----" % CRYPTO_BLOB),
-  ("dir-signing-key", "\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----" % CRYPTO_BLOB),
+  ('dir-key-certificate-version', '3'),
+  ('fingerprint', '27B6B5996C426270A5C95488AA5BCEB6BCC86956'),
+  ('dir-key-published', '2011-11-28 21:51:04'),
+  ('dir-key-expires', '2012-11-28 21:51:04'),
+  ('dir-identity-key', '\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----' % CRYPTO_BLOB),
+  ('dir-signing-key', '\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----' % CRYPTO_BLOB),
 )
 
 KEY_CERTIFICATE_FOOTER = (
-  ("dir-key-certification", "\n-----BEGIN SIGNATURE-----%s-----END SIGNATURE-----" % CRYPTO_BLOB),
+  ('dir-key-certification', '\n-----BEGIN SIGNATURE-----%s-----END SIGNATURE-----' % CRYPTO_BLOB),
 )
 
 NETWORK_STATUS_DOCUMENT_HEADER_V2 = (
-  ("network-status-version", "2"),
-  ("dir-source", "18.244.0.114 18.244.0.114 80"),
-  ("fingerprint", "719BE45DE224B607C53707D0E2143E2D423E74CF"),
-  ("contact", "arma at mit dot edu"),
-  ("published", "2005-12-16 00:13:46"),
-  ("dir-signing-key", "\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----" % CRYPTO_BLOB),
+  ('network-status-version', '2'),
+  ('dir-source', '18.244.0.114 18.244.0.114 80'),
+  ('fingerprint', '719BE45DE224B607C53707D0E2143E2D423E74CF'),
+  ('contact', 'arma at mit dot edu'),
+  ('published', '2005-12-16 00:13:46'),
+  ('dir-signing-key', '\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----' % CRYPTO_BLOB),
 )
 
 NETWORK_STATUS_DOCUMENT_FOOTER_V2 = (
-  ("directory-signature", "moria2\n-----BEGIN SIGNATURE-----%s-----END SIGNATURE-----" % CRYPTO_BLOB),
+  ('directory-signature', 'moria2\n-----BEGIN SIGNATURE-----%s-----END SIGNATURE-----' % CRYPTO_BLOB),
 )
 
 NETWORK_STATUS_DOCUMENT_HEADER = (
-  ("network-status-version", "3"),
-  ("vote-status", "consensus"),
-  ("consensus-methods", None),
-  ("consensus-method", None),
-  ("published", None),
-  ("valid-after", "2012-09-02 22:00:00"),
-  ("fresh-until", "2012-09-02 22:00:00"),
-  ("valid-until", "2012-09-02 22:00:00"),
-  ("voting-delay", "300 300"),
-  ("client-versions", None),
-  ("server-versions", None),
-  ("known-flags", "Authority BadExit Exit Fast Guard HSDir Named Running Stable Unnamed V2Dir Valid"),
-  ("params", None),
+  ('network-status-version', '3'),
+  ('vote-status', 'consensus'),
+  ('consensus-methods', None),
+  ('consensus-method', None),
+  ('published', None),
+  ('valid-after', '2012-09-02 22:00:00'),
+  ('fresh-until', '2012-09-02 22:00:00'),
+  ('valid-until', '2012-09-02 22:00:00'),
+  ('voting-delay', '300 300'),
+  ('client-versions', None),
+  ('server-versions', None),
+  ('known-flags', 'Authority BadExit Exit Fast Guard HSDir Named Running Stable Unnamed V2Dir Valid'),
+  ('params', None),
 )
 
 NETWORK_STATUS_DOCUMENT_FOOTER = (
-  ("directory-footer", ""),
-  ("bandwidth-weights", None),
-  ("directory-signature", "%s %s\n%s" % (DOC_SIG.identity, DOC_SIG.key_digest, DOC_SIG.signature)),
+  ('directory-footer', ''),
+  ('bandwidth-weights', None),
+  ('directory-signature', '%s %s\n%s' % (DOC_SIG.identity, DOC_SIG.key_digest, DOC_SIG.signature)),
 )
 
 
@@ -179,7 +179,7 @@ def get_all_combinations(attr, include_empty = False):
 
   ::
 
-    >>> list(test.mocking.get_all_combinations(["a", "b", "c"]))
+    >>> list(test.mocking.get_all_combinations(['a', 'b', 'c']))
     [('a',), ('b',), ('c',), ('a', 'b'), ('a', 'c'), ('b', 'c'), ('a', 'b', 'c')]
 
   :param list attr: attributes to provide combinations for
@@ -224,10 +224,10 @@ def get_message(content, reformat = True):
   """
 
   if reformat:
-    if not content.endswith("\n"):
-      content += "\n"
+    if not content.endswith('\n'):
+      content += '\n'
 
-    content = content.replace("\n", "\r\n")
+    content = content.replace('\n', '\r\n')
 
   return stem.response.ControlMessage.from_str(content)
 
@@ -243,8 +243,8 @@ def get_protocolinfo_response(**attributes):
   :returns: stem.response.protocolinfo.ProtocolInfoResponse instance
   """
 
-  protocolinfo_response = get_message("250-PROTOCOLINFO 1\n250 OK")
-  stem.response.convert("PROTOCOLINFO", protocolinfo_response)
+  protocolinfo_response = get_message('250-PROTOCOLINFO 1\n250 OK')
+  stem.response.convert('PROTOCOLINFO', protocolinfo_response)
 
   for attr in attributes:
     setattr(protocolinfo_response, attr, attributes[attr])
@@ -307,22 +307,22 @@ def _get_descriptor_content(attr = None, exclude = (), header_template = (), foo
 
       if value is None:
         continue
-      elif value == "":
+      elif value == '':
         content.append(keyword)
-      elif keyword == "onion-key" or keyword == "signing-key" or keyword == "router-signature":
-        content.append("%s%s" % (keyword, value))
+      elif keyword == 'onion-key' or keyword == 'signing-key' or keyword == 'router-signature':
+        content.append('%s%s' % (keyword, value))
       else:
-        content.append("%s %s" % (keyword, value))
+        content.append('%s %s' % (keyword, value))
 
   remainder = []
 
   for k, v in attr.items():
     if v:
-      remainder.append("%s %s" % (k, v))
+      remainder.append('%s %s' % (k, v))
     else:
       remainder.append(k)
 
-  return stem.util.str_tools._to_bytes("\n".join(header_content + remainder + footer_content))
+  return stem.util.str_tools._to_bytes('\n'.join(header_content + remainder + footer_content))
 
 
 def get_relay_server_descriptor(attr = None, exclude = (), content = False, sign_content = False):
@@ -513,7 +513,7 @@ def get_directory_authority(attr = None, exclude = (), is_vote = False, content
   desc_content = _get_descriptor_content(attr, exclude, AUTHORITY_HEADER)
 
   if is_vote:
-    desc_content += b"\n" + get_key_certificate(content = True)
+    desc_content += b'\n' + get_key_certificate(content = True)
 
   if content:
     return desc_content
@@ -580,10 +580,10 @@ def get_network_status_document_v3(attr = None, exclude = (), authorities = None
 
   # add defaults only found in a vote, consensus, or microdescriptor
 
-  if attr.get("vote-status") == "vote":
+  if attr.get('vote-status') == 'vote':
     extra_defaults = {
-      "consensus-methods": "1 9",
-      "published": "2012-09-02 22:00:00",
+      'consensus-methods': '1 9',
+      'published': '2012-09-02 22:00:00',
     }
 
     # votes need an authority to be valid
@@ -592,7 +592,7 @@ def get_network_status_document_v3(attr = None, exclude = (), authorities = None
       authorities = [get_directory_authority(is_vote = True)]
   else:
     extra_defaults = {
-      "consensus-method": "9",
+      'consensus-method': '9',
     }
 
   for k, v in extra_defaults.items():
@@ -603,31 +603,31 @@ def get_network_status_document_v3(attr = None, exclude = (), authorities = None
 
   # inject the authorities and/or routers between the header and footer
   if authorities:
-    if b"directory-footer" in desc_content:
-      footer_div = desc_content.find(b"\ndirectory-footer") + 1
-    elif b"directory-signature" in desc_content:
-      footer_div = desc_content.find(b"\ndirectory-signature") + 1
+    if b'directory-footer' in desc_content:
+      footer_div = desc_content.find(b'\ndirectory-footer') + 1
+    elif b'directory-signature' in desc_content:
+      footer_div = desc_content.find(b'\ndirectory-signature') + 1
     else:
       if routers:
-        desc_content += b"\n"
+        desc_content += b'\n'
 
       footer_div = len(desc_content) + 1
 
-    authority_content = stem.util.str_tools._to_bytes("\n".join([str(a) for a in authorities]) + "\n")
+    authority_content = stem.util.str_tools._to_bytes('\n'.join([str(a) for a in authorities]) + '\n')
     desc_content = desc_content[:footer_div] + authority_content + desc_content[footer_div:]
 
   if routers:
-    if b"directory-footer" in desc_content:
-      footer_div = desc_content.find(b"\ndirectory-footer") + 1
-    elif b"directory-signature" in desc_content:
-      footer_div = desc_content.find(b"\ndirectory-signature") + 1
+    if b'directory-footer' in desc_content:
+      footer_div = desc_content.find(b'\ndirectory-footer') + 1
+    elif b'directory-signature' in desc_content:
+      footer_div = desc_content.find(b'\ndirectory-signature') + 1
     else:
       if routers:
-        desc_content += b"\n"
+        desc_content += b'\n'
 
       footer_div = len(desc_content) + 1
 
-    router_content = stem.util.str_tools._to_bytes("\n".join([str(r) for r in routers]) + "\n")
+    router_content = stem.util.str_tools._to_bytes('\n'.join([str(r) for r in routers]) + '\n')
     desc_content = desc_content[:footer_div] + router_content + desc_content[footer_div:]
 
   if content:
@@ -675,9 +675,9 @@ def sign_descriptor_content(desc_content):
 
     # generate the new signing key string
 
-    signing_key_token = b"\nsigning-key\n"  # note the trailing '\n' is important here so as not to match the string elsewhere
-    signing_key_token_start = b"-----BEGIN RSA PUBLIC KEY-----\n"
-    signing_key_token_end = b"\n-----END RSA PUBLIC KEY-----\n"
+    signing_key_token = b'\nsigning-key\n'  # note the trailing '\n' is important here so as not to match the string elsewhere
+    signing_key_token_start = b'-----BEGIN RSA PUBLIC KEY-----\n'
+    signing_key_token_end = b'\n-----END RSA PUBLIC KEY-----\n'
     new_sk = signing_key_token + signing_key_token_start + public_key_string + signing_key_token_end
 
     # update the descriptor string with the new signing key
@@ -689,24 +689,24 @@ def sign_descriptor_content(desc_content):
     # generate the new fingerprint string
 
     key_hash = stem.util.str_tools._to_bytes(hashlib.sha1(seq_as_string).hexdigest().upper())
-    grouped_fingerprint = b""
+    grouped_fingerprint = b''
 
     for x in range(0, len(key_hash), 4):
-      grouped_fingerprint += b" " + key_hash[x:x + 4]
-      fingerprint_token = b"\nfingerprint"
+      grouped_fingerprint += b' ' + key_hash[x:x + 4]
+      fingerprint_token = b'\nfingerprint'
       new_fp = fingerprint_token + grouped_fingerprint
 
     # update the descriptor string with the new fingerprint
 
     ft_start = desc_content.find(fingerprint_token)
     if ft_start < 0:
-      fingerprint_token = b"\nopt fingerprint"
+      fingerprint_token = b'\nopt fingerprint'
       ft_start = desc_content.find(fingerprint_token)
 
     # if the descriptor does not already contain a fingerprint do not add one
 
     if ft_start >= 0:
-      ft_end = desc_content.find(b"\n", ft_start + 1)
+      ft_end = desc_content.find(b'\n', ft_start + 1)
       desc_content = desc_content[:ft_start] + new_fp + desc_content[ft_end:]
 
     # create a temporary object to use to calculate the digest
@@ -729,7 +729,7 @@ def sign_descriptor_content(desc_content):
     #  2 bytes for the type info
     #  1 byte for the separator
 
-    padding = b""
+    padding = b''
 
     for x in range(125 - len(new_digest)):
       padding += b'\xFF'
@@ -749,9 +749,9 @@ def sign_descriptor_content(desc_content):
 
     # update the descriptor string with the new signature
 
-    router_signature_token = b"\nrouter-signature\n"
-    router_signature_start = b"-----BEGIN SIGNATURE-----\n"
-    router_signature_end = b"\n-----END SIGNATURE-----\n"
+    router_signature_token = b'\nrouter-signature\n'
+    router_signature_start = b'-----BEGIN SIGNATURE-----\n'
+    router_signature_end = b'\n-----END SIGNATURE-----\n'
     rst_start = desc_content.find(router_signature_token)
     desc_content = desc_content[:rst_start] + router_signature_token + router_signature_start + signature_base64 + router_signature_end
 
diff --git a/test/network.py b/test/network.py
index ffd58d4..e7ae0cb 100644
--- a/test/network.py
+++ b/test/network.py
@@ -35,9 +35,9 @@ SOCKS5_CONN_BY_NAME = (0x05, 0x01, 0x00, 0x03)
 
 
 error_msgs = {
-  0x5a: "SOCKS4A request granted",
-  0x5b: "SOCKS4A request rejected or failed",
-  0x5c: "SOCKS4A request failed because client is not running identd (or not reachable from the server)",
+  0x5a: 'SOCKS4A request granted',
+  0x5b: 'SOCKS4A request rejected or failed',
+  0x5c: 'SOCKS4A request failed because client is not running identd (or not reachable from the server)',
   0x5d: "SOCKS4A request failed because client's identd could not confirm the user ID string in the request",
 }
 
@@ -49,7 +49,7 @@ Accept-Encoding: identity
 
 
 class ProxyError(Exception):
-  "Base error for proxy issues."
+  'Base error for proxy issues.'
 
 
 class SocksError(ProxyError):
@@ -62,14 +62,14 @@ class SocksError(ProxyError):
   # Error messages copied from http://en.wikipedia.org/wiki/SOCKS,
   # retrieved 2012-12-15 17:09:21.
   _ERROR_MESSAGE = {
-    0x01: "general failure",
-    0x02: "connection not allowed by ruleset",
-    0x03: "network unreachable",
-    0x04: "host unreachable",
-    0x05: "connection refused by destination host",
-    0x06: "TTL expired",
-    0x07: "command not supported / protocol error",
-    0x08: "address type not supported",
+    0x01: 'general failure',
+    0x02: 'connection not allowed by ruleset',
+    0x03: 'network unreachable',
+    0x04: 'host unreachable',
+    0x05: 'connection refused by destination host',
+    0x06: 'TTL expired',
+    0x07: 'command not supported / protocol error',
+    0x08: 'address type not supported',
   }
 
   def __init__(self, code):
@@ -79,7 +79,7 @@ class SocksError(ProxyError):
     code = 0x01
     if self.code in self._ERROR_MESSAGE:
       code = self.code
-    return "[%s] %s" % (code, self._ERROR_MESSAGE[code])
+    return '[%s] %s' % (code, self._ERROR_MESSAGE[code])
 
 
 class Socks(_socket_socket):
@@ -144,7 +144,7 @@ class Socks(_socket_socket):
       response = self.recv(expected_size * 2)
 
       if len(response) == 0:
-        raise socket.error("socket closed unexpectedly?")
+        raise socket.error('socket closed unexpectedly?')
       elif len(response) == expected_size:
         return response
       elif len(response) > expected_size:
@@ -195,13 +195,12 @@ class Socks(_socket_socket):
     """
 
     try:
-      return struct.pack(">%ss" % len(string_), string_)
+      return struct.pack('>%ss' % len(string_), string_)
     except struct.error:
       # Python 3: encode str to bytes
-      return struct.pack(">%ss" % len(string_), string_.encode())
+      return struct.pack('>%ss' % len(string_), string_.encode())
 
   def connect(self, address):
-
     """
     Establishes a connection to address through the SOCKS5 proxy.
 
@@ -212,9 +211,12 @@ class Socks(_socket_socket):
     """
 
     _socket_socket.connect(self, (self._proxy_addr[0], self._proxy_addr[1]))
+
     # ask for non-authenticated connection
+
     self.sendall(self._ints_to_bytes(SOCKS5_NOAUTH_GREETING))
     response = self._bytes_to_ints(self._recvall(2))
+
     if response != SOCKS5_NOAUTH_RESPONSE:
       raise SocksError(0x01)
 
@@ -223,14 +225,17 @@ class Socks(_socket_socket):
       header = header + socket.inet_aton(address[0])
     else:
       # As a last gasp, try connecting by name
+
       header = self._ints_to_bytes(SOCKS5_CONN_BY_NAME)
       header = header + self._ints_to_bytes([len(address[0])])
       header = header + self._pack_string(address[0])
 
-    header = header + struct.pack(">H", address[1])
+    header = header + struct.pack('>H', address[1])
     self.sendall(header)
     response = self._bytes_to_ints(self._recvall(10))
+
     # check the status byte
+
     if response[1] != 0x00:
       raise SocksError(response[1])
 
@@ -255,7 +260,7 @@ class SocksPatch(object):
     from test.network import SocksPatch
 
     with SocksPatch(('127.0.0.1', 9050)):
-      with urllib.urlopen("https://www.torproject.org";) as f:
+      with urllib.urlopen('https://www.torproject.org') as f:
         for line in f.readline():
           print line
   """
@@ -291,16 +296,17 @@ def external_ip(host, port):
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     sock.connect((host, int(port)))
   except Exception as exc:
-    raise SocketError("Failed to connect to the socks server: " + str(exc))
+    raise SocketError('Failed to connect to the socks server: ' + str(exc))
 
   try:
-    negotiate_socks(sock, "ifconfig.me", 80)
+    negotiate_socks(sock, 'ifconfig.me', 80)
     sock.sendall(ip_request)
     response = sock.recv(1000)
 
     # everything after the blank line is the 'data' in a HTTP response
     # The response data for our request for request should be an IP address + '\n'
-    return response[response.find("\r\n\r\n"):].strip()
+
+    return response[response.find('\r\n\r\n'):].strip()
   except Exception as exc:
     return None
 
@@ -320,12 +326,12 @@ def negotiate_socks(sock, host, port):
   """
 
   # SOCKS4a request here - http://en.wikipedia.org/wiki/SOCKS#Protocol
-  request = b"\x04\x01" + struct.pack("!H", port) + b"\x00\x00\x00\x01" + b"\x00" + stem.util.str_tools._to_bytes(host) + b"\x00"
+  request = b'\x04\x01' + struct.pack('!H', port) + b'\x00\x00\x00\x01' + b'\x00' + stem.util.str_tools._to_bytes(host) + b'\x00'
   sock.sendall(request)
   response = sock.recv(8)
 
-  if len(response) != 8 or response[0:2] != b"\x00\x5a":
+  if len(response) != 8 or response[0:2] != b'\x00\x5a':
     sock.close()
-    raise ProtocolError(error_msgs.get(response[1], "SOCKS server returned unrecognized error code"))
+    raise ProtocolError(error_msgs.get(response[1], 'SOCKS server returned unrecognized error code'))
 
-  return [socket.inet_ntoa(response[4:]), struct.unpack("!H", response[2:4])[0]]
+  return [socket.inet_ntoa(response[4:]), struct.unpack('!H', response[2:4])[0]]
diff --git a/test/output.py b/test/output.py
index dc3d7d0..1435b2f 100644
--- a/test/output.py
+++ b/test/output.py
@@ -15,11 +15,11 @@ from stem.util import system, term
 
 COLOR_SUPPORT = sys.stdout.isatty() and not system.is_windows()
 
-DIVIDER = "=" * 70
+DIVIDER = '=' * 70
 HEADER_ATTR = (term.Color.CYAN, term.Attr.BOLD)
 CATEGORY_ATTR = (term.Color.GREEN, term.Attr.BOLD)
 
-NO_NL = "no newline"
+NO_NL = 'no newline'
 
 # formatting for various categories of messages
 
@@ -29,13 +29,13 @@ SUBSTATUS = (term.Color.BLUE, )
 SUCCESS = (term.Color.GREEN, term.Attr.BOLD)
 ERROR = (term.Color.RED, term.Attr.BOLD)
 
-LineType = stem.util.enum.Enum("OK", "FAIL", "ERROR", "SKIPPED", "CONTENT")
+LineType = stem.util.enum.Enum('OK', 'FAIL', 'ERROR', 'SKIPPED', 'CONTENT')
 
 LINE_ENDINGS = {
-  " ... ok": LineType.OK,
-  " ... FAIL": LineType.FAIL,
-  " ... ERROR": LineType.ERROR,
-  " ... skipped": LineType.SKIPPED,
+  ' ... ok': LineType.OK,
+  ' ... FAIL': LineType.FAIL,
+  ' ... ERROR': LineType.ERROR,
+  ' ... skipped': LineType.SKIPPED,
 }
 
 LINE_ATTR = {
@@ -47,7 +47,7 @@ LINE_ATTR = {
 }
 
 
-def println(msg = "", *attr):
+def println(msg = '', *attr):
   attr = _flatten(attr)
   no_newline = False
 
@@ -67,13 +67,13 @@ def println(msg = "", *attr):
 
 def print_divider(msg, is_header = False):
   attr = HEADER_ATTR if is_header else CATEGORY_ATTR
-  println("%s\n%s\n%s\n" % (DIVIDER, msg.center(70), DIVIDER), *attr)
+  println('%s\n%s\n%s\n' % (DIVIDER, msg.center(70), DIVIDER), *attr)
 
 
 def print_logging(logging_buffer):
   if not logging_buffer.is_empty():
     for entry in logging_buffer:
-      println(entry.replace("\n", "\n  "), term.Color.MAGENTA)
+      println(entry.replace('\n', '\n  '), term.Color.MAGENTA)
 
     print
 
@@ -113,7 +113,7 @@ def apply_filters(testing_output, *filters):
     if line is not None:
       results.append(line)
 
-  return "\n".join(results) + "\n"
+  return '\n'.join(results) + '\n'
 
 
 def colorize(line_type, line_content):
@@ -133,10 +133,10 @@ def strip_module(line_type, line_content):
   repetitive, and redundant with the headers.
   """
 
-  m = re.match(".*( \(test\..*?\)).*", line_content)
+  m = re.match('.*( \(test\..*?\)).*', line_content)
 
   if m:
-    line_content = line_content.replace(m.groups()[0], "", 1)
+    line_content = line_content.replace(m.groups()[0], '', 1)
 
   return line_content
 
@@ -153,7 +153,7 @@ def align_results(line_type, line_content):
   # strip our current ending
   for ending in LINE_ENDINGS:
     if LINE_ENDINGS[ending] == line_type:
-      line_content = line_content.replace(ending, "", 1)
+      line_content = line_content.replace(ending, '', 1)
       break
 
   # skipped tests have extra single quotes around the reason
@@ -161,19 +161,19 @@ def align_results(line_type, line_content):
     line_content = line_content.replace("'(", "(", 1).replace(")'", ")", 1)
 
   if line_type == LineType.OK:
-    new_ending = "SUCCESS"
+    new_ending = 'SUCCESS'
   elif line_type in (LineType.FAIL, LineType.ERROR):
-    new_ending = "FAILURE"
+    new_ending = 'FAILURE'
   elif line_type == LineType.SKIPPED:
-    new_ending = "SKIPPED"
+    new_ending = 'SKIPPED'
   else:
-    assert False, "Unexpected line type: %s" % line_type
+    assert False, 'Unexpected line type: %s' % line_type
     return line_content
 
   if COLOR_SUPPORT:
-    return "%-61s[%s]" % (line_content, term.format(new_ending, term.Attr.BOLD))
+    return '%-61s[%s]' % (line_content, term.format(new_ending, term.Attr.BOLD))
   else:
-    return "%-61s[%s]" % (line_content, term.format(new_ending))
+    return '%-61s[%s]' % (line_content, term.format(new_ending))
 
 
 class ErrorTracker(object):
@@ -215,7 +215,7 @@ class ErrorTracker(object):
     def _error_tracker(line_type, line_content):
       if line_type in (LineType.FAIL, LineType.ERROR):
         if self._category:
-          self._errors.append("[%s] %s" % (self._category, line_content))
+          self._errors.append('[%s] %s' % (self._category, line_content))
         else:
           self._errors.append(line_content)
 
diff --git a/test/runner.py b/test/runner.py
index e88b5c0..3ad78f2 100644
--- a/test/runner.py
+++ b/test/runner.py
@@ -59,12 +59,12 @@ import stem.version
 from test.output import println, STATUS, ERROR, SUBSTATUS, NO_NL
 from test.util import Target, STEM_BASE
 
-CONFIG = stem.util.conf.config_dict("test", {
-  "integ.test_directory": "./test/data",
-  "integ.log": "./test/data/log",
+CONFIG = stem.util.conf.config_dict('test', {
+  'integ.test_directory': './test/data',
+  'integ.log': './test/data/log',
 })
 
-SOCKS_HOST = "127.0.0.1"
+SOCKS_HOST = '127.0.0.1'
 SOCKS_PORT = 1112
 
 BASE_TORRC = """# configuration for stem integration tests
@@ -79,16 +79,16 @@ Log notice file %%s/tor_log
 INTEG_RUNNER = None
 
 # control authentication options and attributes
-CONTROL_PASSWORD = "pw"
+CONTROL_PASSWORD = 'pw'
 CONTROL_PORT = 1111
 CONTROL_SOCKET_PATH = os.path.join(tempfile.gettempdir(), str(uuid.uuid4()), 'socket')
 
 Torrc = stem.util.enum.Enum(
-  ("PORT", "ControlPort %i" % CONTROL_PORT),
-  ("COOKIE", "CookieAuthentication 1"),
-  ("PASSWORD", "HashedControlPassword 16:8C423A41EF4A542C6078985270AE28A4E04D056FB63F9F201505DB8E06"),
-  ("SOCKET", "ControlSocket %s" % CONTROL_SOCKET_PATH),
-  ("PTRACE", "DisableDebuggerAttachment 0"),
+  ('PORT', 'ControlPort %i' % CONTROL_PORT),
+  ('COOKIE', 'CookieAuthentication 1'),
+  ('PASSWORD', 'HashedControlPassword 16:8C423A41EF4A542C6078985270AE28A4E04D056FB63F9F201505DB8E06'),
+  ('SOCKET', 'ControlSocket %s' % CONTROL_SOCKET_PATH),
+  ('PTRACE', 'DisableDebuggerAttachment 0'),
 )
 
 # (test_instance, test_name) tuples that we've registered as having been ran
@@ -100,7 +100,7 @@ class RunnerStopped(Exception):
 
 
 class TorInaccessable(Exception):
-  "Raised when information is needed from tor but the instance we have is inaccessible"
+  'Raised when information is needed from tor but the instance we have is inaccessible'
 
 
 def skip(test_case, message):
@@ -127,7 +127,7 @@ def require_control(test_case):
   """
 
   if not get_runner().is_accessible():
-    skip(test_case, "(no connection)")
+    skip(test_case, '(no connection)')
     return True
 
 
@@ -142,7 +142,7 @@ def require_version(test_case, req_version):
   """
 
   if get_runner().get_tor_version() < req_version:
-    skip(test_case, "(requires %s)" % req_version)
+    skip(test_case, '(requires %s)' % req_version)
     return True
 
 
@@ -157,7 +157,7 @@ def require_online(test_case):
   """
 
   if not Target.ONLINE in get_runner().attribute_targets:
-    skip(test_case, "(requires online target)")
+    skip(test_case, '(requires online target)')
     return True
 
 
@@ -174,7 +174,7 @@ def only_run_once(test_case, test_name):
   """
 
   if (test_case, test_name) in RAN_TESTS:
-    skip(test_case, "(already ran)")
+    skip(test_case, '(already ran)')
     return True
   else:
     RAN_TESTS.append((test_case, test_name))
@@ -194,12 +194,12 @@ def exercise_controller(test_case, controller):
   torrc_path = runner.get_torrc_path()
 
   if isinstance(controller, stem.socket.ControlSocket):
-    controller.send("GETINFO config-file")
+    controller.send('GETINFO config-file')
     config_file_response = controller.recv()
   else:
-    config_file_response = controller.msg("GETINFO config-file")
+    config_file_response = controller.msg('GETINFO config-file')
 
-  test_case.assertEquals("config-file=%s\nOK" % torrc_path, str(config_file_response))
+  test_case.assertEquals('config-file=%s\nOK' % torrc_path, str(config_file_response))
 
 
 def get_runner():
@@ -229,7 +229,7 @@ class _MockChrootFile(object):
     self.strip_text = strip_text
 
   def readline(self):
-    return self.wrapped_file.readline().replace(self.strip_text, "")
+    return self.wrapped_file.readline().replace(self.strip_text, '')
 
 
 class Runner(object):
@@ -240,10 +240,11 @@ class Runner(object):
     self._runner_lock = threading.RLock()
 
     # runtime attributes, set by the start method
-    self._test_dir = ""
+
+    self._test_dir = ''
     self._tor_cmd = None
-    self._tor_cwd = ""
-    self._torrc_contents = ""
+    self._tor_cwd = ''
+    self._torrc_contents = ''
     self._custom_opts = None
     self._tor_process = None
     self._chroot_path = None
@@ -275,17 +276,17 @@ class Runner(object):
       if self._tor_process:
         self.stop()
 
-      println("Setting up a test instance...", STATUS)
+      println('Setting up a test instance...', STATUS)
 
       # if 'test_directory' is unset then we make a new data directory in /tmp
       # and clean it up when we're done
 
-      config_test_dir = CONFIG["integ.test_directory"]
+      config_test_dir = CONFIG['integ.test_directory']
 
       if config_test_dir:
         self._test_dir = stem.util.system.expand_path(config_test_dir, STEM_BASE)
       else:
-        self._test_dir = tempfile.mktemp("-stem-integ")
+        self._test_dir = tempfile.mktemp('-stem-integ')
 
       original_cwd, data_dir_path = os.getcwd(), self._test_dir
 
@@ -296,14 +297,14 @@ class Runner(object):
           os.makedirs(tor_cwd)
 
         os.chdir(tor_cwd)
-        data_dir_path = "./%s" % os.path.basename(self._test_dir)
+        data_dir_path = './%s' % os.path.basename(self._test_dir)
 
       self._tor_cmd = tor_cmd
       self._custom_opts = extra_torrc_opts
       self._torrc_contents = BASE_TORRC % (data_dir_path, data_dir_path)
 
       if extra_torrc_opts:
-        self._torrc_contents += "\n".join(extra_torrc_opts) + "\n"
+        self._torrc_contents += '\n'.join(extra_torrc_opts) + '\n'
 
       try:
         self._tor_cwd = os.getcwd()
@@ -337,7 +338,7 @@ class Runner(object):
     """
 
     with self._runner_lock:
-      println("Shutting down tor... ", STATUS, NO_NL)
+      println('Shutting down tor... ', STATUS, NO_NL)
 
       if self._tor_process:
         # if the tor process has stopped on its own then the following raises
@@ -351,7 +352,7 @@ class Runner(object):
         self._tor_process.communicate()  # blocks until the process is done
 
       # if we've made a temporary data directory then clean it up
-      if self._test_dir and CONFIG["integ.test_directory"] == "":
+      if self._test_dir and CONFIG['integ.test_directory'] == '':
         shutil.rmtree(self._test_dir, ignore_errors = True)
 
       # reverts any mocking of stem.socket.recv_message
@@ -365,14 +366,14 @@ class Runner(object):
       if os.path.exists(socket_dir):
         shutil.rmtree(socket_dir, ignore_errors = True)
 
-      self._test_dir = ""
+      self._test_dir = ''
       self._tor_cmd = None
-      self._tor_cwd = ""
-      self._torrc_contents = ""
+      self._tor_cwd = ''
+      self._torrc_contents = ''
       self._custom_opts = None
       self._tor_process = None
 
-      println("done", STATUS)
+      println('done', STATUS)
 
   def is_running(self):
     """
@@ -388,7 +389,7 @@ class Runner(object):
       if self._tor_process and self._tor_process.poll() is not None:
         # clean up the temporary resources and note the unexpected shutdown
         self.stop()
-        println("tor shut down unexpectedly", ERROR)
+        println('tor shut down unexpectedly', ERROR)
 
       return bool(self._tor_process)
 
@@ -437,9 +438,9 @@ class Runner(object):
     """
 
     if resource:
-      return os.path.join(self._get("_test_dir"), resource)
+      return os.path.join(self._get('_test_dir'), resource)
     else:
-      return self._get("_test_dir")
+      return self._get('_test_dir')
 
   def get_torrc_path(self, ignore_chroot = False):
     """
@@ -452,8 +453,8 @@ class Runner(object):
     :raises: RunnerStopped if we aren't running
     """
 
-    test_dir = self._get("_test_dir")
-    torrc_path = os.path.join(test_dir, "torrc")
+    test_dir = self._get('_test_dir')
+    torrc_path = os.path.join(test_dir, 'torrc')
 
     if not ignore_chroot and self._chroot_path and torrc_path.startswith(self._chroot_path):
       torrc_path = torrc_path[len(self._chroot_path):]
@@ -469,7 +470,7 @@ class Runner(object):
     :raises: :class:`test.runner.RunnerStopped` if we aren't running
     """
 
-    return self._get("_torrc_contents")
+    return self._get('_torrc_contents')
 
   def get_auth_cookie_path(self):
     """
@@ -482,15 +483,15 @@ class Runner(object):
     :raises: :class:`test.runner.RunnerStopped` if we aren't running
     """
 
-    test_dir = self._get("_test_dir")
-    return os.path.join(test_dir, "control_auth_cookie")
+    test_dir = self._get('_test_dir')
+    return os.path.join(test_dir, 'control_auth_cookie')
 
   def get_tor_cwd(self):
     """
     Provides the current working directory of our tor process.
     """
 
-    return self._get("_tor_cwd")
+    return self._get('_tor_cwd')
 
   def get_chroot(self):
     """
@@ -511,7 +512,7 @@ class Runner(object):
     :raises: :class:`test.runner.RunnerStopped` if we aren't running
     """
 
-    tor_process = self._get("_tor_process")
+    tor_process = self._get('_tor_process')
     return tor_process.pid
 
   def get_tor_socket(self, authenticate = True):
@@ -530,7 +531,7 @@ class Runner(object):
     elif Torrc.SOCKET in self._custom_opts:
       control_socket = stem.socket.ControlSocketFile(CONTROL_SOCKET_PATH)
     else:
-      raise TorInaccessable("Unable to connect to tor")
+      raise TorInaccessable('Unable to connect to tor')
 
     if authenticate:
       stem.connection.authenticate(control_socket, CONTROL_PASSWORD, self.get_chroot())
@@ -566,16 +567,17 @@ class Runner(object):
     try:
       # TODO: replace with higher level functions when we've completed a basic
       # controller class
+
       control_socket = self.get_tor_socket()
 
-      control_socket.send("GETINFO version")
+      control_socket.send('GETINFO version')
       version_response = control_socket.recv()
       control_socket.close()
 
       tor_version = list(version_response)[0]
       tor_version = tor_version[8:]
 
-      if " " in tor_version:
+      if ' ' in tor_version:
         tor_version = tor_version.split(' ', 1)[0]
 
       return stem.version.Version(tor_version)
@@ -587,7 +589,7 @@ class Runner(object):
     Provides the command used to run our tor instance.
     """
 
-    return self._get("_tor_cmd")
+    return self._get('_tor_cmd')
 
   def _get(self, attr):
     """
@@ -616,15 +618,15 @@ class Runner(object):
 
     # makes a temporary data directory if needed
     try:
-      println("  making test directory (%s)... " % self._test_dir, STATUS, NO_NL)
+      println('  making test directory (%s)... ' % self._test_dir, STATUS, NO_NL)
 
       if os.path.exists(self._test_dir):
-        println("skipped", STATUS)
+        println('skipped', STATUS)
       else:
         os.makedirs(self._test_dir)
-        println("done", STATUS)
+        println('done', STATUS)
     except OSError as exc:
-      println("failed (%s)" % exc, ERROR)
+      println('failed (%s)' % exc, ERROR)
       raise exc
 
     # Tor checks during startup that the directory a control socket resides in
@@ -634,28 +636,29 @@ class Runner(object):
     if Torrc.SOCKET in self._custom_opts:
       try:
         socket_dir = os.path.dirname(CONTROL_SOCKET_PATH)
-        println("  making control socket directory (%s)... " % socket_dir, STATUS, NO_NL)
+        println('  making control socket directory (%s)... ' % socket_dir, STATUS, NO_NL)
 
         if os.path.exists(socket_dir) and stat.S_IMODE(os.stat(socket_dir).st_mode) == 0700:
-          println("skipped", STATUS)
+          println('skipped', STATUS)
         else:
           if not os.path.exists(socket_dir):
             os.makedirs(socket_dir)
 
           os.chmod(socket_dir, 0700)
-          println("done", STATUS)
+          println('done', STATUS)
       except OSError as exc:
-        println("failed (%s)" % exc, ERROR)
+        println('failed (%s)' % exc, ERROR)
         raise exc
 
     # configures logging
-    logging_path = CONFIG["integ.log"]
+    logging_path = CONFIG['integ.log']
 
     if logging_path:
       logging_path = stem.util.system.expand_path(logging_path, STEM_BASE)
-      println("  configuring logger (%s)... " % logging_path, STATUS, NO_NL)
+      println('  configuring logger (%s)... ' % logging_path, STATUS, NO_NL)
 
       # delete the old log
+
       if os.path.exists(logging_path):
         os.remove(logging_path)
 
@@ -666,27 +669,27 @@ class Runner(object):
         datefmt = '%D %H:%M:%S',
       )
 
-      println("done", STATUS)
+      println('done', STATUS)
     else:
-      println("  configuring logger... skipped", STATUS)
+      println('  configuring logger... skipped', STATUS)
 
     # writes our testing torrc
-    torrc_dst = os.path.join(self._test_dir, "torrc")
+    torrc_dst = os.path.join(self._test_dir, 'torrc')
     try:
-      println("  writing torrc (%s)... " % torrc_dst, STATUS, NO_NL)
+      println('  writing torrc (%s)... ' % torrc_dst, STATUS, NO_NL)
 
-      torrc_file = open(torrc_dst, "w")
+      torrc_file = open(torrc_dst, 'w')
       torrc_file.write(self._torrc_contents)
       torrc_file.close()
 
-      println("done", STATUS)
+      println('done', STATUS)
 
       for line in self._torrc_contents.strip().splitlines():
-        println("    %s" % line.strip(), SUBSTATUS)
+        println('    %s' % line.strip(), SUBSTATUS)
 
       println()
     except Exception as exc:
-      println("failed (%s)\n" % exc, ERROR)
+      println('failed (%s)\n' % exc, ERROR)
       raise OSError(exc)
 
   def _start_tor(self, tor_cmd):
@@ -699,7 +702,7 @@ class Runner(object):
     :raises: OSError if we either fail to create the tor process or reached a timeout without success
     """
 
-    println("Starting tor...\n", STATUS)
+    println('Starting tor...\n', STATUS)
     start_time = time.time()
 
     try:
@@ -708,13 +711,13 @@ class Runner(object):
       complete_percent = 100 if Target.ONLINE in self.attribute_targets else 5
 
       # prints output from tor's stdout while it starts up
-      print_init_line = lambda line: println("  %s" % line, SUBSTATUS)
+      print_init_line = lambda line: println('  %s' % line, SUBSTATUS)
 
-      torrc_dst = os.path.join(self._test_dir, "torrc")
+      torrc_dst = os.path.join(self._test_dir, 'torrc')
       self._tor_process = stem.process.launch_tor(tor_cmd, None, torrc_dst, complete_percent, print_init_line, take_ownership = True)
 
       runtime = time.time() - start_time
-      println("  done (%i seconds)\n" % runtime, STATUS)
+      println('  done (%i seconds)\n' % runtime, STATUS)
     except OSError as exc:
-      println("  failed to start tor: %s\n" % exc, ERROR)
+      println('  failed to start tor: %s\n' % exc, ERROR)
       raise exc
diff --git a/test/unit/__init__.py b/test/unit/__init__.py
index 1932601..9a83be9 100644
--- a/test/unit/__init__.py
+++ b/test/unit/__init__.py
@@ -3,11 +3,11 @@ Unit tests for the stem library.
 """
 
 __all__ = [
-  "connection",
-  "control",
-  "descriptor",
-  "exit_policy",
-  "socket",
-  "util",
-  "version",
+  'connection',
+  'control',
+  'descriptor',
+  'exit_policy',
+  'socket',
+  'util',
+  'version',
 ]
diff --git a/test/unit/connection/__init__.py b/test/unit/connection/__init__.py
index 103b792..c9d7296 100644
--- a/test/unit/connection/__init__.py
+++ b/test/unit/connection/__init__.py
@@ -2,4 +2,4 @@
 Unit tests for stem.connection.
 """
 
-__all__ = ["authentication"]
+__all__ = ['authentication', 'connect']
diff --git a/test/unit/connection/authentication.py b/test/unit/connection/authentication.py
index 4b50bcf..b12efeb 100644
--- a/test/unit/connection/authentication.py
+++ b/test/unit/connection/authentication.py
@@ -107,7 +107,7 @@ class TestAuthenticate(unittest.TestCase):
       # protocolinfo input for the authenticate() call we'll be making
       protocolinfo_arg = mocking.get_protocolinfo_response(
         auth_methods = protocolinfo_auth_methods,
-        cookie_path = "/tmp/blah",
+        cookie_path = '/tmp/blah',
       )
 
       for auth_none_exc in all_auth_none_exc:
@@ -150,9 +150,9 @@ class TestAuthenticate(unittest.TestCase):
                 auth_mock.side_effect = raised_exc
 
             if expect_success:
-              stem.connection.authenticate(None, "blah", None, protocolinfo_arg)
+              stem.connection.authenticate(None, 'blah', None, protocolinfo_arg)
             else:
-              self.assertRaises(stem.connection.AuthenticationFailure, stem.connection.authenticate, None, "blah", None, protocolinfo_arg)
+              self.assertRaises(stem.connection.AuthenticationFailure, stem.connection.authenticate, None, 'blah', None, protocolinfo_arg)
 
     # revert logging back to normal
     stem_logger.setLevel(log.logging_level(log.TRACE))
diff --git a/test/unit/connection/connect.py b/test/unit/connection/connect.py
index 9265a5a..503ad6f 100644
--- a/test/unit/connection/connect.py
+++ b/test/unit/connection/connect.py
@@ -95,7 +95,7 @@ class TestConnect(unittest.TestCase):
       elif password == 'my_password':
         return None  # success
       else:
-        raise ValueError("Unexpected authenticate_mock input: %s" % password)
+        raise ValueError('Unexpected authenticate_mock input: %s' % password)
 
     authenticate_mock.side_effect = authenticate_mock_func
     getpass_mock.return_value = 'my_password'
diff --git a/test/unit/control/__init__.py b/test/unit/control/__init__.py
index 6db492b..6d9b38e 100644
--- a/test/unit/control/__init__.py
+++ b/test/unit/control/__init__.py
@@ -2,4 +2,4 @@
 Unit tests for stem.control.
 """
 
-__all__ = ["controller"]
+__all__ = ['controller']
diff --git a/test/unit/control/controller.py b/test/unit/control/controller.py
index 171a781..7422430 100644
--- a/test/unit/control/controller.py
+++ b/test/unit/control/controller.py
@@ -39,7 +39,7 @@ class TestControl(unittest.TestCase):
 
     try:
       # Use one version for first check.
-      version_2_1 = "0.2.1.32"
+      version_2_1 = '0.2.1.32'
       version_2_1_object = stem.version.Version(version_2_1)
       get_info_mock.return_value = version_2_1
 
@@ -47,7 +47,7 @@ class TestControl(unittest.TestCase):
       self.assertEqual(version_2_1_object, self.controller.get_version())
 
       # Use a different version for second check.
-      version_2_2 = "0.2.2.39"
+      version_2_2 = '0.2.2.39'
       version_2_2_object = stem.version.Version(version_2_2)
       get_info_mock.return_value = version_2_2
 
@@ -64,15 +64,15 @@ class TestControl(unittest.TestCase):
 
       # Get a default value when the call fails.
       self.assertEqual(
-        "default returned",
-        self.controller.get_version(default = "default returned")
+        'default returned',
+        self.controller.get_version(default = 'default returned')
       )
 
       # No default value, accept the error.
       self.assertRaises(InvalidArguments, self.controller.get_version)
 
       # Give a bad version.  The stem.version.Version ValueError should bubble up.
-      version_A_42 = "0.A.42.spam"
+      version_A_42 = '0.A.42.spam'
       get_info_mock.return_value = version_A_42
       get_info_mock.side_effect = None
       self.assertRaises(ValueError, self.controller.get_version)
@@ -88,13 +88,13 @@ class TestControl(unittest.TestCase):
     """
 
     get_conf_mock.side_effect = lambda param, **kwargs: {
-      "ExitPolicyRejectPrivate": "1",
-      "ExitPolicy": ["accept *:80,   accept *:443", "accept 43.5.5.5,reject *:22"],
+      'ExitPolicyRejectPrivate': '1',
+      'ExitPolicy': ['accept *:80,   accept *:443', 'accept 43.5.5.5,reject *:22'],
     }[param]
 
     get_info_mock.side_effect = lambda param, default = None: {
-      "address": "123.45.67.89",
-      "exit-policy/default": "reject *:25,reject *:119,reject *:135-139,reject *:445,reject *:563,reject *:1214,reject *:4661-4666,reject *:6346-6429,reject *:6699,reject *:6881-6999,accept *:*",
+      'address': '123.45.67.89',
+      'exit-policy/default': 'reject *:25,reject *:119,reject *:135-139,reject *:445,reject *:563,reject *:1214,reject *:4661-4666,reject *:6346-6429,reject *:6699,reject *:6881-6999,accept *:*',
     }[param]
 
     expected = ExitPolicy(
@@ -137,8 +137,8 @@ class TestControl(unittest.TestCase):
     get_info_mock.side_effect = InvalidArguments
 
     get_conf_mock.side_effect = lambda param, **kwargs: {
-      "ControlPort": "9050",
-      "ControlListenAddress": ["127.0.0.1"],
+      'ControlPort': '9050',
+      'ControlListenAddress': ['127.0.0.1'],
     }[param]
 
     self.assertEqual([('127.0.0.1', 9050)], self.controller.get_listeners(Listener.CONTROL))
@@ -147,8 +147,8 @@ class TestControl(unittest.TestCase):
     # non-local addresss
 
     get_conf_mock.side_effect = lambda param, **kwargs: {
-      "ControlPort": "9050",
-      "ControlListenAddress": ["27.4.4.1"],
+      'ControlPort': '9050',
+      'ControlListenAddress': ['27.4.4.1'],
     }[param]
 
     self.assertEqual([('27.4.4.1', 9050)], self.controller.get_listeners(Listener.CONTROL))
@@ -187,8 +187,8 @@ class TestControl(unittest.TestCase):
     get_info_mock.side_effect = InvalidArguments
 
     get_conf_mock.side_effect = lambda param, **kwargs: {
-      "SocksPort": "9050",
-      "SocksListenAddress": ["127.0.0.1"],
+      'SocksPort': '9050',
+      'SocksListenAddress': ['127.0.0.1'],
     }[param]
 
     self.assertEqual([('127.0.0.1', 9050)], self.controller.get_socks_listeners())
@@ -196,8 +196,8 @@ class TestControl(unittest.TestCase):
     # Again, an old tor, but SocksListenAddress overrides the port number.
 
     get_conf_mock.side_effect = lambda param, **kwargs: {
-      "SocksPort": "9050",
-      "SocksListenAddress": ["127.0.0.1:1112"],
+      'SocksPort': '9050',
+      'SocksListenAddress': ['127.0.0.1:1112'],
     }[param]
 
     self.assertEqual([('127.0.0.1', 1112)], self.controller.get_socks_listeners())
@@ -205,8 +205,8 @@ class TestControl(unittest.TestCase):
     # Again, an old tor, but multiple listeners
 
     get_conf_mock.side_effect = lambda param, **kwargs: {
-      "SocksPort": "9050",
-      "SocksListenAddress": ["127.0.0.1:1112", "127.0.0.1:1114"],
+      'SocksPort': '9050',
+      'SocksListenAddress': ['127.0.0.1:1112', '127.0.0.1:1114'],
     }[param]
 
     self.assertEqual([('127.0.0.1', 1112), ('127.0.0.1', 1114)], self.controller.get_socks_listeners())
@@ -214,8 +214,8 @@ class TestControl(unittest.TestCase):
     # Again, an old tor, but no SOCKS listeners
 
     get_conf_mock.side_effect = lambda param, **kwargs: {
-      "SocksPort": "0",
-      "SocksListenAddress": [],
+      'SocksPort': '0',
+      'SocksListenAddress': [],
     }[param]
 
     self.assertEqual([], self.controller.get_socks_listeners())
@@ -223,22 +223,22 @@ class TestControl(unittest.TestCase):
     # Where tor provides invalid ports or addresses
 
     get_conf_mock.side_effect = lambda param, **kwargs: {
-      "SocksPort": "blarg",
-      "SocksListenAddress": ["127.0.0.1"],
+      'SocksPort': 'blarg',
+      'SocksListenAddress': ['127.0.0.1'],
     }[param]
 
     self.assertRaises(stem.ProtocolError, self.controller.get_socks_listeners)
 
     get_conf_mock.side_effect = lambda param, **kwargs: {
-      "SocksPort": "0",
-      "SocksListenAddress": ["127.0.0.1:abc"],
+      'SocksPort': '0',
+      'SocksListenAddress': ['127.0.0.1:abc'],
     }[param]
 
     self.assertRaises(stem.ProtocolError, self.controller.get_socks_listeners)
 
     get_conf_mock.side_effect = lambda param, **kwargs: {
-      "SocksPort": "40",
-      "SocksListenAddress": ["500.0.0.1"],
+      'SocksPort': '40',
+      'SocksListenAddress': ['500.0.0.1'],
     }[param]
 
     self.assertRaises(stem.ProtocolError, self.controller.get_socks_listeners)
@@ -302,8 +302,8 @@ class TestControl(unittest.TestCase):
     # get a default value when the call fails
 
     self.assertEqual(
-      "default returned",
-      self.controller.get_protocolinfo(default = "default returned")
+      'default returned',
+      self.controller.get_protocolinfo(default = 'default returned')
     )
 
     # no default value, accept the error
@@ -387,9 +387,9 @@ class TestControl(unittest.TestCase):
 
     # build a single router status entry
 
-    nickname = "Beaver"
-    fingerprint = "/96bKo4soysolMgKn5Hex2nyFSY"
-    desc = "r %s %s u5lTXJKGsLKufRLnSyVqT7TdGYw 2012-12-30 22:02:49 77.223.43.54 9001 0\ns Fast Named Running Stable Valid\nw Bandwidth=75" % (nickname, fingerprint)
+    nickname = 'Beaver'
+    fingerprint = '/96bKo4soysolMgKn5Hex2nyFSY'
+    desc = 'r %s %s u5lTXJKGsLKufRLnSyVqT7TdGYw 2012-12-30 22:02:49 77.223.43.54 9001 0\ns Fast Named Running Stable Valid\nw Bandwidth=75' % (nickname, fingerprint)
     router = stem.descriptor.router_status_entry.RouterStatusEntryV3(desc)
 
     # always return the same router status entry
@@ -417,8 +417,8 @@ class TestControl(unittest.TestCase):
     # get a default value when the call fails
 
     self.assertEqual(
-      "default returned",
-      self.controller.get_network_status(nickname, default = "default returned")
+      'default returned',
+      self.controller.get_network_status(nickname, default = 'default returned')
     )
 
     # no default value, accept the error
@@ -456,12 +456,12 @@ class TestControl(unittest.TestCase):
 
     # get a list of fake, but good looking, streams
     valid_streams = (
-      ("1", "NEW", "4", "10.10.10.1:80"),
-      ("2", "SUCCEEDED", "4", "10.10.10.1:80"),
-      ("3", "SUCCEEDED", "4", "10.10.10.1:80")
+      ('1', 'NEW', '4', '10.10.10.1:80'),
+      ('2', 'SUCCEEDED', '4', '10.10.10.1:80'),
+      ('3', 'SUCCEEDED', '4', '10.10.10.1:80')
     )
 
-    response = "".join(["%s\r\n" % " ".join(entry) for entry in valid_streams])
+    response = ''.join(['%s\r\n' % ' '.join(entry) for entry in valid_streams])
 
     with patch('stem.control.Controller.get_info', Mock(return_value = response)):
       streams = self.controller.get_streams()
@@ -481,7 +481,7 @@ class TestControl(unittest.TestCase):
     # Response when the stream is in a state where it can't be attached (for
     # instance, it's already open).
 
-    response = stem.response.ControlMessage.from_str("555 Connection is not managed by controller.\r\n")
+    response = stem.response.ControlMessage.from_str('555 Connection is not managed by controller.\r\n')
 
     with patch('stem.control.Controller.msg', Mock(return_value = response)):
       self.assertRaises(UnsatisfiableRequest, self.controller.attach_stream, 'stream_id', 'circ_id')
diff --git a/test/unit/descriptor/__init__.py b/test/unit/descriptor/__init__.py
index c67b603..86ec0fd 100644
--- a/test/unit/descriptor/__init__.py
+++ b/test/unit/descriptor/__init__.py
@@ -3,11 +3,11 @@ Unit tests for stem.descriptor.
 """
 
 __all__ = [
-  "export",
-  "extrainfo_descriptor",
-  "microdescriptor",
-  "networkstatus",
-  "reader",
-  "router_status_entry",
-  "server_descriptor",
+  'export',
+  'extrainfo_descriptor',
+  'microdescriptor',
+  'networkstatus',
+  'reader',
+  'router_status_entry',
+  'server_descriptor',
 ]
diff --git a/test/unit/descriptor/export.py b/test/unit/descriptor/export.py
index d2eeaa0..68b4f29 100644
--- a/test/unit/descriptor/export.py
+++ b/test/unit/descriptor/export.py
@@ -29,17 +29,17 @@ class TestExport(unittest.TestCase):
 
     # we won't have a header prior to python 2.7
     if not stem.prereq.is_python_27():
-      test.runner.skip(self, "(header added in python 2.7)")
+      test.runner.skip(self, '(header added in python 2.7)')
       return
 
     desc = get_relay_server_descriptor()
 
     desc_csv = export_csv(desc, included_fields = ('nickname', 'address', 'published'), header = False)
-    expected = "caerSidi,71.35.133.197,2012-03-01 17:15:27\n"
+    expected = 'caerSidi,71.35.133.197,2012-03-01 17:15:27\n'
     self.assertEquals(expected, desc_csv)
 
     desc_csv = export_csv(desc, included_fields = ('nickname', 'address', 'published'), header = True)
-    expected = "nickname,address,published\n" + expected
+    expected = 'nickname,address,published\n' + expected
     self.assertEquals(expected, desc_csv)
 
   @patch('stem.descriptor.server_descriptor.RelayDescriptor._verify_digest', Mock())
@@ -53,10 +53,10 @@ class TestExport(unittest.TestCase):
     descriptors = []
 
     for nickname in nicknames:
-      router_line = "%s 71.35.133.197 9001 0 0" % nickname
+      router_line = '%s 71.35.133.197 9001 0 0' % nickname
       descriptors.append(get_relay_server_descriptor({'router': router_line}))
 
-    expected = "\n".join(nicknames) + "\n"
+    expected = '\n'.join(nicknames) + '\n'
     self.assertEqual(expected, export_csv(descriptors, included_fields = ('nickname',), header = False))
 
   @patch('stem.descriptor.server_descriptor.RelayDescriptor._verify_digest', Mock())
@@ -82,7 +82,7 @@ class TestExport(unittest.TestCase):
 
     # we won't have a header prior to python 2.7
     if not stem.prereq.is_python_27():
-      test.runner.skip(self, "(header added in python 2.7)")
+      test.runner.skip(self, '(header added in python 2.7)')
       return
 
     desc = get_relay_server_descriptor()
@@ -97,7 +97,7 @@ class TestExport(unittest.TestCase):
     Exercises when we don't provide any descriptors.
     """
 
-    self.assertEquals("", export_csv([]))
+    self.assertEquals('', export_csv([]))
 
   @patch('stem.descriptor.server_descriptor.RelayDescriptor._verify_digest', Mock())
   def test_invalid_attributes(self):
diff --git a/test/unit/descriptor/extrainfo_descriptor.py b/test/unit/descriptor/extrainfo_descriptor.py
index b2c46b6..0471bb8 100644
--- a/test/unit/descriptor/extrainfo_descriptor.py
+++ b/test/unit/descriptor/extrainfo_descriptor.py
@@ -18,8 +18,8 @@ class TestExtraInfoDescriptor(unittest.TestCase):
 
     desc = get_relay_extrainfo_descriptor()
 
-    self.assertEquals("ninja", desc.nickname)
-    self.assertEquals("B2289C3EAB83ECD6EB916A2F481A02E6B76A0A48", desc.fingerprint)
+    self.assertEquals('ninja', desc.nickname)
+    self.assertEquals('B2289C3EAB83ECD6EB916A2F481A02E6B76A0A48', desc.fingerprint)
     self.assertTrue(CRYPTO_BLOB in desc.signature)
 
   def test_unrecognized_line(self):
@@ -27,15 +27,15 @@ class TestExtraInfoDescriptor(unittest.TestCase):
     Includes unrecognized content in the descriptor.
     """
 
-    desc = get_relay_extrainfo_descriptor({"pepperjack": "is oh so tasty!"})
-    self.assertEquals(["pepperjack is oh so tasty!"], desc.get_unrecognized_lines())
+    desc = get_relay_extrainfo_descriptor({'pepperjack': 'is oh so tasty!'})
+    self.assertEquals(['pepperjack is oh so tasty!'], desc.get_unrecognized_lines())
 
   def test_proceeding_line(self):
     """
     Includes a line prior to the 'extra-info' entry.
     """
 
-    desc_text = b"exit-streams-opened port=80\n" + get_relay_extrainfo_descriptor(content = True)
+    desc_text = b'exit-streams-opened port=80\n' + get_relay_extrainfo_descriptor(content = True)
     self._expect_invalid_attr(desc_text)
 
   def test_trailing_line(self):
@@ -43,7 +43,7 @@ class TestExtraInfoDescriptor(unittest.TestCase):
     Includes a line after the 'router-signature' entry.
     """
 
-    desc_text = get_relay_extrainfo_descriptor(content = True) + b"\nexit-streams-opened port=80"
+    desc_text = get_relay_extrainfo_descriptor(content = True) + b'\nexit-streams-opened port=80'
     self._expect_invalid_attr(desc_text)
 
   def test_extrainfo_line_missing_fields(self):
@@ -54,15 +54,15 @@ class TestExtraInfoDescriptor(unittest.TestCase):
     """
 
     test_entries = (
-      "ninja",
-      "ninja ",
-      "B2289C3EAB83ECD6EB916A2F481A02E6B76A0A48",
-      " B2289C3EAB83ECD6EB916A2F481A02E6B76A0A48",
+      'ninja',
+      'ninja ',
+      'B2289C3EAB83ECD6EB916A2F481A02E6B76A0A48',
+      ' B2289C3EAB83ECD6EB916A2F481A02E6B76A0A48',
     )
 
     for entry in test_entries:
-      desc_text = get_relay_extrainfo_descriptor({"extra-info": entry}, content = True)
-      desc = self._expect_invalid_attr(desc_text, "nickname")
+      desc_text = get_relay_extrainfo_descriptor({'extra-info': entry}, content = True)
+      desc = self._expect_invalid_attr(desc_text, 'nickname')
       self.assertEquals(None, desc.nickname)
       self.assertEquals(None, desc.fingerprint)
 
@@ -72,27 +72,27 @@ class TestExtraInfoDescriptor(unittest.TestCase):
     invalid data.
     """
 
-    geoip_db_digest = "916A3CA8B7DF61473D5AE5B21711F35F301CE9E8"
-    desc = get_relay_extrainfo_descriptor({"geoip-db-digest": geoip_db_digest})
+    geoip_db_digest = '916A3CA8B7DF61473D5AE5B21711F35F301CE9E8'
+    desc = get_relay_extrainfo_descriptor({'geoip-db-digest': geoip_db_digest})
     self.assertEquals(geoip_db_digest, desc.geoip_db_digest)
 
-    desc = get_relay_extrainfo_descriptor({"geoip6-db-digest": geoip_db_digest})
+    desc = get_relay_extrainfo_descriptor({'geoip6-db-digest': geoip_db_digest})
     self.assertEquals(geoip_db_digest, desc.geoip6_db_digest)
 
     test_entries = (
-      "",
-      "916A3CA8B7DF61473D5AE5B21711F35F301CE9E",
-      "916A3CA8B7DF61473D5AE5B21711F35F301CE9E88",
-      "916A3CA8B7DF61473D5AE5B21711F35F301CE9EG",
-      "916A3CA8B7DF61473D5AE5B21711F35F301CE9E-",
+      '',
+      '916A3CA8B7DF61473D5AE5B21711F35F301CE9E',
+      '916A3CA8B7DF61473D5AE5B21711F35F301CE9E88',
+      '916A3CA8B7DF61473D5AE5B21711F35F301CE9EG',
+      '916A3CA8B7DF61473D5AE5B21711F35F301CE9E-',
     )
 
     for entry in test_entries:
-      desc_text = get_relay_extrainfo_descriptor({"geoip-db-digest": entry}, content = True)
-      self._expect_invalid_attr(desc_text, "geoip_db_digest", entry)
+      desc_text = get_relay_extrainfo_descriptor({'geoip-db-digest': entry}, content = True)
+      self._expect_invalid_attr(desc_text, 'geoip_db_digest', entry)
 
-      desc_text = get_relay_extrainfo_descriptor({"geoip6-db-digest": entry}, content = True)
-      self._expect_invalid_attr(desc_text, "geoip6_db_digest", entry)
+      desc_text = get_relay_extrainfo_descriptor({'geoip6-db-digest': entry}, content = True)
+      self._expect_invalid_attr(desc_text, 'geoip6_db_digest', entry)
 
   def test_cell_circuits_per_decile(self):
     """
@@ -100,24 +100,24 @@ class TestExtraInfoDescriptor(unittest.TestCase):
     """
 
     test_entries = (
-      ("0", 0),
-      ("11", 11),
+      ('0', 0),
+      ('11', 11),
     )
 
-    for entry in ("0", "11", "25"):
-      desc = get_relay_extrainfo_descriptor({"cell-circuits-per-decile": entry})
+    for entry in ('0', '11', '25'):
+      desc = get_relay_extrainfo_descriptor({'cell-circuits-per-decile': entry})
       self.assertEquals(int(entry), desc.cell_circuits_per_decile)
 
     test_entries = (
-      "",
-      " ",
-      "-5",
-      "blarg",
+      '',
+      ' ',
+      '-5',
+      'blarg',
     )
 
     for entry in test_entries:
-      desc_text = get_relay_extrainfo_descriptor({"cell-circuits-per-decile": entry}, content = True)
-      self._expect_invalid_attr(desc_text, "cell_circuits_per_decile")
+      desc_text = get_relay_extrainfo_descriptor({'cell-circuits-per-decile': entry}, content = True)
+      self._expect_invalid_attr(desc_text, 'cell_circuits_per_decile')
 
   def test_dir_response_lines(self):
     """
@@ -125,22 +125,22 @@ class TestExtraInfoDescriptor(unittest.TestCase):
     data.
     """
 
-    for keyword in ("dirreq-v2-resp", "dirreq-v3-resp"):
+    for keyword in ('dirreq-v2-resp', 'dirreq-v3-resp'):
       attr = keyword.replace('-', '_').replace('dirreq', 'dir').replace('resp', 'responses')
-      unknown_attr = attr + "_unknown"
+      unknown_attr = attr + '_unknown'
 
-      test_value = "ok=0,unavailable=0,not-found=984,not-modified=0,something-new=7"
+      test_value = 'ok=0,unavailable=0,not-found=984,not-modified=0,something-new=7'
       desc = get_relay_extrainfo_descriptor({keyword: test_value})
       self.assertEquals(0, getattr(desc, attr)[DirResponse.OK])
       self.assertEquals(0, getattr(desc, attr)[DirResponse.UNAVAILABLE])
       self.assertEquals(984, getattr(desc, attr)[DirResponse.NOT_FOUND])
       self.assertEquals(0, getattr(desc, attr)[DirResponse.NOT_MODIFIED])
-      self.assertEquals(7, getattr(desc, unknown_attr)["something-new"])
+      self.assertEquals(7, getattr(desc, unknown_attr)['something-new'])
 
       test_entries = (
-        "ok=-4",
-        "ok:4",
-        "ok=4.not-found=3",
+        'ok=-4',
+        'ok:4',
+        'ok=4.not-found=3',
       )
 
       for entry in test_entries:
@@ -155,11 +155,11 @@ class TestExtraInfoDescriptor(unittest.TestCase):
     and dirreq-v3-tunneled-dl lines with valid and invalid data.
     """
 
-    for keyword in ("dirreq-v2-direct-dl", "dirreq-v2-direct-dl", "dirreq-v2-tunneled-dl", "dirreq-v2-tunneled-dl"):
+    for keyword in ('dirreq-v2-direct-dl', 'dirreq-v2-direct-dl', 'dirreq-v2-tunneled-dl', 'dirreq-v2-tunneled-dl'):
       attr = keyword.replace('-', '_').replace('dirreq', 'dir')
-      unknown_attr = attr + "_unknown"
+      unknown_attr = attr + '_unknown'
 
-      test_value = "complete=2712,timeout=32,running=4,min=741,d1=14507,d2=22702,q1=28881,d3=38277,d4=73729,md=111455,d6=168231,d7=257218,q3=319833,d8=390507,d9=616301,something-new=11,max=29917857"
+      test_value = 'complete=2712,timeout=32,running=4,min=741,d1=14507,d2=22702,q1=28881,d3=38277,d4=73729,md=111455,d6=168231,d7=257218,q3=319833,d8=390507,d9=616301,something-new=11,max=29917857'
       desc = get_relay_extrainfo_descriptor({keyword: test_value})
       self.assertEquals(2712, getattr(desc, attr)[DirStat.COMPLETE])
       self.assertEquals(32, getattr(desc, attr)[DirStat.TIMEOUT])
@@ -177,12 +177,12 @@ class TestExtraInfoDescriptor(unittest.TestCase):
       self.assertEquals(390507, getattr(desc, attr)[DirStat.D8])
       self.assertEquals(616301, getattr(desc, attr)[DirStat.D9])
       self.assertEquals(29917857, getattr(desc, attr)[DirStat.MAX])
-      self.assertEquals(11, getattr(desc, unknown_attr)["something-new"])
+      self.assertEquals(11, getattr(desc, unknown_attr)['something-new'])
 
       test_entries = (
-        "complete=-4",
-        "complete:4",
-        "complete=4.timeout=3",
+        'complete=-4',
+        'complete:4',
+        'complete=4.timeout=3',
       )
 
       for entry in test_entries:
@@ -196,7 +196,7 @@ class TestExtraInfoDescriptor(unittest.TestCase):
     Parses the conn-bi-direct line with valid and invalid data.
     """
 
-    desc = get_relay_extrainfo_descriptor({"conn-bi-direct": "2012-05-03 12:07:50 (500 s) 277431,12089,0,2134"})
+    desc = get_relay_extrainfo_descriptor({'conn-bi-direct': '2012-05-03 12:07:50 (500 s) 277431,12089,0,2134'})
     self.assertEquals(datetime.datetime(2012, 5, 3, 12, 7, 50), desc.conn_bi_direct_end)
     self.assertEquals(500, desc.conn_bi_direct_interval)
     self.assertEquals(277431, desc.conn_bi_direct_below)
@@ -205,21 +205,21 @@ class TestExtraInfoDescriptor(unittest.TestCase):
     self.assertEquals(2134, desc.conn_bi_direct_both)
 
     test_entries = (
-      "",
-      "2012-05-03 ",
-      "2012-05-03",
-      "2012-05-03 12:07:60 (500 s)",
-      "2012-05-03 12:07:50 (500s)",
-      "2012-05-03 12:07:50 (500 s",
-      "2012-05-03 12:07:50 (500 )",
-      "2012-05-03 12:07:50 (500 s)11",
-      "2012-05-03 12:07:50 (500 s) 277431,12089,0",
-      "2012-05-03 12:07:50 (500 s) 277431,12089,0a,2134",
-      "2012-05-03 12:07:50 (500 s) -277431,12089,0,2134",
+      '',
+      '2012-05-03 ',
+      '2012-05-03',
+      '2012-05-03 12:07:60 (500 s)',
+      '2012-05-03 12:07:50 (500s)',
+      '2012-05-03 12:07:50 (500 s',
+      '2012-05-03 12:07:50 (500 )',
+      '2012-05-03 12:07:50 (500 s)11',
+      '2012-05-03 12:07:50 (500 s) 277431,12089,0',
+      '2012-05-03 12:07:50 (500 s) 277431,12089,0a,2134',
+      '2012-05-03 12:07:50 (500 s) -277431,12089,0,2134',
     )
 
     for entry in test_entries:
-      desc_text = get_relay_extrainfo_descriptor({"conn-bi-direct": entry}, content = True)
+      desc_text = get_relay_extrainfo_descriptor({'conn-bi-direct': entry}, content = True)
       desc = self._expect_invalid_attr(desc_text)
       self.assertEquals(None, desc.conn_bi_direct_end)
       self.assertEquals(None, desc.conn_bi_direct_interval)
@@ -238,10 +238,10 @@ class TestExtraInfoDescriptor(unittest.TestCase):
       attr = keyword.replace('-', '_').replace('dirreq', 'dir')
 
       test_entries = (
-        ("0.00%", 0.0),
-        ("0.01%", 0.0001),
-        ("50%", 0.5),
-        ("100.0%", 1.0),
+        ('0.00%', 0.0),
+        ('0.01%', 0.0001),
+        ('50%', 0.5),
+        ('100.0%', 1.0),
       )
 
       for test_value, expected_value in test_entries:
@@ -249,10 +249,10 @@ class TestExtraInfoDescriptor(unittest.TestCase):
         self.assertEquals(expected_value, getattr(desc, attr))
 
       test_entries = (
-        ("", None),
-        (" ", None),
-        ("100", None),
-        ("-5%", -0.05),
+        ('', None),
+        (' ', None),
+        ('100', None),
+        ('-5%', -0.05),
       )
 
       for entry, expected in test_entries:
@@ -269,10 +269,10 @@ class TestExtraInfoDescriptor(unittest.TestCase):
       attr = keyword.replace('-', '_')
 
       test_entries = (
-        ("", []),
-        (" ", []),
-        ("0,0,0", [0.0, 0.0, 0.0]),
-        ("2.3,-4.6,8.9,16.12,32.15", [2.3, -4.6, 8.9, 16.12, 32.15]),
+        ('', []),
+        (' ', []),
+        ('0,0,0', [0.0, 0.0, 0.0]),
+        ('2.3,-4.6,8.9,16.12,32.15', [2.3, -4.6, 8.9, 16.12, 32.15]),
       )
 
       for test_value, expected_value in test_entries:
@@ -280,9 +280,9 @@ class TestExtraInfoDescriptor(unittest.TestCase):
         self.assertEquals(expected_value, getattr(desc, attr))
 
       test_entries = (
-        (",,11", [11.0]),
-        ("abc,5.7,def", [5.7]),
-        ("blarg", []),
+        (',,11', [11.0]),
+        ('abc,5.7,def', [5.7]),
+        ('blarg', []),
       )
 
       for entry, expected in test_entries:
@@ -298,14 +298,14 @@ class TestExtraInfoDescriptor(unittest.TestCase):
     for keyword in ('published', 'geoip-start-time'):
       attr = keyword.replace('-', '_')
 
-      desc = get_relay_extrainfo_descriptor({keyword: "2012-05-03 12:07:50"})
+      desc = get_relay_extrainfo_descriptor({keyword: '2012-05-03 12:07:50'})
       self.assertEquals(datetime.datetime(2012, 5, 3, 12, 7, 50), getattr(desc, attr))
 
       test_entries = (
-        "",
-        "2012-05-03 12:07:60",
-        "2012-05-03 ",
-        "2012-05-03",
+        '',
+        '2012-05-03 12:07:60',
+        '2012-05-03 ',
+        '2012-05-03',
       )
 
       for entry in test_entries:
@@ -320,20 +320,20 @@ class TestExtraInfoDescriptor(unittest.TestCase):
 
     for keyword in ('cell-stats-end', 'entry-stats-end', 'exit-stats-end', 'bridge-stats-end', 'dirreq-stats-end'):
       end_attr = keyword.replace('-', '_').replace('dirreq', 'dir')
-      interval_attr = end_attr[:-4] + "_interval"
+      interval_attr = end_attr[:-4] + '_interval'
 
-      desc = get_relay_extrainfo_descriptor({keyword: "2012-05-03 12:07:50 (500 s)"})
+      desc = get_relay_extrainfo_descriptor({keyword: '2012-05-03 12:07:50 (500 s)'})
       self.assertEquals(datetime.datetime(2012, 5, 3, 12, 7, 50), getattr(desc, end_attr))
       self.assertEquals(500, getattr(desc, interval_attr))
 
       test_entries = (
-        "",
-        "2012-05-03 ",
-        "2012-05-03",
-        "2012-05-03 12:07:60 (500 s)",
-        "2012-05-03 12:07:50 (500s)",
-        "2012-05-03 12:07:50 (500 s",
-        "2012-05-03 12:07:50 (500 )",
+        '',
+        '2012-05-03 ',
+        '2012-05-03',
+        '2012-05-03 12:07:60 (500 s)',
+        '2012-05-03 12:07:50 (500s)',
+        '2012-05-03 12:07:50 (500 s',
+        '2012-05-03 12:07:50 (500 )',
       )
 
       for entry in test_entries:
@@ -350,31 +350,31 @@ class TestExtraInfoDescriptor(unittest.TestCase):
 
     for keyword in ('read-history', 'write-history', 'dirreq-read-history', 'dirreq-write-history'):
       base_attr = keyword.replace('-', '_').replace('dirreq', 'dir')
-      end_attr = base_attr + "_end"
-      interval_attr = base_attr + "_interval"
-      values_attr = base_attr + "_values"
+      end_attr = base_attr + '_end'
+      interval_attr = base_attr + '_interval'
+      values_attr = base_attr + '_values'
 
       test_entries = (
-        ("", []),
-        (" ", []),
-        (" 50,11,5", [50, 11, 5]),
+        ('', []),
+        (' ', []),
+        (' 50,11,5', [50, 11, 5]),
       )
 
       for test_values, expected_values in test_entries:
-        desc = get_relay_extrainfo_descriptor({keyword: "2012-05-03 12:07:50 (500 s)%s" % test_values})
+        desc = get_relay_extrainfo_descriptor({keyword: '2012-05-03 12:07:50 (500 s)%s' % test_values})
         self.assertEquals(datetime.datetime(2012, 5, 3, 12, 7, 50), getattr(desc, end_attr))
         self.assertEquals(500, getattr(desc, interval_attr))
         self.assertEquals(expected_values, getattr(desc, values_attr))
 
       test_entries = (
-        "",
-        "2012-05-03 ",
-        "2012-05-03",
-        "2012-05-03 12:07:60 (500 s)",
-        "2012-05-03 12:07:50 (500s)",
-        "2012-05-03 12:07:50 (500 s",
-        "2012-05-03 12:07:50 (500 )",
-        "2012-05-03 12:07:50 (500 s)11",
+        '',
+        '2012-05-03 ',
+        '2012-05-03',
+        '2012-05-03 12:07:60 (500 s)',
+        '2012-05-03 12:07:50 (500s)',
+        '2012-05-03 12:07:50 (500 s',
+        '2012-05-03 12:07:50 (500 )',
+        '2012-05-03 12:07:50 (500 s)11',
       )
 
       for entry in test_entries:
@@ -394,9 +394,9 @@ class TestExtraInfoDescriptor(unittest.TestCase):
       attr = keyword.replace('-', '_')
 
       test_entries = (
-        ("", {}),
-        ("443=100,other=111", {443: 100, 'other': 111}),
-        ("80=115533759,443=1777,995=690", {80: 115533759, 443: 1777, 995: 690}),
+        ('', {}),
+        ('443=100,other=111', {443: 100, 'other': 111}),
+        ('80=115533759,443=1777,995=690', {80: 115533759, 443: 1777, 995: 690}),
       )
 
       for test_value, expected_value in test_entries:
@@ -404,12 +404,12 @@ class TestExtraInfoDescriptor(unittest.TestCase):
         self.assertEquals(expected_value, getattr(desc, attr))
 
       test_entries = (
-        "8000000=115533759",
-        "-80=115533759",
-        "80=-115533759",
-        "=115533759",
-        "80=",
-        "80,115533759",
+        '8000000=115533759',
+        '-80=115533759',
+        '80=-115533759',
+        '=115533759',
+        '80=',
+        '80,115533759',
       )
 
       for entry in test_entries:
@@ -426,8 +426,8 @@ class TestExtraInfoDescriptor(unittest.TestCase):
       attr = keyword.replace('-', '_').replace('dirreq', 'dir').replace('reqs', 'requests')
 
       test_entries = (
-        ("", {}),
-        ("uk=5,de=3,jp=2", {'uk': 5, 'de': 3, 'jp': 2}),
+        ('', {}),
+        ('uk=5,de=3,jp=2', {'uk': 5, 'de': 3, 'jp': 2}),
       )
 
       for test_value, expected_value in test_entries:
@@ -435,10 +435,10 @@ class TestExtraInfoDescriptor(unittest.TestCase):
         self.assertEquals(expected_value, getattr(desc, attr))
 
       test_entries = (
-        "uk=-4",
-        "uki=4",
-        "uk:4",
-        "uk=4.de=3",
+        'uk=-4',
+        'uki=4',
+        'uk:4',
+        'uk=4.de=3',
       )
 
       for entry in test_entries:
@@ -452,26 +452,26 @@ class TestExtraInfoDescriptor(unittest.TestCase):
 
     desc = get_bridge_extrainfo_descriptor()
 
-    self.assertEquals("ec2bridgereaac65a3", desc.nickname)
-    self.assertEquals("1EC248422B57D9C0BD751892FE787585407479A4", desc.fingerprint)
-    self.assertEquals("006FD96BA35E7785A6A3B8B75FE2E2435A13BDB4", desc.digest())
+    self.assertEquals('ec2bridgereaac65a3', desc.nickname)
+    self.assertEquals('1EC248422B57D9C0BD751892FE787585407479A4', desc.fingerprint)
+    self.assertEquals('006FD96BA35E7785A6A3B8B75FE2E2435A13BDB4', desc.digest())
     self.assertEquals([], desc.get_unrecognized_lines())
 
     # check that we don't have crypto fields
-    self.assertRaises(AttributeError, getattr, desc, "signature")
+    self.assertRaises(AttributeError, getattr, desc, 'signature')
 
   def test_bridge_ip_versions_line(self):
     """
     Parses the 'bridge-ip-versions' line, which only appears in bridges.
     """
 
-    desc = get_bridge_extrainfo_descriptor({"bridge-ip-versions": "v4=16,v6=40"})
+    desc = get_bridge_extrainfo_descriptor({'bridge-ip-versions': 'v4=16,v6=40'})
     self.assertEquals({'v4': 16, 'v6': 40}, desc.ip_versions)
 
-    desc = get_bridge_extrainfo_descriptor({"bridge-ip-versions": ""})
+    desc = get_bridge_extrainfo_descriptor({'bridge-ip-versions': ''})
     self.assertEquals({}, desc.ip_versions)
 
-    desc_text = get_bridge_extrainfo_descriptor({"bridge-ip-versions": "v4=24.5"}, content = True)
+    desc_text = get_bridge_extrainfo_descriptor({'bridge-ip-versions': 'v4=24.5'}, content = True)
     self.assertRaises(ValueError, RelayExtraInfoDescriptor, desc_text)
 
   def test_bridge_ip_transports_line(self):
@@ -479,13 +479,13 @@ class TestExtraInfoDescriptor(unittest.TestCase):
     Parses the 'bridge-ip-transports' line, which only appears in bridges.
     """
 
-    desc = get_bridge_extrainfo_descriptor({"bridge-ip-transports": "<OR>=16,<??>=40"})
+    desc = get_bridge_extrainfo_descriptor({'bridge-ip-transports': '<OR>=16,<??>=40'})
     self.assertEquals({'<OR>': 16, '<??>': 40}, desc.ip_transports)
 
-    desc = get_bridge_extrainfo_descriptor({"bridge-ip-transports": ""})
+    desc = get_bridge_extrainfo_descriptor({'bridge-ip-transports': ''})
     self.assertEquals({}, desc.ip_transports)
 
-    desc_text = get_bridge_extrainfo_descriptor({"bridge-ip-transports": "<OR>=24.5"}, content = True)
+    desc_text = get_bridge_extrainfo_descriptor({'bridge-ip-transports': '<OR>=24.5'}, content = True)
     self.assertRaises(ValueError, RelayExtraInfoDescriptor, desc_text)
 
   def test_transport_line(self):
@@ -493,17 +493,17 @@ class TestExtraInfoDescriptor(unittest.TestCase):
     Basic exercise for both a bridge and relay's transport entry.
     """
 
-    desc = get_bridge_extrainfo_descriptor({"transport": "obfs3"})
-    self.assertEquals({"obfs3": (None, None, None)}, desc.transport)
+    desc = get_bridge_extrainfo_descriptor({'transport': 'obfs3'})
+    self.assertEquals({'obfs3': (None, None, None)}, desc.transport)
     self.assertEquals([], desc.get_unrecognized_lines())
 
-    desc = get_relay_extrainfo_descriptor({"transport": "obfs2 83.212.96.201:33570"})
-    self.assertEquals({"obfs2": ("83.212.96.201", 33570, [])}, desc.transport)
+    desc = get_relay_extrainfo_descriptor({'transport': 'obfs2 83.212.96.201:33570'})
+    self.assertEquals({'obfs2': ('83.212.96.201', 33570, [])}, desc.transport)
     self.assertEquals([], desc.get_unrecognized_lines())
 
     # multiple transport lines
-    desc = get_bridge_extrainfo_descriptor({"transport": "obfs3\ntransport obfs4"})
-    self.assertEquals({"obfs3": (None, None, None), "obfs4": (None, None, None)}, desc.transport)
+    desc = get_bridge_extrainfo_descriptor({'transport': 'obfs3\ntransport obfs4'})
+    self.assertEquals({'obfs3': (None, None, None), 'obfs4': (None, None, None)}, desc.transport)
     self.assertEquals([], desc.get_unrecognized_lines())
 
   def _expect_invalid_attr(self, desc_text, attr = None, expected_value = None):
@@ -523,6 +523,6 @@ class TestExtraInfoDescriptor(unittest.TestCase):
       self.assertEquals(expected_value, getattr(desc, attr))
     else:
       # check a default attribute
-      self.assertEquals("ninja", desc.nickname)
+      self.assertEquals('ninja', desc.nickname)
 
     return desc
diff --git a/test/unit/descriptor/microdescriptor.py b/test/unit/descriptor/microdescriptor.py
index cd42f78..e126c8c 100644
--- a/test/unit/descriptor/microdescriptor.py
+++ b/test/unit/descriptor/microdescriptor.py
@@ -24,7 +24,7 @@ class TestMicrodescriptor(unittest.TestCase):
     self.assertEquals(None, desc.ntor_onion_key)
     self.assertEquals([], desc.or_addresses)
     self.assertEquals([], desc.family)
-    self.assertEquals(stem.exit_policy.MicroExitPolicy("reject 1-65535"), desc.exit_policy)
+    self.assertEquals(stem.exit_policy.MicroExitPolicy('reject 1-65535'), desc.exit_policy)
     self.assertEquals(None, desc.exit_policy_v6)
     self.assertEquals(None, desc.identifier_type)
     self.assertEquals(None, desc.identifier)
@@ -35,19 +35,19 @@ class TestMicrodescriptor(unittest.TestCase):
     Includes unrecognized content in the descriptor.
     """
 
-    desc = get_microdescriptor({"pepperjack": "is oh so tasty!"})
-    self.assertEquals(["pepperjack is oh so tasty!"], desc.get_unrecognized_lines())
+    desc = get_microdescriptor({'pepperjack': 'is oh so tasty!'})
+    self.assertEquals(['pepperjack is oh so tasty!'], desc.get_unrecognized_lines())
 
   def test_proceeding_line(self):
     """
     Includes a line prior to the 'onion-key' entry.
     """
 
-    desc_text = b"family Amunet1\n" + get_microdescriptor(content = True)
+    desc_text = b'family Amunet1\n' + get_microdescriptor(content = True)
     self.assertRaises(ValueError, Microdescriptor, desc_text)
 
     desc = Microdescriptor(desc_text, validate = False)
-    self.assertEquals(["Amunet1"], desc.family)
+    self.assertEquals(['Amunet1'], desc.family)
 
   def test_a_line(self):
     """
@@ -55,12 +55,12 @@ class TestMicrodescriptor(unittest.TestCase):
     """
 
     desc_text = get_microdescriptor(content = True)
-    desc_text += b"\na 10.45.227.253:9001"
-    desc_text += b"\na [fd9f:2e19:3bcf::02:9970]:9001"
+    desc_text += b'\na 10.45.227.253:9001'
+    desc_text += b'\na [fd9f:2e19:3bcf::02:9970]:9001'
 
     expected = [
-      ("10.45.227.253", 9001, False),
-      ("fd9f:2e19:3bcf::02:9970", 9001, True),
+      ('10.45.227.253', 9001, False),
+      ('fd9f:2e19:3bcf::02:9970', 9001, True),
     ]
 
     desc = Microdescriptor(desc_text)
@@ -71,14 +71,14 @@ class TestMicrodescriptor(unittest.TestCase):
     Check the family line.
     """
 
-    desc = get_microdescriptor({"family": "Amunet1 Amunet2 Amunet3"})
-    self.assertEquals(["Amunet1", "Amunet2", "Amunet3"], desc.family)
+    desc = get_microdescriptor({'family': 'Amunet1 Amunet2 Amunet3'})
+    self.assertEquals(['Amunet1', 'Amunet2', 'Amunet3'], desc.family)
 
     # try multiple family lines
 
     desc_text = get_microdescriptor(content = True)
-    desc_text += b"\nfamily Amunet1"
-    desc_text += b"\nfamily Amunet2"
+    desc_text += b'\nfamily Amunet1'
+    desc_text += b'\nfamily Amunet2'
 
     self.assertRaises(ValueError, Microdescriptor, desc_text)
 
@@ -92,14 +92,14 @@ class TestMicrodescriptor(unittest.TestCase):
     field so we're not investing much effort here.
     """
 
-    desc = get_microdescriptor({"p": "accept 80,110,143,443"})
-    self.assertEquals(stem.exit_policy.MicroExitPolicy("accept 80,110,143,443"), desc.exit_policy)
+    desc = get_microdescriptor({'p': 'accept 80,110,143,443'})
+    self.assertEquals(stem.exit_policy.MicroExitPolicy('accept 80,110,143,443'), desc.exit_policy)
 
   def test_identifier(self):
     """
     Basic check for 'id' lines.
     """
 
-    desc = get_microdescriptor({"id": "rsa1024 Cd47okjCHD83YGzThGBDptXs9Z4"})
+    desc = get_microdescriptor({'id': 'rsa1024 Cd47okjCHD83YGzThGBDptXs9Z4'})
     self.assertEquals('rsa1024', desc.identifier_type)
     self.assertEquals('Cd47okjCHD83YGzThGBDptXs9Z4', desc.identifier)
diff --git a/test/unit/descriptor/networkstatus/__init__.py b/test/unit/descriptor/networkstatus/__init__.py
index bd68bfe..9c77f2d 100644
--- a/test/unit/descriptor/networkstatus/__init__.py
+++ b/test/unit/descriptor/networkstatus/__init__.py
@@ -2,4 +2,4 @@
 Unit tests for stem.descriptor.networkstatus.
 """
 
-__all__ = ["bridge_document", "directory_authority", "key_certificate", "document_v2", "document_v3"]
+__all__ = ['bridge_document', 'directory_authority', 'key_certificate', 'document_v2', 'document_v3']
diff --git a/test/unit/descriptor/networkstatus/bridge_document.py b/test/unit/descriptor/networkstatus/bridge_document.py
index a40bd84..c5aaba6 100644
--- a/test/unit/descriptor/networkstatus/bridge_document.py
+++ b/test/unit/descriptor/networkstatus/bridge_document.py
@@ -26,7 +26,7 @@ class TestBridgeNetworkStatusDocument(unittest.TestCase):
     Parse a document without any router status entries.
     """
 
-    document = BridgeNetworkStatusDocument(b"published 2012-06-01 04:07:04")
+    document = BridgeNetworkStatusDocument(b'published 2012-06-01 04:07:04')
     self.assertEqual(datetime.datetime(2012, 6, 1, 4, 7, 4), document.published)
     self.assertEqual({}, document.routers)
     self.assertEqual([], document.get_unrecognized_lines())
@@ -40,5 +40,5 @@ class TestBridgeNetworkStatusDocument(unittest.TestCase):
     self.assertEqual(datetime.datetime(2012, 6, 1, 4, 7, 4), document.published)
 
     self.assertEqual(2, len(document.routers))
-    self.assertEqual(set(["Unnamed", "TolFuin"]), set([desc.nickname for desc in document.routers.values()]))
+    self.assertEqual(set(['Unnamed', 'TolFuin']), set([desc.nickname for desc in document.routers.values()]))
     self.assertEqual([], document.get_unrecognized_lines())
diff --git a/test/unit/descriptor/networkstatus/directory_authority.py b/test/unit/descriptor/networkstatus/directory_authority.py
index d8a818a..dd769f7 100644
--- a/test/unit/descriptor/networkstatus/directory_authority.py
+++ b/test/unit/descriptor/networkstatus/directory_authority.py
@@ -16,15 +16,15 @@ class TestDirectoryAuthority(unittest.TestCase):
 
     authority = get_directory_authority()
 
-    self.assertEqual("turtles", authority.nickname)
-    self.assertEqual("27B6B5996C426270A5C95488AA5BCEB6BCC86956", authority.fingerprint)
-    self.assertEqual("no.place.com", authority.hostname)
-    self.assertEqual("76.73.17.194", authority.address)
+    self.assertEqual('turtles', authority.nickname)
+    self.assertEqual('27B6B5996C426270A5C95488AA5BCEB6BCC86956', authority.fingerprint)
+    self.assertEqual('no.place.com', authority.hostname)
+    self.assertEqual('76.73.17.194', authority.address)
     self.assertEqual(9030, authority.dir_port)
     self.assertEqual(9090, authority.or_port)
     self.assertEqual(False, authority.is_legacy)
-    self.assertEqual("Mike Perry <email>", authority.contact)
-    self.assertEqual("0B6D1E9A300B895AA2D0B427F92917B6995C3C1C", authority.vote_digest)
+    self.assertEqual('Mike Perry <email>', authority.contact)
+    self.assertEqual('0B6D1E9A300B895AA2D0B427F92917B6995C3C1C', authority.vote_digest)
     self.assertEqual(None, authority.legacy_dir_key)
     self.assertEqual(None, authority.key_certificate)
     self.assertEqual([], authority.get_unrecognized_lines())
@@ -36,14 +36,14 @@ class TestDirectoryAuthority(unittest.TestCase):
 
     authority = get_directory_authority(is_vote = True)
 
-    self.assertEqual("turtles", authority.nickname)
-    self.assertEqual("27B6B5996C426270A5C95488AA5BCEB6BCC86956", authority.fingerprint)
-    self.assertEqual("no.place.com", authority.hostname)
-    self.assertEqual("76.73.17.194", authority.address)
+    self.assertEqual('turtles', authority.nickname)
+    self.assertEqual('27B6B5996C426270A5C95488AA5BCEB6BCC86956', authority.fingerprint)
+    self.assertEqual('no.place.com', authority.hostname)
+    self.assertEqual('76.73.17.194', authority.address)
     self.assertEqual(9030, authority.dir_port)
     self.assertEqual(9090, authority.or_port)
     self.assertEqual(False, authority.is_legacy)
-    self.assertEqual("Mike Perry <email>", authority.contact)
+    self.assertEqual('Mike Perry <email>', authority.contact)
     self.assertEqual(None, authority.vote_digest)
     self.assertEqual(None, authority.legacy_dir_key)
     self.assertEqual(get_key_certificate(), authority.key_certificate)
@@ -54,21 +54,21 @@ class TestDirectoryAuthority(unittest.TestCase):
     Includes unrecognized content in the descriptor.
     """
 
-    authority = get_directory_authority({"pepperjack": "is oh so tasty!"})
-    self.assertEquals(["pepperjack is oh so tasty!"], authority.get_unrecognized_lines())
+    authority = get_directory_authority({'pepperjack': 'is oh so tasty!'})
+    self.assertEquals(['pepperjack is oh so tasty!'], authority.get_unrecognized_lines())
 
   def test_legacy_authority(self):
     """
     Parses an authority using the '-legacy' format.
     """
 
-    content = "dir-source gabelmoo-legacy 81349FC1F2DBA2C2C11B45CB9706637D480AB913 212.112.245.170 212.112.245.170 80 443"
+    content = 'dir-source gabelmoo-legacy 81349FC1F2DBA2C2C11B45CB9706637D480AB913 212.112.245.170 212.112.245.170 80 443'
     authority = DirectoryAuthority(content, is_vote = False)
 
-    self.assertEqual("gabelmoo-legacy", authority.nickname)
-    self.assertEqual("81349FC1F2DBA2C2C11B45CB9706637D480AB913", authority.fingerprint)
-    self.assertEqual("212.112.245.170", authority.hostname)
-    self.assertEqual("212.112.245.170", authority.address)
+    self.assertEqual('gabelmoo-legacy', authority.nickname)
+    self.assertEqual('81349FC1F2DBA2C2C11B45CB9706637D480AB913', authority.fingerprint)
+    self.assertEqual('212.112.245.170', authority.hostname)
+    self.assertEqual('212.112.245.170', authority.address)
     self.assertEqual(80, authority.dir_port)
     self.assertEqual(443, authority.or_port)
     self.assertEqual(True, authority.is_legacy)
@@ -83,50 +83,50 @@ class TestDirectoryAuthority(unittest.TestCase):
     Includes a non-mandatory field before the 'dir-source' line.
     """
 
-    content = b"ho-hum 567\n" + get_directory_authority(content = True)
+    content = b'ho-hum 567\n' + get_directory_authority(content = True)
     self.assertRaises(ValueError, DirectoryAuthority, content)
 
     authority = DirectoryAuthority(content, False)
-    self.assertEqual("turtles", authority.nickname)
-    self.assertEqual(["ho-hum 567"], authority.get_unrecognized_lines())
+    self.assertEqual('turtles', authority.nickname)
+    self.assertEqual(['ho-hum 567'], authority.get_unrecognized_lines())
 
   def test_missing_fields(self):
     """
     Parse an authority where a mandatory field is missing.
     """
 
-    for excluded_field in ("dir-source", "contact"):
+    for excluded_field in ('dir-source', 'contact'):
       content = get_directory_authority(exclude = (excluded_field,), content = True)
       self.assertRaises(ValueError, DirectoryAuthority, content)
 
       authority = DirectoryAuthority(content, False)
 
-      if excluded_field == "dir-source":
-        self.assertEqual("Mike Perry <email>", authority.contact)
+      if excluded_field == 'dir-source':
+        self.assertEqual('Mike Perry <email>', authority.contact)
       else:
-        self.assertEqual("turtles", authority.nickname)
+        self.assertEqual('turtles', authority.nickname)
 
   def test_blank_lines(self):
     """
     Includes blank lines, which should be ignored.
     """
 
-    authority = get_directory_authority({"dir-source": AUTHORITY_HEADER[0][1] + "\n\n\n"})
-    self.assertEqual("Mike Perry <email>", authority.contact)
+    authority = get_directory_authority({'dir-source': AUTHORITY_HEADER[0][1] + '\n\n\n'})
+    self.assertEqual('Mike Perry <email>', authority.contact)
 
   def test_duplicate_lines(self):
     """
     Duplicates linesin the entry.
     """
 
-    lines = get_directory_authority(content = True).split(b"\n")
+    lines = get_directory_authority(content = True).split(b'\n')
 
     for index, duplicate_line in enumerate(lines):
-      content = b"\n".join(lines[:index] + [duplicate_line] + lines[index:])
+      content = b'\n'.join(lines[:index] + [duplicate_line] + lines[index:])
       self.assertRaises(ValueError, DirectoryAuthority, content)
 
       authority = DirectoryAuthority(content, False)
-      self.assertEqual("turtles", authority.nickname)
+      self.assertEqual('turtles', authority.nickname)
 
   def test_missing_dir_source_field(self):
     """
@@ -135,7 +135,7 @@ class TestDirectoryAuthority(unittest.TestCase):
 
     for missing_value in AUTHORITY_HEADER[0][1].split(' '):
       dir_source = AUTHORITY_HEADER[0][1].replace(missing_value, '').replace('  ', ' ')
-      content = get_directory_authority({"dir-source": dir_source}, content = True)
+      content = get_directory_authority({'dir-source': dir_source}, content = True)
       self.assertRaises(ValueError, DirectoryAuthority, content)
 
       authority = DirectoryAuthority(content, False)
@@ -153,14 +153,14 @@ class TestDirectoryAuthority(unittest.TestCase):
     """
 
     test_values = (
-      "",
-      "zzzzz",
-      "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",
+      '',
+      'zzzzz',
+      'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz',
     )
 
     for value in test_values:
       dir_source = AUTHORITY_HEADER[0][1].replace('27B6B5996C426270A5C95488AA5BCEB6BCC86956', value)
-      content = get_directory_authority({"dir-source": dir_source}, content = True)
+      content = get_directory_authority({'dir-source': dir_source}, content = True)
       self.assertRaises(ValueError, DirectoryAuthority, content)
 
       authority = DirectoryAuthority(content, False)
@@ -172,17 +172,17 @@ class TestDirectoryAuthority(unittest.TestCase):
     """
 
     test_values = (
-      "",
-      "71.35.150.",
-      "71.35..29",
-      "71.35.150",
-      "71.35.150.256",
-      "[fd9f:2e19:3bcf::02:9970]",
+      '',
+      '71.35.150.',
+      '71.35..29',
+      '71.35.150',
+      '71.35.150.256',
+      '[fd9f:2e19:3bcf::02:9970]',
     )
 
     for value in test_values:
       dir_source = AUTHORITY_HEADER[0][1].replace('76.73.17.194', value)
-      content = get_directory_authority({"dir-source": dir_source}, content = True)
+      content = get_directory_authority({'dir-source': dir_source}, content = True)
       self.assertRaises(ValueError, DirectoryAuthority, content)
 
       authority = DirectoryAuthority(content, False)
@@ -194,10 +194,10 @@ class TestDirectoryAuthority(unittest.TestCase):
     """
 
     test_values = (
-      "",
-      "-1",
-      "399482",
-      "blarg",
+      '',
+      '-1',
+      '399482',
+      'blarg',
     )
 
     for value in test_values:
@@ -214,12 +214,12 @@ class TestDirectoryAuthority(unittest.TestCase):
           if include_dir_port:
             dir_source = dir_source.replace('9030', value)
 
-          content = get_directory_authority({"dir-source": dir_source}, content = True)
+          content = get_directory_authority({'dir-source': dir_source}, content = True)
           self.assertRaises(ValueError, DirectoryAuthority, content)
 
           authority = DirectoryAuthority(content, False)
 
-          expected_value = 399482 if value == "399482" else None
+          expected_value = 399482 if value == '399482' else None
           actual_value = authority.or_port if include_or_port else authority.dir_port
           self.assertEqual(expected_value, actual_value)
 
@@ -228,22 +228,22 @@ class TestDirectoryAuthority(unittest.TestCase):
     Includes a 'legacy-dir-key' line with both valid and invalid content.
     """
 
-    test_value = "65968CCB6BECB5AA88459C5A072624C6995B6B72"
-    authority = get_directory_authority({"legacy-dir-key": test_value}, is_vote = True)
+    test_value = '65968CCB6BECB5AA88459C5A072624C6995B6B72'
+    authority = get_directory_authority({'legacy-dir-key': test_value}, is_vote = True)
     self.assertEqual(test_value, authority.legacy_dir_key)
 
     # check that we'll fail if legacy-dir-key appears in a consensus
-    content = get_directory_authority({"legacy-dir-key": test_value}, content = True)
+    content = get_directory_authority({'legacy-dir-key': test_value}, content = True)
     self.assertRaises(ValueError, DirectoryAuthority, content)
 
     test_values = (
-      "",
-      "zzzzz",
-      "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",
+      '',
+      'zzzzz',
+      'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz',
     )
 
     for value in test_values:
-      content = get_directory_authority({"legacy-dir-key": value}, content = True)
+      content = get_directory_authority({'legacy-dir-key': value}, content = True)
       self.assertRaises(ValueError, DirectoryAuthority, content)
 
       authority = DirectoryAuthority(content, False)
@@ -257,14 +257,14 @@ class TestDirectoryAuthority(unittest.TestCase):
     key_cert = get_key_certificate(content = True)
 
     # include a key cert with a consensus
-    content = get_directory_authority(content = True) + b"\n" + key_cert
+    content = get_directory_authority(content = True) + b'\n' + key_cert
     self.assertRaises(ValueError, DirectoryAuthority, content)
 
     authority = DirectoryAuthority(content, False)
     self.assertEqual('turtles', authority.nickname)
 
     # exclude  key cert from a vote
-    content = get_directory_authority(content = True, is_vote = True).replace(b"\n" + key_cert, b'')
+    content = get_directory_authority(content = True, is_vote = True).replace(b'\n' + key_cert, b'')
     self.assertRaises(ValueError, DirectoryAuthority, content, True, True)
 
     authority = DirectoryAuthority(content, False, True)
diff --git a/test/unit/descriptor/networkstatus/document_v2.py b/test/unit/descriptor/networkstatus/document_v2.py
index 5c2dd26..1b98491 100644
--- a/test/unit/descriptor/networkstatus/document_v2.py
+++ b/test/unit/descriptor/networkstatus/document_v2.py
@@ -18,15 +18,15 @@ class TestNetworkStatusDocument(unittest.TestCase):
 
     self.assertEquals({}, document.routers)
     self.assertEquals(2, document.version)
-    self.assertEquals("18.244.0.114", document.hostname)
-    self.assertEquals("18.244.0.114", document.address)
+    self.assertEquals('18.244.0.114', document.hostname)
+    self.assertEquals('18.244.0.114', document.address)
     self.assertEquals(80, document.dir_port)
-    self.assertEquals("719BE45DE224B607C53707D0E2143E2D423E74CF", document.fingerprint)
-    self.assertEquals("arma at mit dot edu", document.contact)
+    self.assertEquals('719BE45DE224B607C53707D0E2143E2D423E74CF', document.fingerprint)
+    self.assertEquals('arma at mit dot edu', document.contact)
     self.assertEquals(NETWORK_STATUS_DOCUMENT_HEADER_V2[5][1][1:], document.signing_key)
     self.assertEquals([], document.client_versions)
     self.assertEquals([], document.server_versions)
     self.assertEquals(datetime.datetime(2005, 12, 16, 0, 13, 46), document.published)
     self.assertEquals([], document.options)
-    self.assertEquals("moria2", document.signing_authority)
+    self.assertEquals('moria2', document.signing_authority)
     self.assertEquals(NETWORK_STATUS_DOCUMENT_FOOTER_V2[0][1][7:], document.signature)
diff --git a/test/unit/descriptor/networkstatus/document_v3.py b/test/unit/descriptor/networkstatus/document_v3.py
index 4c82617..e10a7ca 100644
--- a/test/unit/descriptor/networkstatus/document_v3.py
+++ b/test/unit/descriptor/networkstatus/document_v3.py
@@ -31,11 +31,11 @@ from test.mocking import get_router_status_entry_v3, \
                          NETWORK_STATUS_DOCUMENT_FOOTER
 
 BANDWIDTH_WEIGHT_ENTRIES = (
-  "Wbd", "Wbe", "Wbg", "Wbm",
-  "Wdb",
-  "Web", "Wed", "Wee", "Weg", "Wem",
-  "Wgb", "Wgd", "Wgg", "Wgm",
-  "Wmb", "Wmd", "Wme", "Wmg", "Wmm",
+  'Wbd', 'Wbe', 'Wbg', 'Wbm',
+  'Wdb',
+  'Web', 'Wed', 'Wee', 'Weg', 'Wem',
+  'Wgb', 'Wgd', 'Wgg', 'Wgm',
+  'Wmb', 'Wmd', 'Wme', 'Wmg', 'Wmm',
 )
 
 
@@ -81,7 +81,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
     Parses a minimal network status document.
     """
 
-    document = get_network_status_document_v3({"vote-status": "vote"})
+    document = get_network_status_document_v3({'vote-status': 'vote'})
 
     expected_known_flags = [
       Flag.AUTHORITY, Flag.BADEXIT, Flag.EXIT,
@@ -116,8 +116,8 @@ class TestNetworkStatusDocument(unittest.TestCase):
 
     # makes a consensus with a couple routers, both with the same nickname
 
-    entry1 = get_router_status_entry_v3({'s': "Fast"})
-    entry2 = get_router_status_entry_v3({'s': "Valid"})
+    entry1 = get_router_status_entry_v3({'s': 'Fast'})
+    entry2 = get_router_status_entry_v3({'s': 'Valid'})
     content = get_network_status_document_v3(routers = (entry1, entry2), content = True)
 
     # first example: parsing via the NetworkStatusDocumentV3 constructor
@@ -144,10 +144,10 @@ class TestNetworkStatusDocument(unittest.TestCase):
     # Simple sanity check that they provide the right type, and that the
     # document includes or excludes the router status entries as appropriate.
 
-    entry1 = get_router_status_entry_v3({'s': "Fast"})
+    entry1 = get_router_status_entry_v3({'s': 'Fast'})
     entry2 = get_router_status_entry_v3({
-      'r': "Nightfae AWt0XNId/OU2xX5xs5hVtDc5Mes 6873oEfM7fFIbxYtwllw9GPDwkA 2013-02-20 11:12:27 85.177.66.233 9001 9030",
-      's': "Valid",
+      'r': 'Nightfae AWt0XNId/OU2xX5xs5hVtDc5Mes 6873oEfM7fFIbxYtwllw9GPDwkA 2013-02-20 11:12:27 85.177.66.233 9001 9030',
+      's': 'Valid',
     })
 
     content = get_network_status_document_v3(routers = (entry1, entry2), content = True)
@@ -167,8 +167,8 @@ class TestNetworkStatusDocument(unittest.TestCase):
     Try parsing a document via the _parse_file() function.
     """
 
-    entry1 = get_router_status_entry_v3({'s': "Fast"})
-    entry2 = get_router_status_entry_v3({'s': "Valid"})
+    entry1 = get_router_status_entry_v3({'s': 'Fast'})
+    entry2 = get_router_status_entry_v3({'s': 'Valid'})
     content = get_network_status_document_v3(routers = (entry1, entry2), content = True)
 
     # the document that the entries refer to should actually be the minimal
@@ -189,7 +189,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
     """
 
     for is_consensus in (True, False):
-      attr = {"vote-status": "consensus"} if is_consensus else {"vote-status": "vote"}
+      attr = {'vote-status': 'consensus'} if is_consensus else {'vote-status': 'vote'}
       is_vote = not is_consensus
 
       for entries in (HEADER_STATUS_DOCUMENT_FIELDS, FOOTER_STATUS_DOCUMENT_FIELDS):
@@ -204,8 +204,8 @@ class TestNetworkStatusDocument(unittest.TestCase):
     Includes unrecognized content in the document.
     """
 
-    document = get_network_status_document_v3({"pepperjack": "is oh so tasty!"})
-    self.assertEquals(["pepperjack is oh so tasty!"], document.get_unrecognized_lines())
+    document = get_network_status_document_v3({'pepperjack': 'is oh so tasty!'})
+    self.assertEquals(['pepperjack is oh so tasty!'], document.get_unrecognized_lines())
 
   def test_misordered_fields(self):
     """
@@ -213,8 +213,8 @@ class TestNetworkStatusDocument(unittest.TestCase):
     """
 
     for is_consensus in (True, False):
-      attr = {"vote-status": "consensus"} if is_consensus else {"vote-status": "vote"}
-      lines = get_network_status_document_v3(attr, content = True).split(b"\n")
+      attr = {'vote-status': 'consensus'} if is_consensus else {'vote-status': 'vote'}
+      lines = get_network_status_document_v3(attr, content = True).split(b'\n')
 
       for index in xrange(len(lines) - 1):
         # once we reach the authority entry or later we're done since swapping
@@ -229,7 +229,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
         test_lines = list(lines)
         test_lines[index], test_lines[index + 1] = test_lines[index + 1], test_lines[index]
 
-        content = b"\n".join(test_lines)
+        content = b'\n'.join(test_lines)
         self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
         NetworkStatusDocumentV3(content, False)  # constructs without validation
 
@@ -240,8 +240,8 @@ class TestNetworkStatusDocument(unittest.TestCase):
     """
 
     for is_consensus in (True, False):
-      attr = {"vote-status": "consensus"} if is_consensus else {"vote-status": "vote"}
-      lines = get_network_status_document_v3(attr, content = True).split(b"\n")
+      attr = {'vote-status': 'consensus'} if is_consensus else {'vote-status': 'vote'}
+      lines = get_network_status_document_v3(attr, content = True).split(b'\n')
 
       for index, line in enumerate(lines):
         if not is_consensus and lines[index].startswith(b'dir-source'):
@@ -253,13 +253,13 @@ class TestNetworkStatusDocument(unittest.TestCase):
         #   validation failure
 
         test_lines = list(lines)
-        if line.startswith(b"directory-signature "):
+        if line.startswith(b'directory-signature '):
           break
 
         # duplicates the line
         test_lines.insert(index, line)
 
-        content = b"\n".join(test_lines)
+        content = b'\n'.join(test_lines)
         self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
         NetworkStatusDocumentV3(content, False)  # constructs without validation
 
@@ -269,17 +269,17 @@ class TestNetworkStatusDocument(unittest.TestCase):
     different document version with the v3 parser.
     """
 
-    document = get_network_status_document_v3({"network-status-version": "3"})
+    document = get_network_status_document_v3({'network-status-version': '3'})
     self.assertEquals(3, document.version)
     self.assertEquals(None, document.version_flavor)
     self.assertEquals(False, document.is_microdescriptor)
 
-    document = get_network_status_document_v3({"network-status-version": "3 microdesc"})
+    document = get_network_status_document_v3({'network-status-version': '3 microdesc'})
     self.assertEquals(3, document.version)
     self.assertEquals('microdesc', document.version_flavor)
     self.assertEquals(True, document.is_microdescriptor)
 
-    content = get_network_status_document_v3({"network-status-version": "4"}, content = True)
+    content = get_network_status_document_v3({'network-status-version': '4'}, content = True)
     self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
 
     document = NetworkStatusDocumentV3(content, False)
@@ -292,23 +292,23 @@ class TestNetworkStatusDocument(unittest.TestCase):
     Parses the vote-status field.
     """
 
-    document = get_network_status_document_v3({"vote-status": "vote"})
+    document = get_network_status_document_v3({'vote-status': 'vote'})
     self.assertEquals(False, document.is_consensus)
     self.assertEquals(True, document.is_vote)
 
-    content = get_network_status_document_v3({"vote-status": "consensus"}, content = True)
+    content = get_network_status_document_v3({'vote-status': 'consensus'}, content = True)
     document = NetworkStatusDocumentV3(content)
     self.assertEquals(True, document.is_consensus)
     self.assertEquals(False, document.is_vote)
 
     test_values = (
-      "",
-      "   ",
-      "votee",
+      '',
+      '   ',
+      'votee',
     )
 
     for test_value in test_values:
-      content = get_network_status_document_v3({"vote-status": test_value}, content = True)
+      content = get_network_status_document_v3({'vote-status': test_value}, content = True)
       self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
 
       document = NetworkStatusDocumentV3(content, False)
@@ -320,25 +320,25 @@ class TestNetworkStatusDocument(unittest.TestCase):
     Parses the consensus-methods field.
     """
 
-    document = get_network_status_document_v3({"vote-status": "vote", "consensus-methods": "12 3 1 780"})
+    document = get_network_status_document_v3({'vote-status': 'vote', 'consensus-methods': '12 3 1 780'})
     self.assertEquals([12, 3, 1, 780], document.consensus_methods)
 
     # check that we default to including consensus-method 1
-    content = get_network_status_document_v3({"vote-status": "vote"}, ("consensus-methods",), content = True)
+    content = get_network_status_document_v3({'vote-status': 'vote'}, ('consensus-methods',), content = True)
     document = NetworkStatusDocumentV3(content, False)
     self.assertEquals([1], document.consensus_methods)
     self.assertEquals(None, document.consensus_method)
 
     test_values = (
-      ("", []),
-      ("   ", []),
-      ("1 2 3 a 5", [1, 2, 3, 5]),
-      ("1 2 3 4.0 5", [1, 2, 3, 5]),
-      ("2 3 4", [2, 3, 4]),  # spec says version one must be included
+      ('', []),
+      ('   ', []),
+      ('1 2 3 a 5', [1, 2, 3, 5]),
+      ('1 2 3 4.0 5', [1, 2, 3, 5]),
+      ('2 3 4', [2, 3, 4]),  # spec says version one must be included
     )
 
     for test_value, expected_consensus_methods in test_values:
-      content = get_network_status_document_v3({"vote-status": "vote", "consensus-methods": test_value}, content = True)
+      content = get_network_status_document_v3({'vote-status': 'vote', 'consensus-methods': test_value}, content = True)
       self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
 
       document = NetworkStatusDocumentV3(content, False)
@@ -349,25 +349,25 @@ class TestNetworkStatusDocument(unittest.TestCase):
     Parses the consensus-method field.
     """
 
-    document = get_network_status_document_v3({"consensus-method": "12"})
+    document = get_network_status_document_v3({'consensus-method': '12'})
     self.assertEquals(12, document.consensus_method)
 
     # check that we default to being consensus-method 1
-    content = get_network_status_document_v3(exclude = ("consensus-method",), content = True)
+    content = get_network_status_document_v3(exclude = ('consensus-method',), content = True)
     document = NetworkStatusDocumentV3(content, False)
     self.assertEquals(1, document.consensus_method)
     self.assertEquals([], document.consensus_methods)
 
     test_values = (
-      "",
-      "   ",
-      "a",
-      "1 2",
-      "2.0",
+      '',
+      '   ',
+      'a',
+      '1 2',
+      '2.0',
     )
 
     for test_value in test_values:
-      content = get_network_status_document_v3({"consensus-method": test_value}, content = True)
+      content = get_network_status_document_v3({'consensus-method': test_value}, content = True)
       self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
 
       document = NetworkStatusDocumentV3(content, False)
@@ -380,14 +380,14 @@ class TestNetworkStatusDocument(unittest.TestCase):
     """
 
     expected = datetime.datetime(2012, 9, 2, 22, 0, 0)
-    test_value = "2012-09-02 22:00:00"
+    test_value = '2012-09-02 22:00:00'
 
     document = get_network_status_document_v3({
-      "vote-status": "vote",
-      "published": test_value,
-      "valid-after": test_value,
-      "fresh-until": test_value,
-      "valid-until": test_value,
+      'vote-status': 'vote',
+      'published': test_value,
+      'valid-after': test_value,
+      'fresh-until': test_value,
+      'valid-until': test_value,
     })
 
     self.assertEquals(expected, document.published)
@@ -396,18 +396,18 @@ class TestNetworkStatusDocument(unittest.TestCase):
     self.assertEquals(expected, document.valid_until)
 
     test_values = (
-      "",
-      "   ",
-      "2012-12-12",
-      "2012-12-12 01:01:",
-      "2012-12-12 01:a1:01",
+      '',
+      '   ',
+      '2012-12-12',
+      '2012-12-12 01:01:',
+      '2012-12-12 01:a1:01',
     )
 
     for field in ('published', 'valid-after', 'fresh-until', 'valid-until'):
       attr = field.replace('-', '_')
 
       for test_value in test_values:
-        content = get_network_status_document_v3({"vote-status": "vote", field: test_value}, content = True)
+        content = get_network_status_document_v3({'vote-status': 'vote', field: test_value}, content = True)
         self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
 
         document = NetworkStatusDocumentV3(content, False)
@@ -418,20 +418,20 @@ class TestNetworkStatusDocument(unittest.TestCase):
     Parses the voting-delay field.
     """
 
-    document = get_network_status_document_v3({"voting-delay": "12 345"})
+    document = get_network_status_document_v3({'voting-delay': '12 345'})
     self.assertEquals(12, document.vote_delay)
     self.assertEquals(345, document.dist_delay)
 
     test_values = (
-      "",
-      "   ",
-      "1 a",
-      "1\t2",
-      "1 2.0",
+      '',
+      '   ',
+      '1 a',
+      '1\t2',
+      '1 2.0',
     )
 
     for test_value in test_values:
-      content = get_network_status_document_v3({"voting-delay": test_value}, content = True)
+      content = get_network_status_document_v3({'voting-delay': test_value}, content = True)
       self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
 
       document = NetworkStatusDocumentV3(content, False)
@@ -444,18 +444,18 @@ class TestNetworkStatusDocument(unittest.TestCase):
     lists of tor versions.
     """
 
-    expected = [stem.version.Version("1.2.3.4"), stem.version.Version("56.789.12.34-alpha")]
-    test_value = "1.2.3.4,56.789.12.34-alpha"
+    expected = [stem.version.Version('1.2.3.4'), stem.version.Version('56.789.12.34-alpha')]
+    test_value = '1.2.3.4,56.789.12.34-alpha'
 
-    document = get_network_status_document_v3({"client-versions": test_value, "server-versions": test_value})
+    document = get_network_status_document_v3({'client-versions': test_value, 'server-versions': test_value})
     self.assertEquals(expected, document.client_versions)
     self.assertEquals(expected, document.server_versions)
 
     test_values = (
-      ("", []),
-      ("   ", []),
-      ("1.2.3.4,", [stem.version.Version("1.2.3.4")]),
-      ("1.2.3.4,1.2.3.a", [stem.version.Version("1.2.3.4")]),
+      ('', []),
+      ('   ', []),
+      ('1.2.3.4,', [stem.version.Version('1.2.3.4')]),
+      ('1.2.3.4,1.2.3.a', [stem.version.Version('1.2.3.4')]),
     )
 
     for field in ('client-versions', 'server-versions'):
@@ -475,17 +475,17 @@ class TestNetworkStatusDocument(unittest.TestCase):
     """
 
     test_values = (
-      ("", []),
-      ("   ", []),
-      ("BadExit", [Flag.BADEXIT]),
-      ("BadExit ", [Flag.BADEXIT]),
-      ("BadExit   ", [Flag.BADEXIT]),
-      ("BadExit Fast", [Flag.BADEXIT, Flag.FAST]),
-      ("BadExit Unrecognized Fast", [Flag.BADEXIT, "Unrecognized", Flag.FAST]),
+      ('', []),
+      ('   ', []),
+      ('BadExit', [Flag.BADEXIT]),
+      ('BadExit ', [Flag.BADEXIT]),
+      ('BadExit   ', [Flag.BADEXIT]),
+      ('BadExit Fast', [Flag.BADEXIT, Flag.FAST]),
+      ('BadExit Unrecognized Fast', [Flag.BADEXIT, 'Unrecognized', Flag.FAST]),
     )
 
     for test_value, expected_value in test_values:
-      document = get_network_status_document_v3({"known-flags": test_value})
+      document = get_network_status_document_v3({'known-flags': test_value})
       self.assertEquals(expected_value, document.known_flags)
 
   def test_flag_thresholds(self):
@@ -494,43 +494,43 @@ class TestNetworkStatusDocument(unittest.TestCase):
     """
 
     test_values = (
-      ("", {}),
-      ("fast-speed=40960", {u"fast-speed": 40960}),    # numeric value
-      ("guard-wfu=94.669%", {u"guard-wfu": 0.94669}),  # percentage value
-      ("guard-wfu=94.669% guard-tk=691200", {u"guard-wfu": 0.94669, u"guard-tk": 691200}),  # multiple values
+      ('', {}),
+      ('fast-speed=40960', {u'fast-speed': 40960}),    # numeric value
+      ('guard-wfu=94.669%', {u'guard-wfu': 0.94669}),  # percentage value
+      ('guard-wfu=94.669% guard-tk=691200', {u'guard-wfu': 0.94669, u'guard-tk': 691200}),  # multiple values
     )
 
     for test_value, expected_value in test_values:
-      document = get_network_status_document_v3({"vote-status": "vote", "flag-thresholds": test_value})
+      document = get_network_status_document_v3({'vote-status': 'vote', 'flag-thresholds': test_value})
       self.assertEquals(expected_value, document.flag_thresholds)
 
     # parses a full entry found in an actual vote
 
-    full_line = "stable-uptime=693369 stable-mtbf=153249 fast-speed=40960 guard-wfu=94.669% guard-tk=691200 guard-bw-inc-exits=174080 guard-bw-exc-exits=184320 enough-mtbf=1"
+    full_line = 'stable-uptime=693369 stable-mtbf=153249 fast-speed=40960 guard-wfu=94.669% guard-tk=691200 guard-bw-inc-exits=174080 guard-bw-exc-exits=184320 enough-mtbf=1'
 
     expected_value = {
-      u"stable-uptime": 693369,
-      u"stable-mtbf": 153249,
-      u"fast-speed": 40960,
-      u"guard-wfu": 0.94669,
-      u"guard-tk": 691200,
-      u"guard-bw-inc-exits": 174080,
-      u"guard-bw-exc-exits": 184320,
-      u"enough-mtbf": 1,
+      u'stable-uptime': 693369,
+      u'stable-mtbf': 153249,
+      u'fast-speed': 40960,
+      u'guard-wfu': 0.94669,
+      u'guard-tk': 691200,
+      u'guard-bw-inc-exits': 174080,
+      u'guard-bw-exc-exits': 184320,
+      u'enough-mtbf': 1,
     }
 
-    document = get_network_status_document_v3({"vote-status": "vote", "flag-thresholds": full_line})
+    document = get_network_status_document_v3({'vote-status': 'vote', 'flag-thresholds': full_line})
     self.assertEquals(expected_value, document.flag_thresholds)
 
     test_values = (
-      "stable-uptime 693369",   # not a key=value mapping
-      "stable-uptime=a693369",  # non-numeric value
-      "guard-wfu=94.669%%",     # double quote
-      "stable-uptime=693369\tstable-mtbf=153249",  # non-space divider
+      'stable-uptime 693369',   # not a key=value mapping
+      'stable-uptime=a693369',  # non-numeric value
+      'guard-wfu=94.669%%',     # double quote
+      'stable-uptime=693369\tstable-mtbf=153249',  # non-space divider
     )
 
     for test_value in test_values:
-      content = get_network_status_document_v3({"vote-status": "vote", "flag-thresholds": test_value}, content = True)
+      content = get_network_status_document_v3({'vote-status': 'vote', 'flag-thresholds': test_value}, content = True)
       self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
 
       document = NetworkStatusDocumentV3(content, False)
@@ -541,17 +541,17 @@ class TestNetworkStatusDocument(unittest.TestCase):
     General testing for the 'params' line, exercising the happy cases.
     """
 
-    document = get_network_status_document_v3({"params": "CircuitPriorityHalflifeMsec=30000 bwauthpid=1 unrecognized=-122"})
-    self.assertEquals(30000, document.params["CircuitPriorityHalflifeMsec"])
-    self.assertEquals(1, document.params["bwauthpid"])
-    self.assertEquals(-122, document.params["unrecognized"])
+    document = get_network_status_document_v3({'params': 'CircuitPriorityHalflifeMsec=30000 bwauthpid=1 unrecognized=-122'})
+    self.assertEquals(30000, document.params['CircuitPriorityHalflifeMsec'])
+    self.assertEquals(1, document.params['bwauthpid'])
+    self.assertEquals(-122, document.params['unrecognized'])
 
     # empty params line
-    content = get_network_status_document_v3({"params": ""}, content = True)
+    content = get_network_status_document_v3({'params': ''}, content = True)
     document = NetworkStatusDocumentV3(content, default_params = True)
     self.assertEquals(DEFAULT_PARAMS, document.params)
 
-    content = get_network_status_document_v3({"params": ""}, content = True)
+    content = get_network_status_document_v3({'params': ''}, content = True)
     document = NetworkStatusDocumentV3(content, default_params = False)
     self.assertEquals({}, document.params)
 
@@ -581,23 +581,23 @@ class TestNetworkStatusDocument(unittest.TestCase):
     """
 
     test_values = (
-      ("foo=2147483648", {"foo": 2147483648}, False),
-      ("foo=-2147483649", {"foo": -2147483649}, False),
-      ("foo=2147483647", {"foo": 2147483647}, True),
-      ("foo=-2147483648", {"foo": -2147483648}, True),
+      ('foo=2147483648', {'foo': 2147483648}, False),
+      ('foo=-2147483649', {'foo': -2147483649}, False),
+      ('foo=2147483647', {'foo': 2147483647}, True),
+      ('foo=-2147483648', {'foo': -2147483648}, True),
 
       # param with special range constraints
-      ("circwindow=99", {"circwindow": 99}, False),
-      ("circwindow=1001", {"circwindow": 1001}, False),
-      ("circwindow=500", {"circwindow": 500}, True),
+      ('circwindow=99', {'circwindow': 99}, False),
+      ('circwindow=1001', {'circwindow': 1001}, False),
+      ('circwindow=500', {'circwindow': 500}, True),
 
       # param that relies on another param for its constraints
-      ("cbtclosequantile=79 cbtquantile=80", {"cbtclosequantile": 79, "cbtquantile": 80}, False),
-      ("cbtclosequantile=80 cbtquantile=80", {"cbtclosequantile": 80, "cbtquantile": 80}, True),
+      ('cbtclosequantile=79 cbtquantile=80', {'cbtclosequantile': 79, 'cbtquantile': 80}, False),
+      ('cbtclosequantile=80 cbtquantile=80', {'cbtclosequantile': 80, 'cbtquantile': 80}, True),
     )
 
     for test_value, expected_value, is_ok in test_values:
-      content = get_network_status_document_v3({"params": test_value}, content = True)
+      content = get_network_status_document_v3({'params': test_value}, content = True)
 
       if is_ok:
         document = NetworkStatusDocumentV3(content, default_params = False)
@@ -612,11 +612,11 @@ class TestNetworkStatusDocument(unittest.TestCase):
     Check that the 'params' line is rejected if out of order.
     """
 
-    content = get_network_status_document_v3({"params": "unrecognized=-122 bwauthpid=1"}, content = True)
+    content = get_network_status_document_v3({'params': 'unrecognized=-122 bwauthpid=1'}, content = True)
     self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
 
     document = NetworkStatusDocumentV3(content, False, default_params = False)
-    self.assertEquals({"unrecognized": -122, "bwauthpid": 1}, document.params)
+    self.assertEquals({'unrecognized': -122, 'bwauthpid': 1}, document.params)
 
   def test_footer_consensus_method_requirement(self):
     """
@@ -624,7 +624,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
     introduced.
     """
 
-    content = get_network_status_document_v3({"consensus-method": "8"}, content = True)
+    content = get_network_status_document_v3({'consensus-method': '8'}, content = True)
     self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
 
     document = NetworkStatusDocumentV3(content, False)
@@ -633,7 +633,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
 
     # excludes a footer from a version that shouldn't have it
 
-    document = get_network_status_document_v3({"consensus-method": "8"}, ("directory-footer", "directory-signature"))
+    document = get_network_status_document_v3({'consensus-method': '8'}, ('directory-footer', 'directory-signature'))
     self.assertEqual([], document.signatures)
     self.assertEqual([], document.get_unrecognized_lines())
 
@@ -644,10 +644,10 @@ class TestNetworkStatusDocument(unittest.TestCase):
 
     document = get_network_status_document_v3(
       {
-        "vote-status": "vote",
-        "consensus-methods": "1 8",
+        'vote-status': 'vote',
+        'consensus-methods': '1 8',
       },
-      exclude = ("directory-footer",),
+      exclude = ('directory-footer',),
       authorities = (get_directory_authority(is_vote = True),)
     )
 
@@ -659,7 +659,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
     Tries to parse a descriptor with content on the 'directory-footer' line.
     """
 
-    content = get_network_status_document_v3({"directory-footer": "blarg"}, content = True)
+    content = get_network_status_document_v3({'directory-footer': 'blarg'}, content = True)
     self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
 
     document = NetworkStatusDocumentV3(content, False)
@@ -676,10 +676,10 @@ class TestNetworkStatusDocument(unittest.TestCase):
     weight_entries, expected = [], {}
 
     for index, key in enumerate(BANDWIDTH_WEIGHT_ENTRIES):
-      weight_entries.append("%s=%i" % (key, index - 5))
+      weight_entries.append('%s=%i' % (key, index - 5))
       expected[key] = index - 5
 
-    document = get_network_status_document_v3({"bandwidth-weights": " ".join(weight_entries)})
+    document = get_network_status_document_v3({'bandwidth-weights': ' '.join(weight_entries)})
     self.assertEquals(expected, document.bandwidth_weights)
 
   def test_bandwidth_wights_malformed(self):
@@ -688,18 +688,18 @@ class TestNetworkStatusDocument(unittest.TestCase):
     """
 
     test_values = (
-      "Wbe",
-      "Wbe=",
-      "Wbe=a",
-      "Wbe=+7",
+      'Wbe',
+      'Wbe=',
+      'Wbe=a',
+      'Wbe=+7',
     )
 
-    base_weight_entry = " ".join(["%s=5" % e for e in BANDWIDTH_WEIGHT_ENTRIES])
-    expected = dict([(e, 5) for e in BANDWIDTH_WEIGHT_ENTRIES if e != "Wbe"])
+    base_weight_entry = ' '.join(['%s=5' % e for e in BANDWIDTH_WEIGHT_ENTRIES])
+    expected = dict([(e, 5) for e in BANDWIDTH_WEIGHT_ENTRIES if e != 'Wbe'])
 
     for test_value in test_values:
-      weight_entry = base_weight_entry.replace("Wbe=5", test_value)
-      content = get_network_status_document_v3({"bandwidth-weights": weight_entry}, content = True)
+      weight_entry = base_weight_entry.replace('Wbe=5', test_value)
+      content = get_network_status_document_v3({'bandwidth-weights': weight_entry}, content = True)
 
       self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
       document = NetworkStatusDocumentV3(content, False)
@@ -710,10 +710,10 @@ class TestNetworkStatusDocument(unittest.TestCase):
     Check that the 'bandwidth-wights' line is rejected if out of order.
     """
 
-    weight_entry = " ".join(["%s=5" % e for e in reversed(BANDWIDTH_WEIGHT_ENTRIES)])
+    weight_entry = ' '.join(['%s=5' % e for e in reversed(BANDWIDTH_WEIGHT_ENTRIES)])
     expected = dict([(e, 5) for e in BANDWIDTH_WEIGHT_ENTRIES])
 
-    content = get_network_status_document_v3({"bandwidth-weights": weight_entry}, content = True)
+    content = get_network_status_document_v3({'bandwidth-weights': weight_entry}, content = True)
     self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
 
     document = NetworkStatusDocumentV3(content, False)
@@ -724,10 +724,10 @@ class TestNetworkStatusDocument(unittest.TestCase):
     Tries adding a 'bandwidth-wights' line to a vote.
     """
 
-    weight_entry = " ".join(["%s=5" % e for e in BANDWIDTH_WEIGHT_ENTRIES])
+    weight_entry = ' '.join(['%s=5' % e for e in BANDWIDTH_WEIGHT_ENTRIES])
     expected = dict([(e, 5) for e in BANDWIDTH_WEIGHT_ENTRIES])
 
-    content = get_network_status_document_v3({"vote-status": "vote", "bandwidth-weights": weight_entry}, content = True)
+    content = get_network_status_document_v3({'vote-status': 'vote', 'bandwidth-weights': weight_entry}, content = True)
     self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
 
     document = NetworkStatusDocumentV3(content, False)
@@ -742,8 +742,8 @@ class TestNetworkStatusDocument(unittest.TestCase):
     # including the signature method field should work
 
     document = get_network_status_document_v3({
-      "network-status-version": "3 microdesc",
-      "directory-signature": "sha256 " + NETWORK_STATUS_DOCUMENT_FOOTER[2][1],
+      'network-status-version': '3 microdesc',
+      'directory-signature': 'sha256 ' + NETWORK_STATUS_DOCUMENT_FOOTER[2][1],
     })
 
     self.assertEqual('sha256', document.signatures[0].method)
@@ -751,7 +751,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
     # excluding the method should default to sha1
 
     document = get_network_status_document_v3({
-      "network-status-version": "3 microdesc",
+      'network-status-version': '3 microdesc',
     })
 
     self.assertEqual('sha1', document.signatures[0].method)
@@ -762,9 +762,9 @@ class TestNetworkStatusDocument(unittest.TestCase):
     """
 
     test_values = (
-      "",
-      "\n",
-      "blarg",
+      '',
+      '\n',
+      'blarg',
     )
 
     for test_value in test_values:
@@ -772,7 +772,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
         attrs = [DOC_SIG.identity, DOC_SIG.key_digest, DOC_SIG.signature]
         attrs[test_attr] = test_value
 
-        content = get_network_status_document_v3({"directory-signature": "%s %s\n%s" % tuple(attrs)}, content = True)
+        content = get_network_status_document_v3({'directory-signature': '%s %s\n%s' % tuple(attrs)}, content = True)
         self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
         NetworkStatusDocumentV3(content, False)  # checks that it's still parsable without validation
 
@@ -783,10 +783,10 @@ class TestNetworkStatusDocument(unittest.TestCase):
     document.
     """
 
-    entry1 = get_router_status_entry_v3({'s': "Fast"})
+    entry1 = get_router_status_entry_v3({'s': 'Fast'})
     entry2 = get_router_status_entry_v3({
-      'r': "Nightfae AWt0XNId/OU2xX5xs5hVtDc5Mes 6873oEfM7fFIbxYtwllw9GPDwkA 2013-02-20 11:12:27 85.177.66.233 9001 9030",
-      's': "Valid",
+      'r': 'Nightfae AWt0XNId/OU2xX5xs5hVtDc5Mes 6873oEfM7fFIbxYtwllw9GPDwkA 2013-02-20 11:12:27 85.177.66.233 9001 9030',
+      's': 'Valid',
     })
 
     document = get_network_status_document_v3(routers = (entry1, entry2))
@@ -796,7 +796,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
 
     # try with an invalid RouterStatusEntry
 
-    entry3 = RouterStatusEntryV3(get_router_status_entry_v3({'r': "ugabuga"}, content = True), False)
+    entry3 = RouterStatusEntryV3(get_router_status_entry_v3({'r': 'ugabuga'}, content = True), False)
     content = get_network_status_document_v3(routers = (entry3,), content = True)
 
     self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
@@ -805,7 +805,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
 
     # try including with a microdescriptor consensus
 
-    content = get_network_status_document_v3({"network-status-version": "3 microdesc"}, routers = (entry1,), content = True)
+    content = get_network_status_document_v3({'network-status-version': '3 microdesc'}, routers = (entry1,), content = True)
     self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
 
     document = NetworkStatusDocumentV3(content, False)
@@ -817,22 +817,22 @@ class TestNetworkStatusDocument(unittest.TestCase):
     document.
     """
 
-    entry1 = get_router_status_entry_micro_v3({'s': "Fast"})
+    entry1 = get_router_status_entry_micro_v3({'s': 'Fast'})
     entry2 = get_router_status_entry_micro_v3({
-      'r': "tornodeviennasil AcWxDFxrHetHYS5m6/MVt8ZN6AM 2013-03-13 22:09:13 78.142.142.246 443 80",
-      's': "Valid",
+      'r': 'tornodeviennasil AcWxDFxrHetHYS5m6/MVt8ZN6AM 2013-03-13 22:09:13 78.142.142.246 443 80',
+      's': 'Valid',
     })
 
-    document = get_network_status_document_v3({"network-status-version": "3 microdesc"}, routers = (entry1, entry2))
+    document = get_network_status_document_v3({'network-status-version': '3 microdesc'}, routers = (entry1, entry2))
 
     self.assertTrue(entry1 in document.routers.values())
     self.assertTrue(entry2 in document.routers.values())
 
     # try with an invalid RouterStatusEntry
 
-    entry3 = RouterStatusEntryMicroV3(get_router_status_entry_micro_v3({'r': "ugabuga"}, content = True), False)
+    entry3 = RouterStatusEntryMicroV3(get_router_status_entry_micro_v3({'r': 'ugabuga'}, content = True), False)
 
-    content = get_network_status_document_v3({"network-status-version": "3 microdesc"}, routers = (entry3,), content = True)
+    content = get_network_status_document_v3({'network-status-version': '3 microdesc'}, routers = (entry3,), content = True)
     self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
 
     document = NetworkStatusDocumentV3(content, False)
@@ -856,8 +856,8 @@ class TestNetworkStatusDocument(unittest.TestCase):
         authority1 = get_directory_authority({'contact': 'doctor jekyll'}, is_vote = is_authorities_vote)
         authority2 = get_directory_authority({'contact': 'mister hyde'}, is_vote = is_authorities_vote)
 
-        vote_status = "vote" if is_document_vote else "consensus"
-        content = get_network_status_document_v3({"vote-status": vote_status}, authorities = (authority1, authority2), content = True)
+        vote_status = 'vote' if is_document_vote else 'consensus'
+        content = get_network_status_document_v3({'vote-status': vote_status}, authorities = (authority1, authority2), content = True)
 
         if is_document_vote == is_authorities_vote:
           if is_document_vote:
@@ -880,13 +880,13 @@ class TestNetworkStatusDocument(unittest.TestCase):
     Includes both normal authorities and those following the '-legacy' format.
     """
 
-    legacy_content = "dir-source gabelmoo-legacy 81349FC1F2DBA2C2C11B45CB9706637D480AB913 212.112.245.170 212.112.245.170 80 443"
+    legacy_content = 'dir-source gabelmoo-legacy 81349FC1F2DBA2C2C11B45CB9706637D480AB913 212.112.245.170 212.112.245.170 80 443'
 
     authority1 = get_directory_authority({'contact': 'doctor jekyll'}, is_vote = False)
     authority2 = DirectoryAuthority(legacy_content, validate = True, is_vote = False)
     authority3 = get_directory_authority({'contact': 'mister hyde'}, is_vote = False)
 
-    document = get_network_status_document_v3({"vote-status": "consensus"}, authorities = (authority1, authority2, authority3))
+    document = get_network_status_document_v3({'vote-status': 'consensus'}, authorities = (authority1, authority2, authority3))
 
     self.assertEquals((authority1, authority2, authority3), document.directory_authorities)
 
@@ -899,10 +899,10 @@ class TestNetworkStatusDocument(unittest.TestCase):
 
     # make the dir-key-published field of the certiciate be malformed
     authority_content = get_directory_authority(is_vote = True, content = True)
-    authority_content = authority_content.replace(b"dir-key-published 2011", b"dir-key-published 2011a")
+    authority_content = authority_content.replace(b'dir-key-published 2011', b'dir-key-published 2011a')
     authority = DirectoryAuthority(authority_content, False, True)
 
-    content = get_network_status_document_v3({"vote-status": "vote"}, authorities = (authority,), content = True)
+    content = get_network_status_document_v3({'vote-status': 'vote'}, authorities = (authority,), content = True)
     self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
 
     document = NetworkStatusDocumentV3(content, validate = False)
diff --git a/test/unit/descriptor/networkstatus/key_certificate.py b/test/unit/descriptor/networkstatus/key_certificate.py
index f94bf0c..8cdb282 100644
--- a/test/unit/descriptor/networkstatus/key_certificate.py
+++ b/test/unit/descriptor/networkstatus/key_certificate.py
@@ -24,7 +24,7 @@ class TestKeyCertificate(unittest.TestCase):
     self.assertEqual(3, certificate.version)
     self.assertEqual(None, certificate.address)
     self.assertEqual(None, certificate.dir_port)
-    self.assertEqual("27B6B5996C426270A5C95488AA5BCEB6BCC86956", certificate.fingerprint)
+    self.assertEqual('27B6B5996C426270A5C95488AA5BCEB6BCC86956', certificate.fingerprint)
     self.assertTrue(CRYPTO_BLOB in certificate.identity_key)
     self.assertEqual(datetime.datetime(2011, 11, 28, 21, 51, 4), certificate.published)
     self.assertEqual(datetime.datetime(2012, 11, 28, 21, 51, 4), certificate.expires)
@@ -38,8 +38,8 @@ class TestKeyCertificate(unittest.TestCase):
     Includes unrecognized content in the descriptor.
     """
 
-    certificate = get_key_certificate({"pepperjack": "is oh so tasty!"})
-    self.assertEquals(["pepperjack is oh so tasty!"], certificate.get_unrecognized_lines())
+    certificate = get_key_certificate({'pepperjack': 'is oh so tasty!'})
+    self.assertEquals(['pepperjack is oh so tasty!'], certificate.get_unrecognized_lines())
 
   def test_first_and_last_lines(self):
     """
@@ -49,12 +49,12 @@ class TestKeyCertificate(unittest.TestCase):
 
     content = get_key_certificate(content = True)
 
-    for cert_text in (b"dir-address 127.0.0.1:80\n" + content,
-                      content + b"\ndir-address 127.0.0.1:80"):
+    for cert_text in (b'dir-address 127.0.0.1:80\n' + content,
+                      content + b'\ndir-address 127.0.0.1:80'):
       self.assertRaises(ValueError, KeyCertificate, cert_text)
 
       certificate = KeyCertificate(cert_text, False)
-      self.assertEqual("127.0.0.1", certificate.address)
+      self.assertEqual('127.0.0.1', certificate.address)
       self.assertEqual(80, certificate.dir_port)
 
   def test_missing_fields(self):
@@ -70,17 +70,17 @@ class TestKeyCertificate(unittest.TestCase):
 
       certificate = KeyCertificate(content, False)
 
-      if excluded_field == "fingerprint":
+      if excluded_field == 'fingerprint':
         self.assertEqual(3, certificate.version)
       else:
-        self.assertEqual("27B6B5996C426270A5C95488AA5BCEB6BCC86956", certificate.fingerprint)
+        self.assertEqual('27B6B5996C426270A5C95488AA5BCEB6BCC86956', certificate.fingerprint)
 
   def test_blank_lines(self):
     """
     Includes blank lines, which should be ignored.
     """
 
-    certificate = get_key_certificate({"dir-key-published": "2011-11-28 21:51:04\n\n\n"})
+    certificate = get_key_certificate({'dir-key-published': '2011-11-28 21:51:04\n\n\n'})
     self.assertEqual(datetime.datetime(2011, 11, 28, 21, 51, 4), certificate.published)
 
   def test_version(self):
@@ -89,14 +89,14 @@ class TestKeyCertificate(unittest.TestCase):
     different certificate version with the v3 parser.
     """
 
-    certificate = get_key_certificate({"dir-key-certificate-version": "3"})
+    certificate = get_key_certificate({'dir-key-certificate-version': '3'})
     self.assertEquals(3, certificate.version)
 
-    content = get_key_certificate({"dir-key-certificate-version": "4"}, content = True)
+    content = get_key_certificate({'dir-key-certificate-version': '4'}, content = True)
     self.assertRaises(ValueError, KeyCertificate, content)
     self.assertEquals(4, KeyCertificate(content, False).version)
 
-    content = get_key_certificate({"dir-key-certificate-version": "boo"}, content = True)
+    content = get_key_certificate({'dir-key-certificate-version': 'boo'}, content = True)
     self.assertRaises(ValueError, KeyCertificate, content)
     self.assertEquals(None, KeyCertificate(content, False).version)
 
@@ -105,23 +105,23 @@ class TestKeyCertificate(unittest.TestCase):
     Parses the dir-address field.
     """
 
-    certificate = get_key_certificate({"dir-address": "127.0.0.1:80"})
-    self.assertEqual("127.0.0.1", certificate.address)
+    certificate = get_key_certificate({'dir-address': '127.0.0.1:80'})
+    self.assertEqual('127.0.0.1', certificate.address)
     self.assertEqual(80, certificate.dir_port)
 
     test_values = (
-      ("", None, None),
-      ("   ", None, None),
-      ("127.0.0.1", None, None),
-      ("127.0.0.1:", None, None),
-      ("80", None, None),
-      (":80", "", 80),
-      ("127.0.0.1a:80", "127.0.0.1a", 80),
-      ("127.0.0.1:80a", None, None),
+      ('', None, None),
+      ('   ', None, None),
+      ('127.0.0.1', None, None),
+      ('127.0.0.1:', None, None),
+      ('80', None, None),
+      (':80', '', 80),
+      ('127.0.0.1a:80', '127.0.0.1a', 80),
+      ('127.0.0.1:80a', None, None),
     )
 
     for test_value, expected_address, expected_port in test_values:
-      content = get_key_certificate({"dir-address": test_value}, content = True)
+      content = get_key_certificate({'dir-address': test_value}, content = True)
       self.assertRaises(ValueError, KeyCertificate, content)
 
       certificate = KeyCertificate(content, False)
@@ -134,14 +134,14 @@ class TestKeyCertificate(unittest.TestCase):
     """
 
     test_values = (
-      "",
-      "   ",
-      "27B6B5996C426270A5C95488AA5BCEB6BCC8695",
-      "27B6B5996C426270A5C95488AA5BCEB6BCC869568",
+      '',
+      '   ',
+      '27B6B5996C426270A5C95488AA5BCEB6BCC8695',
+      '27B6B5996C426270A5C95488AA5BCEB6BCC869568',
     )
 
     for test_value in test_values:
-      content = get_key_certificate({"fingerprint": test_value}, content = True)
+      content = get_key_certificate({'fingerprint': test_value}, content = True)
       self.assertRaises(ValueError, KeyCertificate, content)
 
       certificate = KeyCertificate(content, False)
@@ -154,14 +154,14 @@ class TestKeyCertificate(unittest.TestCase):
     """
 
     test_values = (
-      "",
-      "   ",
-      "2012-12-12",
-      "2012-12-12 01:01:",
-      "2012-12-12 01:a1:01",
+      '',
+      '   ',
+      '2012-12-12',
+      '2012-12-12 01:01:',
+      '2012-12-12 01:a1:01',
     )
 
-    for field, attr in (("dir-key-published", "published"), ("dir-key-expires", "expires")):
+    for field, attr in (('dir-key-published', 'published'), ('dir-key-expires', 'expires')):
       for test_value in test_values:
         content = get_key_certificate({field: test_value}, content = True)
         self.assertRaises(ValueError, KeyCertificate, content)
@@ -177,10 +177,10 @@ class TestKeyCertificate(unittest.TestCase):
 
     # the only non-mandatory field that we haven't exercised yet is dir-key-crosscert
 
-    certificate = get_key_certificate({"dir-key-crosscert": "\n-----BEGIN ID SIGNATURE-----%s-----END ID SIGNATURE-----" % CRYPTO_BLOB})
+    certificate = get_key_certificate({'dir-key-crosscert': '\n-----BEGIN ID SIGNATURE-----%s-----END ID SIGNATURE-----' % CRYPTO_BLOB})
     self.assertTrue(CRYPTO_BLOB in certificate.crosscert)
 
-    test_value = "\n-----BEGIN ID SIGNATURE-----%s-----END UGABUGA SIGNATURE-----" % CRYPTO_BLOB
+    test_value = '\n-----BEGIN ID SIGNATURE-----%s-----END UGABUGA SIGNATURE-----' % CRYPTO_BLOB
 
     for field, attr in (('dir-identity-key', 'identity_key'),
                        ('dir-signing-key', 'signing_key'),
diff --git a/test/unit/descriptor/reader.py b/test/unit/descriptor/reader.py
index 62b561b..34cd8ce 100644
--- a/test/unit/descriptor/reader.py
+++ b/test/unit/descriptor/reader.py
@@ -22,25 +22,25 @@ class TestDescriptorReader(unittest.TestCase):
     """
 
     test_lines = (
-      u"/dir/ 0",
-      u"/dir/file 12345",
-      u"/dir/file with spaces 7138743",
-      u"  /dir/with extra space 12345   ",
-      u"   \t   ",
-      u"",
-      u"/dir/after empty line 12345",
+      u'/dir/ 0',
+      u'/dir/file 12345',
+      u'/dir/file with spaces 7138743',
+      u'  /dir/with extra space 12345   ',
+      u'   \t   ',
+      u'',
+      u'/dir/after empty line 12345',
     )
 
     expected_value = {
-      "/dir/": 0,
-      "/dir/file": 12345,
-      "/dir/file with spaces": 7138743,
-      "/dir/with extra space": 12345,
-      "/dir/after empty line": 12345,
+      '/dir/': 0,
+      '/dir/file': 12345,
+      '/dir/file with spaces': 7138743,
+      '/dir/with extra space': 12345,
+      '/dir/after empty line': 12345,
     }
 
-    open_mock.return_value = io.StringIO(u"\n".join(test_lines))
-    self.assertEquals(expected_value, stem.descriptor.reader.load_processed_files(""))
+    open_mock.return_value = io.StringIO(u'\n'.join(test_lines))
+    self.assertEquals(expected_value, stem.descriptor.reader.load_processed_files(''))
 
   @patch('stem.descriptor.reader.open', create = True)
   def test_load_processed_files_empty(self, open_mock):
@@ -48,8 +48,8 @@ class TestDescriptorReader(unittest.TestCase):
     Tests the load_processed_files() function with an empty file.
     """
 
-    open_mock.return_value = io.StringIO(u"")
-    self.assertEquals({}, stem.descriptor.reader.load_processed_files(""))
+    open_mock.return_value = io.StringIO(u'')
+    self.assertEquals({}, stem.descriptor.reader.load_processed_files(''))
 
   @patch('stem.descriptor.reader.open', create = True)
   def test_load_processed_files_no_file(self, open_mock):
@@ -58,8 +58,8 @@ class TestDescriptorReader(unittest.TestCase):
     it is missing the file path.
     """
 
-    open_mock.return_value = io.StringIO(u" 12345")
-    self.assertRaises(TypeError, stem.descriptor.reader.load_processed_files, "")
+    open_mock.return_value = io.StringIO(u' 12345')
+    self.assertRaises(TypeError, stem.descriptor.reader.load_processed_files, '')
 
   @patch('stem.descriptor.reader.open', create = True)
   def test_load_processed_files_no_timestamp(self, open_mock):
@@ -68,8 +68,8 @@ class TestDescriptorReader(unittest.TestCase):
     it is missing the timestamp.
     """
 
-    open_mock.return_value = io.StringIO(u"/dir/file ")
-    self.assertRaises(TypeError, stem.descriptor.reader.load_processed_files, "")
+    open_mock.return_value = io.StringIO(u'/dir/file ')
+    self.assertRaises(TypeError, stem.descriptor.reader.load_processed_files, '')
 
   @patch('stem.descriptor.reader.open', create = True)
   def test_load_processed_files_malformed_file(self, open_mock):
@@ -78,8 +78,8 @@ class TestDescriptorReader(unittest.TestCase):
     it has an invalid file path.
     """
 
-    open_mock.return_value = io.StringIO(u"not_an_absolute_file 12345")
-    self.assertRaises(TypeError, stem.descriptor.reader.load_processed_files, "")
+    open_mock.return_value = io.StringIO(u'not_an_absolute_file 12345')
+    self.assertRaises(TypeError, stem.descriptor.reader.load_processed_files, '')
 
   @patch('stem.descriptor.reader.open', create = True)
   def test_load_processed_files_malformed_timestamp(self, open_mock):
@@ -88,5 +88,5 @@ class TestDescriptorReader(unittest.TestCase):
     it has a non-numeric timestamp.
     """
 
-    open_mock.return_value = io.StringIO(u"/dir/file 123a")
-    self.assertRaises(TypeError, stem.descriptor.reader.load_processed_files, "")
+    open_mock.return_value = io.StringIO(u'/dir/file 123a')
+    self.assertRaises(TypeError, stem.descriptor.reader.load_processed_files, '')
diff --git a/test/unit/descriptor/router_status_entry.py b/test/unit/descriptor/router_status_entry.py
index bf966e9..77b4e20 100644
--- a/test/unit/descriptor/router_status_entry.py
+++ b/test/unit/descriptor/router_status_entry.py
@@ -48,11 +48,11 @@ class TestRouterStatusEntry(unittest.TestCase):
     entry = get_router_status_entry_v2()
 
     self.assertEqual(None, entry.document)
-    self.assertEqual("caerSidi", entry.nickname)
-    self.assertEqual("A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB", entry.fingerprint)
-    self.assertEqual("A106452D87BD7B803B6CE916291ED368DC5BD091", entry.digest)
+    self.assertEqual('caerSidi', entry.nickname)
+    self.assertEqual('A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB', entry.fingerprint)
+    self.assertEqual('A106452D87BD7B803B6CE916291ED368DC5BD091', entry.digest)
     self.assertEqual(datetime.datetime(2012, 8, 6, 11, 19, 31), entry.published)
-    self.assertEqual("71.35.150.29", entry.address)
+    self.assertEqual('71.35.150.29', entry.address)
     self.assertEqual(9001, entry.or_port)
     self.assertEqual(None, entry.dir_port)
     self.assertEqual(None, entry.flags)
@@ -69,11 +69,11 @@ class TestRouterStatusEntry(unittest.TestCase):
 
     expected_flags = set([Flag.FAST, Flag.NAMED, Flag.RUNNING, Flag.STABLE, Flag.VALID])
     self.assertEqual(None, entry.document)
-    self.assertEqual("caerSidi", entry.nickname)
-    self.assertEqual("A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB", entry.fingerprint)
-    self.assertEqual("A106452D87BD7B803B6CE916291ED368DC5BD091", entry.digest)
+    self.assertEqual('caerSidi', entry.nickname)
+    self.assertEqual('A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB', entry.fingerprint)
+    self.assertEqual('A106452D87BD7B803B6CE916291ED368DC5BD091', entry.digest)
     self.assertEqual(datetime.datetime(2012, 8, 6, 11, 19, 31), entry.published)
-    self.assertEqual("71.35.150.29", entry.address)
+    self.assertEqual('71.35.150.29', entry.address)
     self.assertEqual(9001, entry.or_port)
     self.assertEqual(None, entry.dir_port)
     self.assertEqual(expected_flags, set(entry.flags))
@@ -96,16 +96,16 @@ class TestRouterStatusEntry(unittest.TestCase):
 
     expected_flags = set([Flag.FAST, Flag.GUARD, Flag.HSDIR, Flag.NAMED, Flag.RUNNING, Flag.STABLE, Flag.V2DIR, Flag.VALID])
     self.assertEqual(None, entry.document)
-    self.assertEqual("Konata", entry.nickname)
-    self.assertEqual("011209176CDBAA2AC1F48C2C5B4990CE771C5B0C", entry.fingerprint)
+    self.assertEqual('Konata', entry.nickname)
+    self.assertEqual('011209176CDBAA2AC1F48C2C5B4990CE771C5B0C', entry.fingerprint)
     self.assertEqual(datetime.datetime(2012, 9, 24, 13, 40, 40), entry.published)
-    self.assertEqual("69.64.48.168", entry.address)
+    self.assertEqual('69.64.48.168', entry.address)
     self.assertEqual(9001, entry.or_port)
     self.assertEqual(9030, entry.dir_port)
     self.assertEqual(expected_flags, set(entry.flags))
     self.assertEqual(None, entry.version_line)
     self.assertEqual(None, entry.version)
-    self.assertEqual("6A252497006BB9AF36A1B1B902C4D7FA2129923400DBE0101F167B1B031F63BD", entry.digest)
+    self.assertEqual('6A252497006BB9AF36A1B1B902C4D7FA2129923400DBE0101F167B1B031F63BD', entry.digest)
     self.assertEqual([], entry.get_unrecognized_lines())
 
   def test_missing_fields(self):
@@ -114,13 +114,13 @@ class TestRouterStatusEntry(unittest.TestCase):
     """
 
     content = get_router_status_entry_v3(exclude = ('r', 's'), content = True)
-    self._expect_invalid_attr(content, "address")
+    self._expect_invalid_attr(content, 'address')
 
     content = get_router_status_entry_v3(exclude = ('r',), content = True)
-    self._expect_invalid_attr(content, "address")
+    self._expect_invalid_attr(content, 'address')
 
     content = get_router_status_entry_v3(exclude = ('s',), content = True)
-    self._expect_invalid_attr(content, "flags")
+    self._expect_invalid_attr(content, 'flags')
 
   def test_unrecognized_lines(self):
     """
@@ -136,30 +136,30 @@ class TestRouterStatusEntry(unittest.TestCase):
     """
 
     content = b'z some stuff\n' + get_router_status_entry_v3(content = True)
-    self._expect_invalid_attr(content, "_unrecognized_lines", ['z some stuff'])
+    self._expect_invalid_attr(content, '_unrecognized_lines', ['z some stuff'])
 
   def test_blank_lines(self):
     """
     Includes blank lines, which should be ignored.
     """
 
-    content = get_router_status_entry_v3(content = True) + b"\n\nv Tor 0.2.2.35\n\n"
+    content = get_router_status_entry_v3(content = True) + b'\n\nv Tor 0.2.2.35\n\n'
     entry = RouterStatusEntryV3(content)
-    self.assertEqual("Tor 0.2.2.35", entry.version_line)
+    self.assertEqual('Tor 0.2.2.35', entry.version_line)
 
   def test_duplicate_lines(self):
     """
     Duplicates linesin the entry.
     """
 
-    lines = get_router_status_entry_v3(content = True).split(b"\n")
+    lines = get_router_status_entry_v3(content = True).split(b'\n')
 
     for index, duplicate_line in enumerate(lines):
-      content = b"\n".join(lines[:index] + [duplicate_line] + lines[index:])
+      content = b'\n'.join(lines[:index] + [duplicate_line] + lines[index:])
       self.assertRaises(ValueError, RouterStatusEntryV3, content)
 
       entry = RouterStatusEntryV3(content, False)
-      self.assertEqual("caerSidi", entry.nickname)
+      self.assertEqual('caerSidi', entry.nickname)
 
   def test_missing_r_field(self):
     """
@@ -191,13 +191,13 @@ class TestRouterStatusEntry(unittest.TestCase):
     """
 
     test_values = (
-      "",
-      "saberrider2008ReallyLongNickname",  # too long
-      "$aberrider2008",  # invalid characters
+      '',
+      'saberrider2008ReallyLongNickname',  # too long
+      '$aberrider2008',  # invalid characters
     )
 
     for value in test_values:
-      r_line = ROUTER_STATUS_ENTRY_V3_HEADER[0][1].replace("caerSidi", value)
+      r_line = ROUTER_STATUS_ENTRY_V3_HEADER[0][1].replace('caerSidi', value)
       content = get_router_status_entry_v3({'r': r_line}, content = True)
 
       # TODO: Initial whitespace is consumed as part of the keyword/value
@@ -210,10 +210,10 @@ class TestRouterStatusEntry(unittest.TestCase):
       # is that our validation doesn't catch the new SP restriction on V3
       # entries.
 
-      if value == "":
+      if value == '':
         value = None
 
-      self._expect_invalid_attr(content, "nickname", value)
+      self._expect_invalid_attr(content, 'nickname', value)
 
   def test_malformed_fingerprint(self):
     """
@@ -221,15 +221,15 @@ class TestRouterStatusEntry(unittest.TestCase):
     """
 
     test_values = (
-      "",
-      "zzzzz",
-      "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",
+      '',
+      'zzzzz',
+      'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz',
     )
 
     for value in test_values:
-      r_line = ROUTER_STATUS_ENTRY_V3_HEADER[0][1].replace("p1aag7VwarGxqctS7/fS0y5FU+s", value)
+      r_line = ROUTER_STATUS_ENTRY_V3_HEADER[0][1].replace('p1aag7VwarGxqctS7/fS0y5FU+s', value)
       content = get_router_status_entry_v3({'r': r_line}, content = True)
-      self._expect_invalid_attr(content, "fingerprint")
+      self._expect_invalid_attr(content, 'fingerprint')
 
   def test_malformed_published_date(self):
     """
@@ -237,25 +237,25 @@ class TestRouterStatusEntry(unittest.TestCase):
     """
 
     test_values = (
-      "",
-      "2012-08-06 11:19:",
-      "2012-08-06 11:19:71",
-      "2012-08-06 11::31",
-      "2012-08-06 11:79:31",
-      "2012-08-06 :19:31",
-      "2012-08-06 41:19:31",
-      "2012-08- 11:19:31",
-      "2012-08-86 11:19:31",
-      "2012--06 11:19:31",
-      "2012-38-06 11:19:31",
-      "-08-06 11:19:31",
-      "2012-08-06   11:19:31",
+      '',
+      '2012-08-06 11:19:',
+      '2012-08-06 11:19:71',
+      '2012-08-06 11::31',
+      '2012-08-06 11:79:31',
+      '2012-08-06 :19:31',
+      '2012-08-06 41:19:31',
+      '2012-08- 11:19:31',
+      '2012-08-86 11:19:31',
+      '2012--06 11:19:31',
+      '2012-38-06 11:19:31',
+      '-08-06 11:19:31',
+      '2012-08-06   11:19:31',
     )
 
     for value in test_values:
-      r_line = ROUTER_STATUS_ENTRY_V3_HEADER[0][1].replace("2012-08-06 11:19:31", value)
+      r_line = ROUTER_STATUS_ENTRY_V3_HEADER[0][1].replace('2012-08-06 11:19:31', value)
       content = get_router_status_entry_v3({'r': r_line}, content = True)
-      self._expect_invalid_attr(content, "published")
+      self._expect_invalid_attr(content, 'published')
 
   def test_malformed_address(self):
     """
@@ -263,17 +263,17 @@ class TestRouterStatusEntry(unittest.TestCase):
     """
 
     test_values = (
-      "",
-      "71.35.150.",
-      "71.35..29",
-      "71.35.150",
-      "71.35.150.256",
+      '',
+      '71.35.150.',
+      '71.35..29',
+      '71.35.150',
+      '71.35.150.256',
     )
 
     for value in test_values:
-      r_line = ROUTER_STATUS_ENTRY_V3_HEADER[0][1].replace("71.35.150.29", value)
+      r_line = ROUTER_STATUS_ENTRY_V3_HEADER[0][1].replace('71.35.150.29', value)
       content = get_router_status_entry_v3({'r': r_line}, content = True)
-      self._expect_invalid_attr(content, "address", value)
+      self._expect_invalid_attr(content, 'address', value)
 
   def test_malformed_port(self):
     """
@@ -281,10 +281,10 @@ class TestRouterStatusEntry(unittest.TestCase):
     """
 
     test_values = (
-      "",
-      "-1",
-      "399482",
-      "blarg",
+      '',
+      '-1',
+      '399482',
+      'blarg',
     )
 
     for value in test_values:
@@ -296,12 +296,12 @@ class TestRouterStatusEntry(unittest.TestCase):
           r_line = ROUTER_STATUS_ENTRY_V3_HEADER[0][1]
 
           if include_or_port:
-            r_line = r_line.replace(" 9001 ", " %s " % value)
+            r_line = r_line.replace(' 9001 ', ' %s ' % value)
 
           if include_dir_port:
             r_line = r_line[:-1] + value
 
-          attr = "or_port" if include_or_port else "dir_port"
+          attr = 'or_port' if include_or_port else 'dir_port'
           expected = int(value) if value.isdigit() else None
 
           content = get_router_status_entry_v3({'r': r_line}, content = True)
@@ -313,7 +313,7 @@ class TestRouterStatusEntry(unittest.TestCase):
     """
 
     test_values = {
-      "[2607:fcd0:daaa:101::602c:bd62]:443": [
+      '[2607:fcd0:daaa:101::602c:bd62]:443': [
         ('2607:fcd0:daaa:101::602c:bd62', 443, True)],
     }
 
@@ -324,8 +324,8 @@ class TestRouterStatusEntry(unittest.TestCase):
     # includes multiple 'a' lines
 
     content = get_router_status_entry_v3(content = True)
-    content += b"\na [2607:fcd0:daaa:101::602c:bd62]:443"
-    content += b"\na [1148:fcd0:daaa:101::602c:bd62]:80"
+    content += b'\na [2607:fcd0:daaa:101::602c:bd62]:443'
+    content += b'\na [1148:fcd0:daaa:101::602c:bd62]:80'
 
     expected = [
       ('2607:fcd0:daaa:101::602c:bd62', 443, True),
@@ -338,8 +338,8 @@ class TestRouterStatusEntry(unittest.TestCase):
     # tries some invalid inputs
 
     test_values = (
-      "",
-      "[1148:fcd0:daaa:101::602c:bd62]:80000",
+      '',
+      '[1148:fcd0:daaa:101::602c:bd62]:80000',
     )
 
     for a_line in test_values:
@@ -352,10 +352,10 @@ class TestRouterStatusEntry(unittest.TestCase):
     """
 
     test_values = {
-      "": [],
-      "Fast": [Flag.FAST],
-      "Fast Valid": [Flag.FAST, Flag.VALID],
-      "Ugabuga": ["Ugabuga"],
+      '': [],
+      'Fast': [Flag.FAST],
+      'Fast Valid': [Flag.FAST, Flag.VALID],
+      'Ugabuga': ['Ugabuga'],
     }
 
     for s_line, expected in test_values.items():
@@ -364,14 +364,14 @@ class TestRouterStatusEntry(unittest.TestCase):
 
     # tries some invalid inputs
     test_values = {
-      "Fast   ": [Flag.FAST, "", "", ""],
-      "Fast  Valid": [Flag.FAST, "", Flag.VALID],
-      "Fast Fast": [Flag.FAST, Flag.FAST],
+      'Fast   ': [Flag.FAST, '', '', ''],
+      'Fast  Valid': [Flag.FAST, '', Flag.VALID],
+      'Fast Fast': [Flag.FAST, Flag.FAST],
     }
 
     for s_line, expected in test_values.items():
       content = get_router_status_entry_v3({'s': s_line}, content = True)
-      self._expect_invalid_attr(content, "flags", expected)
+      self._expect_invalid_attr(content, 'flags', expected)
 
   def test_versions(self):
     """
@@ -379,10 +379,10 @@ class TestRouterStatusEntry(unittest.TestCase):
     """
 
     test_values = {
-      "Tor 0.2.2.35": Version("0.2.2.35"),
-      "Tor 0.1.2": Version("0.1.2"),
-      "Torr new_stuff": None,
-      "new_stuff and stuff": None,
+      'Tor 0.2.2.35': Version('0.2.2.35'),
+      'Tor 0.1.2': Version('0.1.2'),
+      'Torr new_stuff': None,
+      'new_stuff and stuff': None,
     }
 
     for v_line, expected in test_values.items():
@@ -391,8 +391,8 @@ class TestRouterStatusEntry(unittest.TestCase):
       self.assertEquals(v_line, entry.version_line)
 
     # tries an invalid input
-    content = get_router_status_entry_v3({'v': "Tor ugabuga"}, content = True)
-    self._expect_invalid_attr(content, "version")
+    content = get_router_status_entry_v3({'v': 'Tor ugabuga'}, content = True)
+    self._expect_invalid_attr(content, 'version')
 
   def test_bandwidth(self):
     """
@@ -400,11 +400,11 @@ class TestRouterStatusEntry(unittest.TestCase):
     """
 
     test_values = {
-      "Bandwidth=0": (0, None, False, []),
-      "Bandwidth=63138": (63138, None, False, []),
-      "Bandwidth=11111 Measured=482": (11111, 482, False, []),
-      "Bandwidth=11111 Measured=482 Blarg!": (11111, 482, False, ["Blarg!"]),
-      "Bandwidth=11111 Measured=482 Unmeasured=1 Blarg!": (11111, 482, True, ["Blarg!"]),
+      'Bandwidth=0': (0, None, False, []),
+      'Bandwidth=63138': (63138, None, False, []),
+      'Bandwidth=11111 Measured=482': (11111, 482, False, []),
+      'Bandwidth=11111 Measured=482 Blarg!': (11111, 482, False, ['Blarg!']),
+      'Bandwidth=11111 Measured=482 Unmeasured=1 Blarg!': (11111, 482, True, ['Blarg!']),
     }
 
     for w_line, expected in test_values.items():
@@ -416,21 +416,21 @@ class TestRouterStatusEntry(unittest.TestCase):
 
     # tries some invalid inputs
     test_values = (
-      "",
-      "blarg",
-      "Bandwidth",
-      "Bandwidth=",
-      "Bandwidth:0",
-      "Bandwidth 0",
-      "Bandwidth=-10",
-      "Bandwidth=10 Measured",
-      "Bandwidth=10 Measured=",
-      "Bandwidth=10 Measured=-50",
-      "Bandwidth=10 Measured=482 Unmeasured",
-      "Bandwidth=10 Measured=482 Unmeasured=",
-      "Bandwidth=10 Measured=482 Unmeasured=0",
-      "Bandwidth=10 Measured=482 Unmeasured=842",
-      "Bandwidth=10 Measured=482 Unmeasured=-5",
+      '',
+      'blarg',
+      'Bandwidth',
+      'Bandwidth=',
+      'Bandwidth:0',
+      'Bandwidth 0',
+      'Bandwidth=-10',
+      'Bandwidth=10 Measured',
+      'Bandwidth=10 Measured=',
+      'Bandwidth=10 Measured=-50',
+      'Bandwidth=10 Measured=482 Unmeasured',
+      'Bandwidth=10 Measured=482 Unmeasured=',
+      'Bandwidth=10 Measured=482 Unmeasured=0',
+      'Bandwidth=10 Measured=482 Unmeasured=842',
+      'Bandwidth=10 Measured=482 Unmeasured=-5',
     )
 
     for w_line in test_values:
@@ -443,8 +443,8 @@ class TestRouterStatusEntry(unittest.TestCase):
     """
 
     test_values = {
-      "reject 1-65535": MicroExitPolicy("reject 1-65535"),
-      "accept 80,110,143,443": MicroExitPolicy("accept 80,110,143,443"),
+      'reject 1-65535': MicroExitPolicy('reject 1-65535'),
+      'accept 80,110,143,443': MicroExitPolicy('accept 80,110,143,443'),
     }
 
     for p_line, expected in test_values.items():
@@ -453,15 +453,15 @@ class TestRouterStatusEntry(unittest.TestCase):
 
     # tries some invalid inputs
     test_values = (
-      "",
-      "blarg",
-      "reject -50",
-      "accept 80,",
+      '',
+      'blarg',
+      'reject -50',
+      'accept 80,',
     )
 
     for p_line in test_values:
       content = get_router_status_entry_v3({'p': p_line}, content = True)
-      self._expect_invalid_attr(content, "exit_policy")
+      self._expect_invalid_attr(content, 'exit_policy')
 
   def test_microdescriptor_hashes(self):
     """
@@ -469,18 +469,18 @@ class TestRouterStatusEntry(unittest.TestCase):
     """
 
     test_values = {
-      "8,9,10,11,12":
+      '8,9,10,11,12':
         [([8, 9, 10, 11, 12], {})],
-      "8,9,10,11,12 sha256=g1vx9si329muxV3tquWIXXySNOIwRGMeAESKs/v4DWs":
-        [([8, 9, 10, 11, 12], {"sha256": "g1vx9si329muxV3tquWIXXySNOIwRGMeAESKs/v4DWs"})],
-      "8,9,10,11,12 sha256=g1vx9si329muxV md5=3tquWIXXySNOIwRGMeAESKs/v4DWs":
-        [([8, 9, 10, 11, 12], {"sha256": "g1vx9si329muxV", "md5": "3tquWIXXySNOIwRGMeAESKs/v4DWs"})],
+      '8,9,10,11,12 sha256=g1vx9si329muxV3tquWIXXySNOIwRGMeAESKs/v4DWs':
+        [([8, 9, 10, 11, 12], {'sha256': 'g1vx9si329muxV3tquWIXXySNOIwRGMeAESKs/v4DWs'})],
+      '8,9,10,11,12 sha256=g1vx9si329muxV md5=3tquWIXXySNOIwRGMeAESKs/v4DWs':
+        [([8, 9, 10, 11, 12], {'sha256': 'g1vx9si329muxV', 'md5': '3tquWIXXySNOIwRGMeAESKs/v4DWs'})],
     }
 
     # we need a document that's a vote
     mock_document = lambda x: x  # just need anything with a __dict__
-    setattr(mock_document, "is_vote", True)
-    setattr(mock_document, "is_consensus", False)
+    setattr(mock_document, 'is_vote', True)
+    setattr(mock_document, 'is_consensus', False)
 
     for m_line, expected in test_values.items():
       content = get_router_status_entry_v3({'m': m_line}, content = True)
@@ -490,26 +490,26 @@ class TestRouterStatusEntry(unittest.TestCase):
     # try with multiple 'm' lines
 
     content = get_router_status_entry_v3(content = True)
-    content += b"\nm 11,12 sha256=g1vx9si329muxV3tquWIXXySNOIwRGMeAESKs/v4DWs"
-    content += b"\nm 31,32 sha512=g1vx9si329muxV3tquWIXXySNOIwRGMeAESKs/v4DWs"
+    content += b'\nm 11,12 sha256=g1vx9si329muxV3tquWIXXySNOIwRGMeAESKs/v4DWs'
+    content += b'\nm 31,32 sha512=g1vx9si329muxV3tquWIXXySNOIwRGMeAESKs/v4DWs'
 
     expected = [
-      ([11, 12], {"sha256": "g1vx9si329muxV3tquWIXXySNOIwRGMeAESKs/v4DWs"}),
-      ([31, 32], {"sha512": "g1vx9si329muxV3tquWIXXySNOIwRGMeAESKs/v4DWs"}),
+      ([11, 12], {'sha256': 'g1vx9si329muxV3tquWIXXySNOIwRGMeAESKs/v4DWs'}),
+      ([31, 32], {'sha512': 'g1vx9si329muxV3tquWIXXySNOIwRGMeAESKs/v4DWs'}),
     ]
 
     entry = RouterStatusEntryV3(content, document = mock_document)
     self.assertEquals(expected, entry.microdescriptor_hashes)
 
     # try without a document
-    content = get_router_status_entry_v3({'m': "8,9,10,11,12"}, content = True)
-    self._expect_invalid_attr(content, "microdescriptor_hashes", expected_value = [])
+    content = get_router_status_entry_v3({'m': '8,9,10,11,12'}, content = True)
+    self._expect_invalid_attr(content, 'microdescriptor_hashes', expected_value = [])
 
     # tries some invalid inputs
     test_values = (
-      "",
-      "4,a,2",
-      "1,2,3 stuff",
+      '',
+      '4,a,2',
+      '1,2,3 stuff',
     )
 
     for m_line in test_values:
@@ -529,4 +529,4 @@ class TestRouterStatusEntry(unittest.TestCase):
     if attr:
       self.assertEquals(expected_value, getattr(entry, attr))
     else:
-      self.assertEquals("caerSidi", entry.nickname)
+      self.assertEquals('caerSidi', entry.nickname)
diff --git a/test/unit/descriptor/server_descriptor.py b/test/unit/descriptor/server_descriptor.py
index 6308535..c51de06 100644
--- a/test/unit/descriptor/server_descriptor.py
+++ b/test/unit/descriptor/server_descriptor.py
@@ -35,8 +35,8 @@ class TestServerDescriptor(unittest.TestCase):
 
     desc = get_relay_server_descriptor()
 
-    self.assertEquals("caerSidi", desc.nickname)
-    self.assertEquals("71.35.133.197", desc.address)
+    self.assertEquals('caerSidi', desc.nickname)
+    self.assertEquals('71.35.133.197', desc.address)
     self.assertEquals(None, desc.fingerprint)
     self.assertTrue(CRYPTO_BLOB in desc.onion_key)
 
@@ -46,8 +46,8 @@ class TestServerDescriptor(unittest.TestCase):
     Includes an 'opt <keyword> <value>' entry.
     """
 
-    desc = get_relay_server_descriptor({"opt": "contact www.atagar.com/contact/"})
-    self.assertEquals(b"www.atagar.com/contact/", desc.contact)
+    desc = get_relay_server_descriptor({'opt': 'contact www.atagar.com/contact/'})
+    self.assertEquals(b'www.atagar.com/contact/', desc.contact)
 
   @patch('stem.descriptor.server_descriptor.RelayDescriptor._verify_digest', Mock())
   def test_unrecognized_line(self):
@@ -55,15 +55,15 @@ class TestServerDescriptor(unittest.TestCase):
     Includes unrecognized content in the descriptor.
     """
 
-    desc = get_relay_server_descriptor({"pepperjack": "is oh so tasty!"})
-    self.assertEquals(["pepperjack is oh so tasty!"], desc.get_unrecognized_lines())
+    desc = get_relay_server_descriptor({'pepperjack': 'is oh so tasty!'})
+    self.assertEquals(['pepperjack is oh so tasty!'], desc.get_unrecognized_lines())
 
   def test_proceeding_line(self):
     """
     Includes a line prior to the 'router' entry.
     """
 
-    desc_text = b"hibernate 1\n" + get_relay_server_descriptor(content = True)
+    desc_text = b'hibernate 1\n' + get_relay_server_descriptor(content = True)
     self._expect_invalid_attr(desc_text)
 
   def test_trailing_line(self):
@@ -71,7 +71,7 @@ class TestServerDescriptor(unittest.TestCase):
     Includes a line after the 'router-signature' entry.
     """
 
-    desc_text = get_relay_server_descriptor(content = True) + b"\nhibernate 1"
+    desc_text = get_relay_server_descriptor(content = True) + b'\nhibernate 1'
     self._expect_invalid_attr(desc_text)
 
   def test_nickname_missing(self):
@@ -79,70 +79,70 @@ class TestServerDescriptor(unittest.TestCase):
     Constructs with a malformed router entry.
     """
 
-    desc_text = get_relay_server_descriptor({"router": " 71.35.133.197 9001 0 0"}, content = True)
-    self._expect_invalid_attr(desc_text, "nickname")
+    desc_text = get_relay_server_descriptor({'router': ' 71.35.133.197 9001 0 0'}, content = True)
+    self._expect_invalid_attr(desc_text, 'nickname')
 
   def test_nickname_too_long(self):
     """
     Constructs with a nickname that is an invalid length.
     """
 
-    desc_text = get_relay_server_descriptor({"router": "saberrider2008ReallyLongNickname 71.35.133.197 9001 0 0"}, content = True)
-    self._expect_invalid_attr(desc_text, "nickname", "saberrider2008ReallyLongNickname")
+    desc_text = get_relay_server_descriptor({'router': 'saberrider2008ReallyLongNickname 71.35.133.197 9001 0 0'}, content = True)
+    self._expect_invalid_attr(desc_text, 'nickname', 'saberrider2008ReallyLongNickname')
 
   def test_nickname_invalid_char(self):
     """
     Constructs with an invalid relay nickname.
     """
 
-    desc_text = get_relay_server_descriptor({"router": "$aberrider2008 71.35.133.197 9001 0 0"}, content = True)
-    self._expect_invalid_attr(desc_text, "nickname", "$aberrider2008")
+    desc_text = get_relay_server_descriptor({'router': '$aberrider2008 71.35.133.197 9001 0 0'}, content = True)
+    self._expect_invalid_attr(desc_text, 'nickname', '$aberrider2008')
 
   def test_address_malformed(self):
     """
     Constructs with an invalid ip address.
     """
 
-    desc_text = get_relay_server_descriptor({"router": "caerSidi 371.35.133.197 9001 0 0"}, content = True)
-    self._expect_invalid_attr(desc_text, "address", "371.35.133.197")
+    desc_text = get_relay_server_descriptor({'router': 'caerSidi 371.35.133.197 9001 0 0'}, content = True)
+    self._expect_invalid_attr(desc_text, 'address', '371.35.133.197')
 
   def test_port_too_high(self):
     """
     Constructs with an ORPort that is too large.
     """
 
-    desc_text = get_relay_server_descriptor({"router": "caerSidi 71.35.133.197 900001 0 0"}, content = True)
-    self._expect_invalid_attr(desc_text, "or_port", 900001)
+    desc_text = get_relay_server_descriptor({'router': 'caerSidi 71.35.133.197 900001 0 0'}, content = True)
+    self._expect_invalid_attr(desc_text, 'or_port', 900001)
 
   def test_port_malformed(self):
     """
     Constructs with an ORPort that isn't numeric.
     """
 
-    desc_text = get_relay_server_descriptor({"router": "caerSidi 71.35.133.197 900a1 0 0"}, content = True)
-    self._expect_invalid_attr(desc_text, "or_port")
+    desc_text = get_relay_server_descriptor({'router': 'caerSidi 71.35.133.197 900a1 0 0'}, content = True)
+    self._expect_invalid_attr(desc_text, 'or_port')
 
   def test_port_newline(self):
     """
     Constructs with a newline replacing the ORPort.
     """
 
-    desc_text = get_relay_server_descriptor({"router": "caerSidi 71.35.133.197 \n 0 0"}, content = True)
-    self._expect_invalid_attr(desc_text, "or_port")
+    desc_text = get_relay_server_descriptor({'router': 'caerSidi 71.35.133.197 \n 0 0'}, content = True)
+    self._expect_invalid_attr(desc_text, 'or_port')
 
   def test_platform_empty(self):
     """
     Constructs with an empty platform entry.
     """
 
-    desc_text = get_relay_server_descriptor({"platform": ""}, content = True)
+    desc_text = get_relay_server_descriptor({'platform': ''}, content = True)
     desc = RelayDescriptor(desc_text, validate = False)
-    self.assertEquals(b"", desc.platform)
+    self.assertEquals(b'', desc.platform)
 
     # does the same but with 'platform ' replaced with 'platform'
-    desc_text = desc_text.replace(b"platform ", b"platform")
+    desc_text = desc_text.replace(b'platform ', b'platform')
     desc = RelayDescriptor(desc_text, validate = False)
-    self.assertEquals(b"", desc.platform)
+    self.assertEquals(b'', desc.platform)
 
   @patch('stem.descriptor.server_descriptor.RelayDescriptor._verify_digest', Mock())
   def test_platform_for_node_tor(self):
@@ -150,18 +150,18 @@ class TestServerDescriptor(unittest.TestCase):
     Parse a platform line belonging to a node-Tor relay.
     """
 
-    desc = get_relay_server_descriptor({"platform": "node-Tor 0.1.0 on Linux x86_64"})
-    self.assertEquals(b"node-Tor 0.1.0 on Linux x86_64", desc.platform)
-    self.assertEquals(stem.version.Version("0.1.0"), desc.tor_version)
-    self.assertEquals("Linux x86_64", desc.operating_system)
+    desc = get_relay_server_descriptor({'platform': 'node-Tor 0.1.0 on Linux x86_64'})
+    self.assertEquals(b'node-Tor 0.1.0 on Linux x86_64', desc.platform)
+    self.assertEquals(stem.version.Version('0.1.0'), desc.tor_version)
+    self.assertEquals('Linux x86_64', desc.operating_system)
 
   def test_protocols_no_circuit_versions(self):
     """
     Constructs with a protocols line without circuit versions.
     """
 
-    desc_text = get_relay_server_descriptor({"opt": "protocols Link 1 2"}, content = True)
-    self._expect_invalid_attr(desc_text, "circuit_protocols")
+    desc_text = get_relay_server_descriptor({'opt': 'protocols Link 1 2'}, content = True)
+    self._expect_invalid_attr(desc_text, 'circuit_protocols')
 
   @patch('stem.descriptor.server_descriptor.RelayDescriptor._verify_digest', Mock())
   def test_published_leap_year(self):
@@ -170,10 +170,10 @@ class TestServerDescriptor(unittest.TestCase):
     invalid.
     """
 
-    desc_text = get_relay_server_descriptor({"published": "2011-02-29 04:03:19"}, content = True)
-    self._expect_invalid_attr(desc_text, "published")
+    desc_text = get_relay_server_descriptor({'published': '2011-02-29 04:03:19'}, content = True)
+    self._expect_invalid_attr(desc_text, 'published')
 
-    desc_text = get_relay_server_descriptor({"published": "2012-02-29 04:03:19"}, content = True)
+    desc_text = get_relay_server_descriptor({'published': '2012-02-29 04:03:19'}, content = True)
     expected_published = datetime.datetime(2012, 2, 29, 4, 3, 19)
     self.assertEquals(expected_published, RelayDescriptor(desc_text).published)
 
@@ -182,8 +182,8 @@ class TestServerDescriptor(unittest.TestCase):
     Constructs with a published entry without a time component.
     """
 
-    desc_text = get_relay_server_descriptor({"published": "2012-01-01"}, content = True)
-    self._expect_invalid_attr(desc_text, "published")
+    desc_text = get_relay_server_descriptor({'published': '2012-01-01'}, content = True)
+    self._expect_invalid_attr(desc_text, 'published')
 
   @patch('stem.descriptor.server_descriptor.RelayDescriptor._verify_digest', Mock())
   def test_read_and_write_history(self):
@@ -193,11 +193,11 @@ class TestServerDescriptor(unittest.TestCase):
     extra-info descriptors.
     """
 
-    for field in ("read-history", "write-history"):
-      value = "2005-12-16 18:00:48 (900 s) 81,8848,8927,8927,83,8848"
-      desc = get_relay_server_descriptor({"opt %s" % field: value})
+    for field in ('read-history', 'write-history'):
+      value = '2005-12-16 18:00:48 (900 s) 81,8848,8927,8927,83,8848'
+      desc = get_relay_server_descriptor({'opt %s' % field: value})
 
-      if field == "read-history":
+      if field == 'read-history':
         attr = (desc.read_history_end, desc.read_history_interval, desc.read_history_values)
       else:
         attr = (desc.write_history_end, desc.write_history_interval, desc.write_history_values)
@@ -215,8 +215,8 @@ class TestServerDescriptor(unittest.TestCase):
     Parses a read-history with an empty value.
     """
 
-    value = "2005-12-17 01:23:11 (900 s) "
-    desc = get_relay_server_descriptor({"opt read-history": value})
+    value = '2005-12-17 01:23:11 (900 s) '
+    desc = get_relay_server_descriptor({'opt read-history': value})
     self.assertEquals(datetime.datetime(2005, 12, 17, 1, 23, 11), desc.read_history_end)
     self.assertEquals(900, desc.read_history_interval)
     self.assertEquals([], desc.read_history_values)
@@ -227,15 +227,15 @@ class TestServerDescriptor(unittest.TestCase):
     Checks that content before a descriptor are parsed as annotations.
     """
 
-    desc_text = b"@pepperjack very tasty\n@mushrooms not so much\n"
+    desc_text = b'@pepperjack very tasty\n@mushrooms not so much\n'
     desc_text += get_relay_server_descriptor(content = True)
-    desc_text += b"\ntrailing text that should be invalid, ho hum"
+    desc_text += b'\ntrailing text that should be invalid, ho hum'
 
     # running _parse_file should provide an iterator with a single descriptor
     desc_iter = stem.descriptor.server_descriptor._parse_file(io.BytesIO(desc_text))
     self.assertRaises(ValueError, list, desc_iter)
 
-    desc_text = b"@pepperjack very tasty\n@mushrooms not so much\n"
+    desc_text = b'@pepperjack very tasty\n@mushrooms not so much\n'
     desc_text += get_relay_server_descriptor(content = True)
     desc_iter = stem.descriptor.server_descriptor._parse_file(io.BytesIO(desc_text))
 
@@ -243,10 +243,10 @@ class TestServerDescriptor(unittest.TestCase):
     self.assertEquals(1, len(desc_entries))
     desc = desc_entries[0]
 
-    self.assertEquals("caerSidi", desc.nickname)
-    self.assertEquals(b"@pepperjack very tasty", desc.get_annotation_lines()[0])
-    self.assertEquals(b"@mushrooms not so much", desc.get_annotation_lines()[1])
-    self.assertEquals({b"@pepperjack": b"very tasty", b"@mushrooms": b"not so much"}, desc.get_annotations())
+    self.assertEquals('caerSidi', desc.nickname)
+    self.assertEquals(b'@pepperjack very tasty', desc.get_annotation_lines()[0])
+    self.assertEquals(b'@mushrooms not so much', desc.get_annotation_lines()[1])
+    self.assertEquals({b'@pepperjack': b'very tasty', b'@mushrooms': b'not so much'}, desc.get_annotations())
     self.assertEquals([], desc.get_unrecognized_lines())
 
   def test_duplicate_field(self):
@@ -254,9 +254,9 @@ class TestServerDescriptor(unittest.TestCase):
     Constructs with a field appearing twice.
     """
 
-    desc_text = get_relay_server_descriptor({"<replace>": ""}, content = True)
-    desc_text = desc_text.replace(b"<replace>", b"contact foo\ncontact bar")
-    self._expect_invalid_attr(desc_text, "contact", b"foo")
+    desc_text = get_relay_server_descriptor({'<replace>': ''}, content = True)
+    desc_text = desc_text.replace(b'<replace>', b'contact foo\ncontact bar')
+    self._expect_invalid_attr(desc_text, 'contact', b'foo')
 
   def test_missing_required_attr(self):
     """
@@ -271,7 +271,7 @@ class TestServerDescriptor(unittest.TestCase):
       desc = RelayDescriptor(desc_text, validate = False)
 
       # for one of them checks that the corresponding values are None
-      if attr == "router":
+      if attr == 'router':
         self.assertEquals(None, desc.nickname)
         self.assertEquals(None, desc.address)
         self.assertEquals(None, desc.or_port)
@@ -284,9 +284,9 @@ class TestServerDescriptor(unittest.TestCase):
     it doesn't match the hash of our signing key.
     """
 
-    fingerprint = "4F0C 867D F0EF 6816 0568 C826 838F 482C EA7C FE45"
-    desc_text = get_relay_server_descriptor({"opt fingerprint": fingerprint}, content = True)
-    self._expect_invalid_attr(desc_text, "fingerprint", fingerprint.replace(" ", ""))
+    fingerprint = '4F0C 867D F0EF 6816 0568 C826 838F 482C EA7C FE45'
+    desc_text = get_relay_server_descriptor({'opt fingerprint': fingerprint}, content = True)
+    self._expect_invalid_attr(desc_text, 'fingerprint', fingerprint.replace(' ', ''))
 
   @patch('stem.descriptor.server_descriptor.RelayDescriptor._verify_digest', Mock())
   def test_ipv6_policy(self):
@@ -294,8 +294,8 @@ class TestServerDescriptor(unittest.TestCase):
     Checks a 'ipv6-policy' line.
     """
 
-    expected = stem.exit_policy.MicroExitPolicy("accept 22-23,53,80,110")
-    desc = get_relay_server_descriptor({"ipv6-policy": "accept 22-23,53,80,110"})
+    expected = stem.exit_policy.MicroExitPolicy('accept 22-23,53,80,110')
+    desc = get_relay_server_descriptor({'ipv6-policy': 'accept 22-23,53,80,110'})
     self.assertEquals(expected, desc.exit_policy_v6)
 
   @patch('stem.descriptor.server_descriptor.RelayDescriptor._verify_digest', Mock())
@@ -304,8 +304,8 @@ class TestServerDescriptor(unittest.TestCase):
     Checks a 'ntor-onion-key' line.
     """
 
-    desc = get_relay_server_descriptor({"ntor-onion-key": "Od2Sj3UXFyDjwESLXk6fhatqW9z/oBL/vAKJ+tbDqUU="})
-    self.assertEquals("Od2Sj3UXFyDjwESLXk6fhatqW9z/oBL/vAKJ+tbDqUU=", desc.ntor_onion_key)
+    desc = get_relay_server_descriptor({'ntor-onion-key': 'Od2Sj3UXFyDjwESLXk6fhatqW9z/oBL/vAKJ+tbDqUU='})
+    self.assertEquals('Od2Sj3UXFyDjwESLXk6fhatqW9z/oBL/vAKJ+tbDqUU=', desc.ntor_onion_key)
 
   def test_minimal_bridge_descriptor(self):
     """
@@ -314,15 +314,15 @@ class TestServerDescriptor(unittest.TestCase):
 
     desc = get_bridge_server_descriptor()
 
-    self.assertEquals("Unnamed", desc.nickname)
-    self.assertEquals("10.45.227.253", desc.address)
+    self.assertEquals('Unnamed', desc.nickname)
+    self.assertEquals('10.45.227.253', desc.address)
     self.assertEquals(None, desc.fingerprint)
-    self.assertEquals("006FD96BA35E7785A6A3B8B75FE2E2435A13BDB4", desc.digest())
+    self.assertEquals('006FD96BA35E7785A6A3B8B75FE2E2435A13BDB4', desc.digest())
 
     # check that we don't have crypto fields
-    self.assertRaises(AttributeError, getattr, desc, "onion_key")
-    self.assertRaises(AttributeError, getattr, desc, "signing_key")
-    self.assertRaises(AttributeError, getattr, desc, "signature")
+    self.assertRaises(AttributeError, getattr, desc, 'onion_key')
+    self.assertRaises(AttributeError, getattr, desc, 'signing_key')
+    self.assertRaises(AttributeError, getattr, desc, 'signature')
 
   def test_bridge_unsanitized(self):
     """
@@ -330,13 +330,13 @@ class TestServerDescriptor(unittest.TestCase):
     """
 
     unsanitized_attr = [
-      {"router": "Unnamed 75.45.227.253 9001 0 0"},
-      {"contact": "Damian"},
-      {"or-address": "71.35.133.197:9001"},
-      {"or-address": "[12ab:2e19:3bcf::02:9970]:9001"},
-      {"onion-key": "\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----" % CRYPTO_BLOB},
-      {"signing-key": "\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----" % CRYPTO_BLOB},
-      {"router-signature": "\n-----BEGIN SIGNATURE-----%s-----END SIGNATURE-----" % CRYPTO_BLOB},
+      {'router': 'Unnamed 75.45.227.253 9001 0 0'},
+      {'contact': 'Damian'},
+      {'or-address': '71.35.133.197:9001'},
+      {'or-address': '[12ab:2e19:3bcf::02:9970]:9001'},
+      {'onion-key': '\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----' % CRYPTO_BLOB},
+      {'signing-key': '\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----' % CRYPTO_BLOB},
+      {'router-signature': '\n-----BEGIN SIGNATURE-----%s-----END SIGNATURE-----' % CRYPTO_BLOB},
     ]
 
     for attr in unsanitized_attr:
@@ -349,7 +349,7 @@ class TestServerDescriptor(unittest.TestCase):
     its unsanatized content.
     """
 
-    desc_text = get_relay_server_descriptor({"router-digest": "006FD96BA35E7785A6A3B8B75FE2E2435A13BDB4"}, content = True)
+    desc_text = get_relay_server_descriptor({'router-digest': '006FD96BA35E7785A6A3B8B75FE2E2435A13BDB4'}, content = True)
     desc = BridgeDescriptor(desc_text)
     self.assertFalse(desc.is_scrubbed())
 
@@ -360,13 +360,13 @@ class TestServerDescriptor(unittest.TestCase):
 
     # checks with valid content
 
-    router_digest = "068A2E28D4C934D9490303B7A645BA068DCA0504"
-    desc = get_bridge_server_descriptor({"router-digest": router_digest})
+    router_digest = '068A2E28D4C934D9490303B7A645BA068DCA0504'
+    desc = get_bridge_server_descriptor({'router-digest': router_digest})
     self.assertEquals(router_digest, desc.digest())
 
     # checks when missing
 
-    desc_text = get_bridge_server_descriptor(exclude = ["router-digest"], content = True)
+    desc_text = get_bridge_server_descriptor(exclude = ['router-digest'], content = True)
     self.assertRaises(ValueError, BridgeDescriptor, desc_text)
 
     # check that we can still construct it without validation
@@ -376,14 +376,14 @@ class TestServerDescriptor(unittest.TestCase):
     # checks with invalid content
 
     test_values = (
-      "",
-      "006FD96BA35E7785A6A3B8B75FE2E2435A13BDB44",
-      "006FD96BA35E7785A6A3B8B75FE2E2435A13BDB",
-      "006FD96BA35E7785A6A3B8B75FE2E2435A13BDBH",
+      '',
+      '006FD96BA35E7785A6A3B8B75FE2E2435A13BDB44',
+      '006FD96BA35E7785A6A3B8B75FE2E2435A13BDB',
+      '006FD96BA35E7785A6A3B8B75FE2E2435A13BDBH',
     )
 
     for value in test_values:
-      desc_text = get_bridge_server_descriptor({"router-digest": value}, content = True)
+      desc_text = get_bridge_server_descriptor({'router-digest': value}, content = True)
       self.assertRaises(ValueError, BridgeDescriptor, desc_text)
 
       desc = BridgeDescriptor(desc_text, validate = False)
@@ -394,29 +394,29 @@ class TestServerDescriptor(unittest.TestCase):
     Constructs a bridge descriptor with a sanatized IPv4 or-address entry.
     """
 
-    desc = get_bridge_server_descriptor({"or-address": "10.45.227.253:9001"})
-    self.assertEquals([("10.45.227.253", 9001, False)], desc.or_addresses)
+    desc = get_bridge_server_descriptor({'or-address': '10.45.227.253:9001'})
+    self.assertEquals([('10.45.227.253', 9001, False)], desc.or_addresses)
 
   def test_or_address_v6(self):
     """
     Constructs a bridge descriptor with a sanatized IPv6 or-address entry.
     """
 
-    desc = get_bridge_server_descriptor({"or-address": "[fd9f:2e19:3bcf::02:9970]:9001"})
-    self.assertEquals([("fd9f:2e19:3bcf::02:9970", 9001, True)], desc.or_addresses)
+    desc = get_bridge_server_descriptor({'or-address': '[fd9f:2e19:3bcf::02:9970]:9001'})
+    self.assertEquals([('fd9f:2e19:3bcf::02:9970', 9001, True)], desc.or_addresses)
 
   def test_or_address_multiple(self):
     """
     Constructs a bridge descriptor with multiple or-address entries and multiple ports.
     """
 
-    desc_text = b"\n".join((get_bridge_server_descriptor(content = True),
-                           b"or-address 10.45.227.253:9001",
-                           b"or-address [fd9f:2e19:3bcf::02:9970]:443"))
+    desc_text = b'\n'.join((get_bridge_server_descriptor(content = True),
+                           b'or-address 10.45.227.253:9001',
+                           b'or-address [fd9f:2e19:3bcf::02:9970]:443'))
 
     expected_or_addresses = [
-      ("10.45.227.253", 9001, False),
-      ("fd9f:2e19:3bcf::02:9970", 443, True),
+      ('10.45.227.253', 9001, False),
+      ('fd9f:2e19:3bcf::02:9970', 443, True),
     ]
 
     desc = BridgeDescriptor(desc_text)
@@ -439,4 +439,4 @@ class TestServerDescriptor(unittest.TestCase):
       self.assertEquals(expected_value, getattr(desc, attr))
     else:
       # check a default attribute
-      self.assertEquals("caerSidi", desc.nickname)
+      self.assertEquals('caerSidi', desc.nickname)
diff --git a/test/unit/descriptor/tordnsel.py b/test/unit/descriptor/tordnsel.py
index b494a6f..220af26 100644
--- a/test/unit/descriptor/tordnsel.py
+++ b/test/unit/descriptor/tordnsel.py
@@ -57,23 +57,23 @@ class TestTorDNSELDescriptor(unittest.TestCase):
     self.assertTrue(isinstance(descriptors[0], TorDNSEL))
     desc = descriptors[1]
     self.assertTrue(is_valid_fingerprint(desc.fingerprint))
-    self.assertEqual("00FF300624FECA7F40515C8D854EE925332580D6", desc.fingerprint)
+    self.assertEqual('00FF300624FECA7F40515C8D854EE925332580D6', desc.fingerprint)
     self.assertEqual(datetime.datetime(2013, 8, 18, 7, 2, 14), desc.published)
     self.assertEqual(datetime.datetime(2013, 8, 18, 9, 2, 58), desc.last_status)
     self.assertEqual(3, len(desc.exit_addresses))
     exit = desc.exit_addresses[0]
-    self.assertEqual("82.252.181.153", exit[0])
+    self.assertEqual('82.252.181.153', exit[0])
     self.assertEqual(datetime.datetime(2013, 8, 18, 8, 3, 1), exit[1])
 
     # block content raises value error
 
-    extra = b"ExtraContent goes here\n"
+    extra = b'ExtraContent goes here\n'
     descriptors = _parse_file(io.BytesIO(TEST_DESC + extra))
     self.assertRaises(ValueError, list, descriptors)
 
     # malformed fingerprint raises value errors
 
-    extra = b"ExitNode 030B22437D99B2DB2908B747B6"
+    extra = b'ExitNode 030B22437D99B2DB2908B747B6'
     self.assertRaises(ValueError, list, _parse_file(io.BytesIO(TEST_DESC + extra)))
 
     # malformed date raises value errors
@@ -84,5 +84,5 @@ class TestTorDNSELDescriptor(unittest.TestCase):
 
     desc = _parse_file(io.BytesIO(MALFORMED_ENTRY_2), validate=False).next()
     self.assertTrue(is_valid_fingerprint(desc.fingerprint))
-    self.assertEqual("030B22437D99B2DB2908B747B6962EAD13AB4038", desc.fingerprint)
+    self.assertEqual('030B22437D99B2DB2908B747B6962EAD13AB4038', desc.fingerprint)
     self.assertEqual(0, len(desc.exit_addresses))
diff --git a/test/unit/doctest.py b/test/unit/doctest.py
index 1906480..4692dd6 100644
--- a/test/unit/doctest.py
+++ b/test/unit/doctest.py
@@ -88,4 +88,4 @@ class TestDocumentation(unittest.TestCase):
         is_failed = True
 
     if is_failed:
-      self.fail("doctests encountered errors")
+      self.fail('doctests encountered errors')
diff --git a/test/unit/exit_policy/__init__.py b/test/unit/exit_policy/__init__.py
index 04ea48a..a2dbf94 100644
--- a/test/unit/exit_policy/__init__.py
+++ b/test/unit/exit_policy/__init__.py
@@ -2,4 +2,4 @@
 Unit tests for stem.exit_policy.py contents.
 """
 
-__all__ = ["policy", "rule"]
+__all__ = ['policy', 'rule']
diff --git a/test/unit/exit_policy/policy.py b/test/unit/exit_policy/policy.py
index 041f81e..4965aac 100644
--- a/test/unit/exit_policy/policy.py
+++ b/test/unit/exit_policy/policy.py
@@ -14,13 +14,13 @@ from stem.exit_policy import get_config_policy, \
 class TestExitPolicy(unittest.TestCase):
   def test_example(self):
     # tests the ExitPolicy and MicroExitPolicy pydoc examples
-    policy = ExitPolicy("accept *:80", "accept *:443", "reject *:*")
-    self.assertEquals("accept *:80, accept *:443, reject *:*", str(policy))
-    self.assertEquals("accept 80, 443", policy.summary())
-    self.assertTrue(policy.can_exit_to("75.119.206.243", 80))
+    policy = ExitPolicy('accept *:80', 'accept *:443', 'reject *:*')
+    self.assertEquals('accept *:80, accept *:443, reject *:*', str(policy))
+    self.assertEquals('accept 80, 443', policy.summary())
+    self.assertTrue(policy.can_exit_to('75.119.206.243', 80))
 
-    policy = MicroExitPolicy("accept 80,443")
-    self.assertTrue(policy.can_exit_to("75.119.206.243", 80))
+    policy = MicroExitPolicy('accept 80,443')
+    self.assertTrue(policy.can_exit_to('75.119.206.243', 80))
 
   def test_constructor(self):
     # The ExitPolicy constructor takes a series of string or ExitPolicyRule
@@ -35,18 +35,18 @@ class TestExitPolicy(unittest.TestCase):
     policy = ExitPolicy('accept *:80', 'accept *:443', 'reject *:*')
     self.assertEquals(expected_policy, policy)
 
-    policy = ExitPolicy(*"accept *:80, accept *:443, reject *:*".split(","))
+    policy = ExitPolicy(*'accept *:80, accept *:443, reject *:*'.split(','))
     self.assertEquals(expected_policy, policy)
 
     # checks that we truncate after getting a catch-all policy
 
-    policy = ExitPolicy(*"accept *:80, accept *:443, reject *:*, accept *:20-50".split(","))
+    policy = ExitPolicy(*'accept *:80, accept *:443, reject *:*, accept *:20-50'.split(','))
     self.assertEquals(expected_policy, policy)
 
     # checks that we compress redundant policies
 
-    policy = ExitPolicy(*"reject *:80, reject *:443, reject *:*".split(","))
-    self.assertEquals(ExitPolicy("reject *:*"), policy)
+    policy = ExitPolicy(*'reject *:80, reject *:443, reject *:*'.split(','))
+    self.assertEquals(ExitPolicy('reject *:*'), policy)
 
   def test_can_exit_to(self):
     # Basic sanity test for our can_exit_to() method. Most of the interesting
@@ -56,7 +56,7 @@ class TestExitPolicy(unittest.TestCase):
     policy = ExitPolicy('accept *:80', 'accept *:443', 'reject *:*')
 
     for index in xrange(1, 500):
-      ip_addr = "%i.%i.%i.%i" % (index / 2, index / 2, index / 2, index / 2)
+      ip_addr = '%i.%i.%i.%i' % (index / 2, index / 2, index / 2, index / 2)
       expected_result = index in (80, 443)
 
       self.assertEquals(expected_result, policy.can_exit_to(ip_addr, index))
@@ -83,25 +83,25 @@ class TestExitPolicy(unittest.TestCase):
     # checks the summary() method's pydoc examples
 
     policy = ExitPolicy('accept *:80', 'accept *:443', 'reject *:*')
-    self.assertEquals("accept 80, 443", policy.summary())
+    self.assertEquals('accept 80, 443', policy.summary())
 
     policy = ExitPolicy('accept *:443', 'reject *:1-1024', 'accept *:*')
-    self.assertEquals("reject 1-442, 444-1024", policy.summary())
+    self.assertEquals('reject 1-442, 444-1024', policy.summary())
 
   def test_summary_large_ranges(self):
     # checks the summary() method when the policy includes very large port ranges
 
     policy = ExitPolicy('reject *:80-65535', 'accept *:1-65533', 'reject *:*')
-    self.assertEquals("accept 1-79", policy.summary())
+    self.assertEquals('accept 1-79', policy.summary())
 
   def test_str(self):
     # sanity test for our __str__ method
 
     policy = ExitPolicy('  accept *:80\n', '\taccept *:443')
-    self.assertEquals("accept *:80, accept *:443", str(policy))
+    self.assertEquals('accept *:80, accept *:443', str(policy))
 
     policy = ExitPolicy('reject 0.0.0.0/255.255.255.0:*', 'accept *:*')
-    self.assertEquals("reject 0.0.0.0/24:*, accept *:*", str(policy))
+    self.assertEquals('reject 0.0.0.0/24:*, accept *:*', str(policy))
 
   def test_iter(self):
     # sanity test for our __iter__ method
@@ -183,10 +183,10 @@ class TestExitPolicy(unittest.TestCase):
 
   def test_get_config_policy(self):
     test_inputs = {
-      "": ExitPolicy(),
-      "reject *": ExitPolicy('reject *:*'),
-      "reject *:*": ExitPolicy('reject *:*'),
-      "reject private": ExitPolicy(
+      '': ExitPolicy(),
+      'reject *': ExitPolicy('reject *:*'),
+      'reject *:*': ExitPolicy('reject *:*'),
+      'reject private': ExitPolicy(
         'reject 0.0.0.0/8:*',
         'reject 169.254.0.0/16:*',
         'reject 127.0.0.0/8:*',
@@ -194,11 +194,11 @@ class TestExitPolicy(unittest.TestCase):
         'reject 10.0.0.0/8:*',
         'reject 172.16.0.0/12:*',
       ),
-      "accept *:80, reject *": ExitPolicy(
+      'accept *:80, reject *': ExitPolicy(
         'accept *:80',
         'reject *:*',
       ),
-      "  accept *:80,     reject *   ": ExitPolicy(
+      '  accept *:80,     reject *   ': ExitPolicy(
         'accept *:80',
         'reject *:*',
       ),
@@ -208,11 +208,11 @@ class TestExitPolicy(unittest.TestCase):
       self.assertEqual(expected, get_config_policy(test_input))
 
     test_inputs = (
-      "blarg",
-      "accept *:*:*",
-      "acceptt *:80",
-      "accept 257.0.0.1:80",
-      "accept *:999999",
+      'blarg',
+      'accept *:*:*',
+      'acceptt *:80',
+      'accept 257.0.0.1:80',
+      'accept *:999999',
     )
 
     for test_input in test_inputs:
@@ -223,7 +223,7 @@ class TestExitPolicy(unittest.TestCase):
     Checks that we can unpickle ExitPolicy instances.
     """
 
-    policy = ExitPolicy("accept *:80", "accept *:443", "reject *:*")
+    policy = ExitPolicy('accept *:80', 'accept *:443', 'reject *:*')
     self.assertTrue(policy.can_exit_to('74.125.28.106', 80))
 
     encoded_policy = pickle.dumps(policy)
diff --git a/test/unit/exit_policy/rule.py b/test/unit/exit_policy/rule.py
index 09c0e23..5a6c0d4 100644
--- a/test/unit/exit_policy/rule.py
+++ b/test/unit/exit_policy/rule.py
@@ -9,21 +9,21 @@ from stem.exit_policy import AddressType, ExitPolicyRule
 
 class TestExitPolicyRule(unittest.TestCase):
   def test_accept_or_reject(self):
-    self.assertTrue(ExitPolicyRule("accept *:*").is_accept)
-    self.assertFalse(ExitPolicyRule("reject *:*").is_accept)
+    self.assertTrue(ExitPolicyRule('accept *:*').is_accept)
+    self.assertFalse(ExitPolicyRule('reject *:*').is_accept)
 
     invalid_inputs = (
-      "accept",
-      "reject",
-      "accept  *:*",
-      "accept\t*:*",
-      "accept\n*:*",
-      "acceptt *:*",
-      "rejectt *:*",
-      "blarg *:*",
-      " *:*",
-      "*:*",
-      "",
+      'accept',
+      'reject',
+      'accept  *:*',
+      'accept\t*:*',
+      'accept\n*:*',
+      'acceptt *:*',
+      'rejectt *:*',
+      'blarg *:*',
+      ' *:*',
+      '*:*',
+      '',
     )
 
     for rule_arg in invalid_inputs:
@@ -34,15 +34,15 @@ class TestExitPolicyRule(unittest.TestCase):
     # match the input rule
 
     test_inputs = (
-      "accept *:*",
-      "reject *:*",
-      "accept *:80",
-      "accept *:80-443",
-      "accept 127.0.0.1:80",
-      "accept 87.0.0.1/24:80",
-      "accept 156.5.38.3/255.255.0.255:80",
-      "accept [FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF]:80",
-      "accept [FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF]/32:80",
+      'accept *:*',
+      'reject *:*',
+      'accept *:80',
+      'accept *:80-443',
+      'accept 127.0.0.1:80',
+      'accept 87.0.0.1/24:80',
+      'accept 156.5.38.3/255.255.0.255:80',
+      'accept [FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF]:80',
+      'accept [FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF]/32:80',
     )
 
     for rule_arg in test_inputs:
@@ -52,10 +52,10 @@ class TestExitPolicyRule(unittest.TestCase):
   def test_str_changed(self):
     # some instances where our rule is valid but won't match our str() representation
     test_inputs = {
-      "accept 10.0.0.1/32:80": "accept 10.0.0.1:80",
-      "accept 192.168.0.1/255.255.255.0:80": "accept 192.168.0.1/24:80",
-      "accept [::]/32:*": "accept [0000:0000:0000:0000:0000:0000:0000:0000]/32:*",
-      "accept [::]/128:*": "accept [0000:0000:0000:0000:0000:0000:0000:0000]:*",
+      'accept 10.0.0.1/32:80': 'accept 10.0.0.1:80',
+      'accept 192.168.0.1/255.255.255.0:80': 'accept 192.168.0.1/24:80',
+      'accept [::]/32:*': 'accept [0000:0000:0000:0000:0000:0000:0000:0000]/32:*',
+      'accept [::]/128:*': 'accept [0000:0000:0000:0000:0000:0000:0000:0000]:*',
     }
 
     for rule_arg, expected_str in test_inputs.items():
@@ -64,23 +64,23 @@ class TestExitPolicyRule(unittest.TestCase):
 
   def test_valid_wildcard(self):
     test_inputs = {
-      "reject *:*": (True, True),
-      "reject *:80": (True, False),
-      "accept 192.168.0.1:*": (False, True),
-      "accept 192.168.0.1:80": (False, False),
-
-      "reject 127.0.0.1/0:*": (True, True),
-      "reject 127.0.0.1/0.0.0.0:*": (True, True),
-      "reject 127.0.0.1/16:*": (False, True),
-      "reject 127.0.0.1/32:*": (False, True),
-      "reject [0000:0000:0000:0000:0000:0000:0000:0000]/0:80": (True, False),
-      "reject [0000:0000:0000:0000:0000:0000:0000:0000]/64:80": (False, False),
-      "reject [0000:0000:0000:0000:0000:0000:0000:0000]/128:80": (False, False),
-
-      "accept 192.168.0.1:0-65535": (False, True),
-      "accept 192.168.0.1:1-65535": (False, True),
-      "accept 192.168.0.1:2-65535": (False, False),
-      "accept 192.168.0.1:1-65534": (False, False),
+      'reject *:*': (True, True),
+      'reject *:80': (True, False),
+      'accept 192.168.0.1:*': (False, True),
+      'accept 192.168.0.1:80': (False, False),
+
+      'reject 127.0.0.1/0:*': (True, True),
+      'reject 127.0.0.1/0.0.0.0:*': (True, True),
+      'reject 127.0.0.1/16:*': (False, True),
+      'reject 127.0.0.1/32:*': (False, True),
+      'reject [0000:0000:0000:0000:0000:0000:0000:0000]/0:80': (True, False),
+      'reject [0000:0000:0000:0000:0000:0000:0000:0000]/64:80': (False, False),
+      'reject [0000:0000:0000:0000:0000:0000:0000:0000]/128:80': (False, False),
+
+      'accept 192.168.0.1:0-65535': (False, True),
+      'accept 192.168.0.1:1-65535': (False, True),
+      'accept 192.168.0.1:2-65535': (False, False),
+      'accept 192.168.0.1:1-65534': (False, False),
     }
 
     for rule_arg, attr in test_inputs.items():
@@ -92,27 +92,27 @@ class TestExitPolicyRule(unittest.TestCase):
 
     # check that when appropriate a /0 is reported as *not* being a wildcard
 
-    rule = ExitPolicyRule("reject 127.0.0.1/0:*")
+    rule = ExitPolicyRule('reject 127.0.0.1/0:*')
     rule._submask_wildcard = False
     self.assertEquals(False, rule.is_address_wildcard())
 
-    rule = ExitPolicyRule("reject [0000:0000:0000:0000:0000:0000:0000:0000]/0:80")
+    rule = ExitPolicyRule('reject [0000:0000:0000:0000:0000:0000:0000:0000]/0:80')
     rule._submask_wildcard = False
     self.assertEquals(False, rule.is_address_wildcard())
 
   def test_invalid_wildcard(self):
     test_inputs = (
-      "reject */16:*",
-      "reject 127.0.0.1/*:*",
-      "reject *:0-*",
-      "reject *:*-15",
+      'reject */16:*',
+      'reject 127.0.0.1/*:*',
+      'reject *:0-*',
+      'reject *:*-15',
     )
 
     for rule_arg in test_inputs:
       self.assertRaises(ValueError, ExitPolicyRule, rule_arg)
 
   def test_wildcard_attributes(self):
-    rule = ExitPolicyRule("reject *:*")
+    rule = ExitPolicyRule('reject *:*')
     self.assertEquals(AddressType.WILDCARD, rule.get_address_type())
     self.assertEquals(None, rule.address)
     self.assertEquals(None, rule.get_mask())
@@ -122,16 +122,16 @@ class TestExitPolicyRule(unittest.TestCase):
 
   def test_valid_ipv4_addresses(self):
     test_inputs = {
-      "0.0.0.0": ("0.0.0.0", "255.255.255.255", 32),
-      "127.0.0.1/32": ("127.0.0.1", "255.255.255.255", 32),
-      "192.168.0.50/24": ("192.168.0.50", "255.255.255.0", 24),
-      "255.255.255.255/0": ("255.255.255.255", "0.0.0.0", 0),
+      '0.0.0.0': ('0.0.0.0', '255.255.255.255', 32),
+      '127.0.0.1/32': ('127.0.0.1', '255.255.255.255', 32),
+      '192.168.0.50/24': ('192.168.0.50', '255.255.255.0', 24),
+      '255.255.255.255/0': ('255.255.255.255', '0.0.0.0', 0),
     }
 
     for rule_addr, attr in test_inputs.items():
       address, mask, masked_bits = attr
 
-      rule = ExitPolicyRule("accept %s:*" % rule_addr)
+      rule = ExitPolicyRule('accept %s:*' % rule_addr)
       self.assertEquals(AddressType.IPv4, rule.get_address_type())
       self.assertEquals(address, rule.address)
       self.assertEquals(mask, rule.get_mask())
@@ -139,38 +139,38 @@ class TestExitPolicyRule(unittest.TestCase):
 
   def test_invalid_ipv4_addresses(self):
     test_inputs = (
-      "256.0.0.0",
-      "-1.0.0.0",
-      "0.0.0",
-      "0.0.0.",
-      "0.0.0.a",
-      "127.0.0.1/-1",
-      "127.0.0.1/33",
+      '256.0.0.0',
+      '-1.0.0.0',
+      '0.0.0',
+      '0.0.0.',
+      '0.0.0.a',
+      '127.0.0.1/-1',
+      '127.0.0.1/33',
     )
 
     for rule_addr in test_inputs:
-      self.assertRaises(ValueError, ExitPolicyRule, "accept %s:*" % rule_addr)
+      self.assertRaises(ValueError, ExitPolicyRule, 'accept %s:*' % rule_addr)
 
   def test_valid_ipv6_addresses(self):
     test_inputs = {
-      "[fe80:0000:0000:0000:0202:b3ff:fe1e:8329]":
-        ("FE80:0000:0000:0000:0202:B3FF:FE1E:8329",
-         "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", 128),
-      "[FE80::0202:b3ff:fe1e:8329]":
-        ("FE80:0000:0000:0000:0202:B3FF:FE1E:8329",
-         "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", 128),
-      "[0000:0000:0000:0000:0000:0000:0000:0000]/0":
-        ("0000:0000:0000:0000:0000:0000:0000:0000",
-         "0000:0000:0000:0000:0000:0000:0000:0000", 0),
-      "[::]":
-        ("0000:0000:0000:0000:0000:0000:0000:0000",
-         "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", 128),
+      '[fe80:0000:0000:0000:0202:b3ff:fe1e:8329]':
+        ('FE80:0000:0000:0000:0202:B3FF:FE1E:8329',
+         'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF', 128),
+      '[FE80::0202:b3ff:fe1e:8329]':
+        ('FE80:0000:0000:0000:0202:B3FF:FE1E:8329',
+         'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF', 128),
+      '[0000:0000:0000:0000:0000:0000:0000:0000]/0':
+        ('0000:0000:0000:0000:0000:0000:0000:0000',
+         '0000:0000:0000:0000:0000:0000:0000:0000', 0),
+      '[::]':
+        ('0000:0000:0000:0000:0000:0000:0000:0000',
+         'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF', 128),
     }
 
     for rule_addr, attr in test_inputs.items():
       address, mask, masked_bits = attr
 
-      rule = ExitPolicyRule("accept %s:*" % rule_addr)
+      rule = ExitPolicyRule('accept %s:*' % rule_addr)
       self.assertEquals(AddressType.IPv6, rule.get_address_type())
       self.assertEquals(address, rule.address)
       self.assertEquals(mask, rule.get_mask())
@@ -178,67 +178,67 @@ class TestExitPolicyRule(unittest.TestCase):
 
   def test_invalid_ipv6_addresses(self):
     test_inputs = (
-      "fe80::0202:b3ff:fe1e:8329",
-      "[fe80::0202:b3ff:fe1e:8329",
-      "fe80::0202:b3ff:fe1e:8329]",
-      "[fe80::0202:b3ff:fe1e:832g]",
-      "[fe80:::b3ff:fe1e:8329]",
-      "[fe80::b3ff::fe1e:8329]",
-      "[fe80::0202:b3ff:fe1e:8329]/-1",
-      "[fe80::0202:b3ff:fe1e:8329]/129",
+      'fe80::0202:b3ff:fe1e:8329',
+      '[fe80::0202:b3ff:fe1e:8329',
+      'fe80::0202:b3ff:fe1e:8329]',
+      '[fe80::0202:b3ff:fe1e:832g]',
+      '[fe80:::b3ff:fe1e:8329]',
+      '[fe80::b3ff::fe1e:8329]',
+      '[fe80::0202:b3ff:fe1e:8329]/-1',
+      '[fe80::0202:b3ff:fe1e:8329]/129',
     )
 
     for rule_addr in test_inputs:
-      self.assertRaises(ValueError, ExitPolicyRule, "accept %s:*" % rule_addr)
+      self.assertRaises(ValueError, ExitPolicyRule, 'accept %s:*' % rule_addr)
 
   def test_valid_ports(self):
     test_inputs = {
-      "0": (0, 0),
-      "1": (1, 1),
-      "80": (80, 80),
-      "80-443": (80, 443),
+      '0': (0, 0),
+      '1': (1, 1),
+      '80': (80, 80),
+      '80-443': (80, 443),
     }
 
     for rule_port, attr in test_inputs.items():
       min_port, max_port = attr
 
-      rule = ExitPolicyRule("accept 127.0.0.1:%s" % rule_port)
+      rule = ExitPolicyRule('accept 127.0.0.1:%s' % rule_port)
       self.assertEquals(min_port, rule.min_port)
       self.assertEquals(max_port, rule.max_port)
 
   def test_invalid_ports(self):
     test_inputs = (
-      "65536",
-      "a",
-      "5-3",
-      "5-",
-      "-3",
+      '65536',
+      'a',
+      '5-3',
+      '5-',
+      '-3',
     )
 
     for rule_port in test_inputs:
-      self.assertRaises(ValueError, ExitPolicyRule, "accept 127.0.0.1:%s" % rule_port)
+      self.assertRaises(ValueError, ExitPolicyRule, 'accept 127.0.0.1:%s' % rule_port)
 
   def test_is_match_wildcard(self):
     test_inputs = {
-      "reject *:*": {
-        ("192.168.0.1", 80): True,
-        ("0.0.0.0", 80): True,
-        ("255.255.255.255", 80): True,
-        ("FE80:0000:0000:0000:0202:B3FF:FE1E:8329", 80): True,
-        ("[FE80:0000:0000:0000:0202:B3FF:FE1E:8329]", 80): True,
-        ("192.168.0.1", None): True,
+      'reject *:*': {
+        ('192.168.0.1', 80): True,
+        ('0.0.0.0', 80): True,
+        ('255.255.255.255', 80): True,
+        ('FE80:0000:0000:0000:0202:B3FF:FE1E:8329', 80): True,
+        ('[FE80:0000:0000:0000:0202:B3FF:FE1E:8329]', 80): True,
+        ('192.168.0.1', None): True,
         (None, 80, False): True,
         (None, 80, True): True,
         (None, None, False): True,
         (None, None, True): True,
       },
-      "reject 255.255.255.255/0:*": {
-        ("192.168.0.1", 80): True,
-        ("0.0.0.0", 80): True,
-        ("255.255.255.255", 80): True,
-        ("FE80:0000:0000:0000:0202:B3FF:FE1E:8329", 80): False,
-        ("[FE80:0000:0000:0000:0202:B3FF:FE1E:8329]", 80): False,
-        ("192.168.0.1", None): True,
+      'reject 255.255.255.255/0:*': {
+        ('192.168.0.1', 80): True,
+        ('0.0.0.0', 80): True,
+        ('255.255.255.255', 80): True,
+        ('FE80:0000:0000:0000:0202:B3FF:FE1E:8329', 80): False,
+        ('[FE80:0000:0000:0000:0202:B3FF:FE1E:8329]', 80): False,
+        ('192.168.0.1', None): True,
         (None, 80, False): True,
         (None, 80, True): False,
         (None, None, False): True,
@@ -256,29 +256,29 @@ class TestExitPolicyRule(unittest.TestCase):
     # port zero is special in that exit policies can include it, but it's not
     # something that we can match against
 
-    rule = ExitPolicyRule("reject *:*")
-    self.assertRaises(ValueError, rule.is_match, "127.0.0.1", 0)
+    rule = ExitPolicyRule('reject *:*')
+    self.assertRaises(ValueError, rule.is_match, '127.0.0.1', 0)
 
   def test_is_match_ipv4(self):
     test_inputs = {
-      "reject 192.168.0.50:*": {
-        ("192.168.0.50", 80): True,
-        ("192.168.0.51", 80): False,
-        ("192.168.0.49", 80): False,
+      'reject 192.168.0.50:*': {
+        ('192.168.0.50', 80): True,
+        ('192.168.0.51', 80): False,
+        ('192.168.0.49', 80): False,
         (None, 80, False): True,
         (None, 80, True): False,
-        ("192.168.0.50", None): True,
+        ('192.168.0.50', None): True,
       },
-      "reject 0.0.0.0/24:*": {
-        ("0.0.0.0", 80): True,
-        ("0.0.0.1", 80): True,
-        ("0.0.0.255", 80): True,
-        ("0.0.1.0", 80): False,
-        ("0.1.0.0", 80): False,
-        ("1.0.0.0", 80): False,
+      'reject 0.0.0.0/24:*': {
+        ('0.0.0.0', 80): True,
+        ('0.0.0.1', 80): True,
+        ('0.0.0.255', 80): True,
+        ('0.0.1.0', 80): False,
+        ('0.1.0.0', 80): False,
+        ('1.0.0.0', 80): False,
         (None, 80, False): True,
         (None, 80, True): False,
-        ("0.0.0.0", None): True,
+        ('0.0.0.0', None): True,
       },
     }
 
@@ -290,26 +290,26 @@ class TestExitPolicyRule(unittest.TestCase):
 
   def test_is_match_ipv6(self):
     test_inputs = {
-      "reject [FE80:0000:0000:0000:0202:B3FF:FE1E:8329]:*": {
-        ("FE80:0000:0000:0000:0202:B3FF:FE1E:8329", 80): True,
-        ("fe80:0000:0000:0000:0202:b3ff:fe1e:8329", 80): True,
-        ("[FE80:0000:0000:0000:0202:B3FF:FE1E:8329]", 80): True,
-        ("FE80:0000:0000:0000:0202:B3FF:FE1E:8330", 80): False,
-        ("FE80:0000:0000:0000:0202:B3FF:FE1E:8328", 80): False,
+      'reject [FE80:0000:0000:0000:0202:B3FF:FE1E:8329]:*': {
+        ('FE80:0000:0000:0000:0202:B3FF:FE1E:8329', 80): True,
+        ('fe80:0000:0000:0000:0202:b3ff:fe1e:8329', 80): True,
+        ('[FE80:0000:0000:0000:0202:B3FF:FE1E:8329]', 80): True,
+        ('FE80:0000:0000:0000:0202:B3FF:FE1E:8330', 80): False,
+        ('FE80:0000:0000:0000:0202:B3FF:FE1E:8328', 80): False,
         (None, 80, False): True,
         (None, 80, True): False,
-        ("FE80:0000:0000:0000:0202:B3FF:FE1E:8329", None): True,
+        ('FE80:0000:0000:0000:0202:B3FF:FE1E:8329', None): True,
       },
-      "reject [FE80:0000:0000:0000:0202:B3FF:FE1E:8329]/112:*": {
-        ("FE80:0000:0000:0000:0202:B3FF:FE1E:8329", 80): True,
-        ("FE80:0000:0000:0000:0202:B3FF:FE1E:0000", 80): True,
-        ("FE80:0000:0000:0000:0202:B3FF:FE1E:FFFF", 80): True,
-        ("FE80:0000:0000:0000:0202:B3FF:FE1F:8329", 80): False,
-        ("FE81:0000:0000:0000:0202:B3FF:FE1E:8329", 80): False,
+      'reject [FE80:0000:0000:0000:0202:B3FF:FE1E:8329]/112:*': {
+        ('FE80:0000:0000:0000:0202:B3FF:FE1E:8329', 80): True,
+        ('FE80:0000:0000:0000:0202:B3FF:FE1E:0000', 80): True,
+        ('FE80:0000:0000:0000:0202:B3FF:FE1E:FFFF', 80): True,
+        ('FE80:0000:0000:0000:0202:B3FF:FE1F:8329', 80): False,
+        ('FE81:0000:0000:0000:0202:B3FF:FE1E:8329', 80): False,
         (None, 80, False): True,
         (None, 80, True): False,
-        ("FE80:0000:0000:0000:0202:B3FF:FE1E:8329", None, False): True,
-        ("FE80:0000:0000:0000:0202:B3FF:FE1E:8329", None, True): True,
+        ('FE80:0000:0000:0000:0202:B3FF:FE1E:8329', None, False): True,
+        ('FE80:0000:0000:0000:0202:B3FF:FE1E:8329', None, True): True,
       },
     }
 
@@ -321,23 +321,23 @@ class TestExitPolicyRule(unittest.TestCase):
 
   def test_is_match_port(self):
     test_inputs = {
-      "reject *:80": {
-        ("192.168.0.50", 80): True,
-        ("192.168.0.50", 81): False,
-        ("192.168.0.50", 79): False,
+      'reject *:80': {
+        ('192.168.0.50', 80): True,
+        ('192.168.0.50', 81): False,
+        ('192.168.0.50', 79): False,
         (None, 80): True,
-        ("192.168.0.50", None, False): True,
-        ("192.168.0.50", None, True): False,
+        ('192.168.0.50', None, False): True,
+        ('192.168.0.50', None, True): False,
       },
-      "reject *:80-85": {
-        ("192.168.0.50", 79): False,
-        ("192.168.0.50", 80): True,
-        ("192.168.0.50", 83): True,
-        ("192.168.0.50", 85): True,
-        ("192.168.0.50", 86): False,
+      'reject *:80-85': {
+        ('192.168.0.50', 79): False,
+        ('192.168.0.50', 80): True,
+        ('192.168.0.50', 83): True,
+        ('192.168.0.50', 85): True,
+        ('192.168.0.50', 86): False,
         (None, 83): True,
-        ("192.168.0.50", None, False): True,
-        ("192.168.0.50", None, True): False,
+        ('192.168.0.50', None, False): True,
+        ('192.168.0.50', None, True): False,
       },
     }
 
diff --git a/test/unit/interpretor/__init__.py b/test/unit/interpretor/__init__.py
index 702cb92..705734d 100644
--- a/test/unit/interpretor/__init__.py
+++ b/test/unit/interpretor/__init__.py
@@ -3,10 +3,10 @@ Unit tests for the stem's interpretor prompt.
 """
 
 __all__ = [
-  "arguments",
-  "autocomplete",
-  "commands",
-  "help",
+  'arguments',
+  'autocomplete',
+  'commands',
+  'help',
 ]
 
 try:
diff --git a/test/unit/response/__init__.py b/test/unit/response/__init__.py
index 3320f64..bb1724b 100644
--- a/test/unit/response/__init__.py
+++ b/test/unit/response/__init__.py
@@ -3,12 +3,12 @@ Unit tests for stem.response.
 """
 
 __all__ = [
-  "control_message",
-  "control_line",
-  "events",
-  "getinfo",
-  "getconf",
-  "protocolinfo",
-  "authchallenge",
-  "singleline"
+  'control_message',
+  'control_line',
+  'events',
+  'getinfo',
+  'getconf',
+  'protocolinfo',
+  'authchallenge',
+  'singleline',
 ]
diff --git a/test/unit/response/authchallenge.py b/test/unit/response/authchallenge.py
index 5cdf347..aa71ecc 100644
--- a/test/unit/response/authchallenge.py
+++ b/test/unit/response/authchallenge.py
@@ -10,15 +10,15 @@ import stem.socket
 
 from test import mocking
 
-VALID_RESPONSE = "250 AUTHCHALLENGE \
+VALID_RESPONSE = '250 AUTHCHALLENGE \
 SERVERHASH=B16F72DACD4B5ED1531F3FCC04B593D46A1E30267E636EA7C7F8DD7A2B7BAA05 \
-SERVERNONCE=653574272ABBB49395BD1060D642D653CFB7A2FCE6A4955BCFED819703A9998C"
+SERVERNONCE=653574272ABBB49395BD1060D642D653CFB7A2FCE6A4955BCFED819703A9998C'
 
-VALID_HASH = b"\xb1or\xda\xcdK^\xd1S\x1f?\xcc\x04\xb5\x93\xd4j\x1e0&~cn\xa7\xc7\xf8\xddz+{\xaa\x05"
+VALID_HASH = b'\xb1or\xda\xcdK^\xd1S\x1f?\xcc\x04\xb5\x93\xd4j\x1e0&~cn\xa7\xc7\xf8\xddz+{\xaa\x05'
 VALID_NONCE = b"e5t'*\xbb\xb4\x93\x95\xbd\x10`\xd6B\xd6S\xcf\xb7\xa2\xfc\xe6\xa4\x95[\xcf\xed\x81\x97\x03\xa9\x99\x8c"
-INVALID_RESPONSE = "250 AUTHCHALLENGE \
+INVALID_RESPONSE = '250 AUTHCHALLENGE \
 SERVERHASH=FOOBARB16F72DACD4B5ED1531F3FCC04B593D46A1E30267E636EA7C7F8DD7A2B7BAA05 \
-SERVERNONCE=FOOBAR653574272ABBB49395BD1060D642D653CFB7A2FCE6A4955BCFED819703A9998C"
+SERVERNONCE=FOOBAR653574272ABBB49395BD1060D642D653CFB7A2FCE6A4955BCFED819703A9998C'
 
 
 class TestAuthChallengeResponse(unittest.TestCase):
@@ -28,7 +28,7 @@ class TestAuthChallengeResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(VALID_RESPONSE)
-    stem.response.convert("AUTHCHALLENGE", control_message)
+    stem.response.convert('AUTHCHALLENGE', control_message)
 
     # now this should be a AuthChallengeResponse (ControlMessage subclass)
     self.assertTrue(isinstance(control_message, stem.response.ControlMessage))
@@ -52,4 +52,4 @@ class TestAuthChallengeResponse(unittest.TestCase):
 
       remaining_comp = auth_challenge_comp[:index] + auth_challenge_comp[index + 1:]
       control_message = mocking.get_message(' '.join(remaining_comp))
-      self.assertRaises(stem.ProtocolError, stem.response.convert, "AUTHCHALLENGE", control_message)
+      self.assertRaises(stem.ProtocolError, stem.response.convert, 'AUTHCHALLENGE', control_message)
diff --git a/test/unit/response/control_line.py b/test/unit/response/control_line.py
index c00baf6..edccb2e 100644
--- a/test/unit/response/control_line.py
+++ b/test/unit/response/control_line.py
@@ -23,11 +23,11 @@ class TestControlLine(unittest.TestCase):
 
     line = stem.response.ControlLine("\"We're all mad here.\" says the grinning cat.")
     self.assertEquals(line.pop(True), "We're all mad here.")
-    self.assertEquals(line.pop(), "says")
-    self.assertEquals(line.remainder(), "the grinning cat.")
+    self.assertEquals(line.pop(), 'says')
+    self.assertEquals(line.remainder(), 'the grinning cat.')
 
-    line = stem.response.ControlLine("\"this has a \\\" and \\\\ in it\" foo=bar more_data")
-    self.assertEquals(line.pop(True, True), "this has a \" and \\ in it")
+    line = stem.response.ControlLine('"this has a \\" and \\\\ in it" foo=bar more_data')
+    self.assertEquals(line.pop(True, True), 'this has a " and \\ in it')
 
   def test_string(self):
     """
@@ -93,10 +93,10 @@ class TestControlLine(unittest.TestCase):
     self.assertFalse(line.is_empty())
     self.assertFalse(line.is_next_quoted())
     self.assertTrue(line.is_next_mapping())
-    self.assertTrue(line.is_next_mapping(key = "Tor"))
-    self.assertTrue(line.is_next_mapping(key = "Tor", quoted = True))
+    self.assertTrue(line.is_next_mapping(key = 'Tor'))
+    self.assertTrue(line.is_next_mapping(key = 'Tor', quoted = True))
     self.assertTrue(line.is_next_mapping(quoted = True))
-    self.assertEquals("Tor", line.peek_key())
+    self.assertEquals('Tor', line.peek_key())
 
     # try popping this as a non-quoted mapping
     self.assertEquals(line.pop_mapping(), ('Tor', '"0.2.1.30'))
@@ -128,12 +128,12 @@ class TestControlLine(unittest.TestCase):
     self.assertEquals(line, auth_line)
     self.assertEquals(line.remainder(), auth_line)
 
-    self.assertEquals(line.pop(), "AUTH")
-    self.assertEquals(line.pop_mapping(), ("METHODS", "COOKIE"))
+    self.assertEquals(line.pop(), 'AUTH')
+    self.assertEquals(line.pop_mapping(), ('METHODS', 'COOKIE'))
 
     self.assertEquals(line.remainder(), r'COOKIEFILE="/tmp/my data\\\"dir//control_auth_cookie"')
     self.assertTrue(line.is_next_mapping())
-    self.assertTrue(line.is_next_mapping(key = "COOKIEFILE"))
+    self.assertTrue(line.is_next_mapping(key = 'COOKIEFILE'))
     self.assertTrue(line.is_next_mapping(quoted = True))
     self.assertTrue(line.is_next_mapping(quoted = True, escaped = True))
     cookie_file_entry = line.remainder()
diff --git a/test/unit/response/control_message.py b/test/unit/response/control_message.py
index 435bed7..91b7fbd 100644
--- a/test/unit/response/control_message.py
+++ b/test/unit/response/control_message.py
@@ -10,16 +10,16 @@ import stem.socket
 import stem.response
 import stem.response.getinfo
 
-OK_REPLY = "250 OK\r\n"
+OK_REPLY = '250 OK\r\n'
 
-EVENT_BW = "650 BW 32326 2856\r\n"
-EVENT_CIRC_TIMEOUT = "650 CIRC 5 FAILED PURPOSE=GENERAL REASON=TIMEOUT\r\n"
-EVENT_CIRC_LAUNCHED = "650 CIRC 9 LAUNCHED PURPOSE=GENERAL\r\n"
-EVENT_CIRC_EXTENDED = "650 CIRC 5 EXTENDED $A200F527C82C59A25CCA44884B49D3D65B122652=faktor PURPOSE=MEASURE_TIMEOUT\r\n"
+EVENT_BW = '650 BW 32326 2856\r\n'
+EVENT_CIRC_TIMEOUT = '650 CIRC 5 FAILED PURPOSE=GENERAL REASON=TIMEOUT\r\n'
+EVENT_CIRC_LAUNCHED = '650 CIRC 9 LAUNCHED PURPOSE=GENERAL\r\n'
+EVENT_CIRC_EXTENDED = '650 CIRC 5 EXTENDED $A200F527C82C59A25CCA44884B49D3D65B122652=faktor PURPOSE=MEASURE_TIMEOUT\r\n'
 
 GETINFO_VERSION = """250-version=0.2.2.23-alpha (git-b85eb949b528f4d7)
 250 OK
-""".replace("\n", "\r\n")
+""".replace('\n', '\r\n')
 
 GETINFO_INFONAMES = """250+info/names=
 accounting/bytes -- Number of bytes read/written so far in the accounting interval.
@@ -30,7 +30,7 @@ stream-status -- List of current streams.
 version -- The current version of Tor.
 .
 250 OK
-""".replace("\n", "\r\n")
+""".replace('\n', '\r\n')
 
 
 class TestControlMessage(unittest.TestCase):
@@ -40,7 +40,7 @@ class TestControlMessage(unittest.TestCase):
     self.assertTrue(isinstance(msg, stem.response.ControlMessage))
     self.assertEqual('version=0.2.2.23-alpha (git-b85eb949b528f4d7)\nOK', str(msg))
 
-    msg = stem.response.ControlMessage.from_str(GETINFO_VERSION, "GETINFO")
+    msg = stem.response.ControlMessage.from_str(GETINFO_VERSION, 'GETINFO')
     self.assertTrue(isinstance(msg, stem.response.getinfo.GetInfoResponse))
     self.assertEqual({'version': b'0.2.2.23-alpha (git-b85eb949b528f4d7)'}, msg.entries)
 
@@ -50,11 +50,11 @@ class TestControlMessage(unittest.TestCase):
     """
 
     message = self._assert_message_parses(OK_REPLY)
-    self.assertEquals("OK", str(message))
+    self.assertEquals('OK', str(message))
 
     contents = message.content()
     self.assertEquals(1, len(contents))
-    self.assertEquals(("250", " ", "OK"), contents[0])
+    self.assertEquals(('250', ' ', 'OK'), contents[0])
 
   def test_event_response(self):
     """
@@ -63,11 +63,11 @@ class TestControlMessage(unittest.TestCase):
 
     # BW event
     message = self._assert_message_parses(EVENT_BW)
-    self.assertEquals("BW 32326 2856", str(message))
+    self.assertEquals('BW 32326 2856', str(message))
 
     contents = message.content()
     self.assertEquals(1, len(contents))
-    self.assertEquals(("650", " ", "BW 32326 2856"), contents[0])
+    self.assertEquals(('650', ' ', 'BW 32326 2856'), contents[0])
 
     # few types of CIRC events
     for circ_content in (EVENT_CIRC_TIMEOUT, EVENT_CIRC_LAUNCHED, EVENT_CIRC_EXTENDED):
@@ -76,7 +76,7 @@ class TestControlMessage(unittest.TestCase):
 
       contents = message.content()
       self.assertEquals(1, len(contents))
-      self.assertEquals(("650", " ", str(message)), contents[0])
+      self.assertEquals(('650', ' ', str(message)), contents[0])
 
   def test_getinfo_response(self):
     """
@@ -91,8 +91,8 @@ class TestControlMessage(unittest.TestCase):
     # manually checks the contents
     contents = message.content()
     self.assertEquals(2, len(contents))
-    self.assertEquals(("250", "-", "version=0.2.2.23-alpha (git-b85eb949b528f4d7)"), contents[0])
-    self.assertEquals(("250", " ", "OK"), contents[1])
+    self.assertEquals(('250', '-', 'version=0.2.2.23-alpha (git-b85eb949b528f4d7)'), contents[0])
+    self.assertEquals(('250', ' ', 'OK'), contents[1])
 
     # GETINFO info/names (data entry)
     message = self._assert_message_parses(GETINFO_INFONAMES)
@@ -103,9 +103,9 @@ class TestControlMessage(unittest.TestCase):
     contents = message.content()
     self.assertEquals(2, len(contents))
 
-    first_entry = (contents[0][0], contents[0][1], contents[0][2][:contents[0][2].find("\n")])
-    self.assertEquals(("250", "+", "info/names="), first_entry)
-    self.assertEquals(("250", " ", "OK"), contents[1])
+    first_entry = (contents[0][0], contents[0][1], contents[0][2][:contents[0][2].find('\n')])
+    self.assertEquals(('250', '+', 'info/names='), first_entry)
+    self.assertEquals(('250', ' ', 'OK'), contents[1])
 
   def test_no_crlf(self):
     """
@@ -119,21 +119,21 @@ class TestControlMessage(unittest.TestCase):
     # causes a parsing error. This should test line endings for both data
     # entry parsing and non-data.
 
-    infonames_lines = [line + "\n" for line in GETINFO_INFONAMES.splitlines()]
+    infonames_lines = [line + '\n' for line in GETINFO_INFONAMES.splitlines()]
 
     for index, line in enumerate(infonames_lines):
       # replace the CRLF for the line
-      infonames_lines[index] = line.rstrip("\r\n") + "\n"
-      test_socket_file = StringIO.StringIO("".join(infonames_lines))
+      infonames_lines[index] = line.rstrip('\r\n') + '\n'
+      test_socket_file = StringIO.StringIO(''.join(infonames_lines))
       self.assertRaises(stem.ProtocolError, stem.socket.recv_message, test_socket_file)
 
       # puts the CRLF back
-      infonames_lines[index] = infonames_lines[index].rstrip("\n") + "\r\n"
+      infonames_lines[index] = infonames_lines[index].rstrip('\n') + '\r\n'
 
     # sanity check the above test isn't broken due to leaving infonames_lines
     # with invalid data
 
-    self._assert_message_parses("".join(infonames_lines))
+    self._assert_message_parses(''.join(infonames_lines))
 
   def test_malformed_prefix(self):
     """
@@ -143,7 +143,7 @@ class TestControlMessage(unittest.TestCase):
     for index in range(len(EVENT_BW)):
       # makes test input with that character missing or replaced
       removal_test_input = EVENT_BW[:index] + EVENT_BW[index + 1:]
-      replacement_test_input = EVENT_BW[:index] + "#" + EVENT_BW[index + 1:]
+      replacement_test_input = EVENT_BW[:index] + '#' + EVENT_BW[index + 1:]
 
       if index < 4 or index >= (len(EVENT_BW) - 2):
         # dropping the character should cause an error if...
@@ -182,14 +182,14 @@ class TestControlMessage(unittest.TestCase):
 
     # checks that the contents match the input
     message_lines = str(message).splitlines()
-    controller_lines = controller_reply.split("\r\n")
+    controller_lines = controller_reply.split('\r\n')
     controller_lines.pop()  # the ControlMessage won't have a trailing newline
 
     while controller_lines:
       line = controller_lines.pop(0)
 
       # mismatching lines with just a period are probably data termination
-      if line == "." and (not message_lines or line != message_lines[0]):
+      if line == '.' and (not message_lines or line != message_lines[0]):
         continue
 
       self.assertTrue(line.endswith(message_lines.pop(0)))
diff --git a/test/unit/response/events.py b/test/unit/response/events.py
index 28de639..dac2609 100644
--- a/test/unit/response/events.py
+++ b/test/unit/response/events.py
@@ -48,7 +48,7 @@ CACHED="KINDA"'
 
 # BUILDTIMEOUT_SET event from tor 0.2.3.16.
 
-BUILD_TIMEOUT_EVENT = "650 BUILDTIMEOUT_SET COMPUTED \
+BUILD_TIMEOUT_EVENT = '650 BUILDTIMEOUT_SET COMPUTED \
 TOTAL_TIMES=124 \
 TIMEOUT_MS=9019 \
 XM=1375 \
@@ -56,9 +56,9 @@ ALPHA=0.855662 \
 CUTOFF_QUANTILE=0.800000 \
 TIMEOUT_RATE=0.137097 \
 CLOSE_MS=21850 \
-CLOSE_RATE=0.072581"
+CLOSE_RATE=0.072581'
 
-BUILD_TIMEOUT_EVENT_BAD_1 = "650 BUILDTIMEOUT_SET COMPUTED \
+BUILD_TIMEOUT_EVENT_BAD_1 = '650 BUILDTIMEOUT_SET COMPUTED \
 TOTAL_TIMES=one_twenty_four \
 TIMEOUT_MS=9019 \
 XM=1375 \
@@ -66,9 +66,9 @@ ALPHA=0.855662 \
 CUTOFF_QUANTILE=0.800000 \
 TIMEOUT_RATE=0.137097 \
 CLOSE_MS=21850 \
-CLOSE_RATE=0.072581"
+CLOSE_RATE=0.072581'
 
-BUILD_TIMEOUT_EVENT_BAD_2 = "650 BUILDTIMEOUT_SET COMPUTED \
+BUILD_TIMEOUT_EVENT_BAD_2 = '650 BUILDTIMEOUT_SET COMPUTED \
 TOTAL_TIMES=124 \
 TIMEOUT_MS=9019 \
 XM=1375 \
@@ -76,69 +76,69 @@ ALPHA=0.855662 \
 CUTOFF_QUANTILE=zero_point_eight \
 TIMEOUT_RATE=0.137097 \
 CLOSE_MS=21850 \
-CLOSE_RATE=0.072581"
+CLOSE_RATE=0.072581'
 
 # CIRC events from tor v0.2.3.16
 
-CIRC_LAUNCHED = "650 CIRC 7 LAUNCHED \
+CIRC_LAUNCHED = '650 CIRC 7 LAUNCHED \
 BUILD_FLAGS=NEED_CAPACITY \
 PURPOSE=GENERAL \
-TIME_CREATED=2012-11-08T16:48:38.417238"
+TIME_CREATED=2012-11-08T16:48:38.417238'
 
-CIRC_LAUNCHED_BAD_1 = "650 CIRC 7 LAUNCHED \
+CIRC_LAUNCHED_BAD_1 = '650 CIRC 7 LAUNCHED \
 BUILD_FLAGS=NEED_CAPACITY \
 PURPOSE=GENERAL \
-TIME_CREATED=20121108T164838417238"
+TIME_CREATED=20121108T164838417238'
 
-CIRC_LAUNCHED_BAD_2 = "650 CIRC toolong8901234567 LAUNCHED \
+CIRC_LAUNCHED_BAD_2 = '650 CIRC toolong8901234567 LAUNCHED \
 BUILD_FLAGS=NEED_CAPACITY \
 PURPOSE=GENERAL \
-TIME_CREATED=2012-11-08T16:48:38.417238"
+TIME_CREATED=2012-11-08T16:48:38.417238'
 
-CIRC_EXTENDED = "650 CIRC 7 EXTENDED \
+CIRC_EXTENDED = '650 CIRC 7 EXTENDED \
 $999A226EBED397F331B612FE1E4CFAE5C1F201BA=piyaz \
 BUILD_FLAGS=NEED_CAPACITY \
 PURPOSE=GENERAL \
-TIME_CREATED=2012-11-08T16:48:38.417238"
+TIME_CREATED=2012-11-08T16:48:38.417238'
 
-CIRC_FAILED = "650 CIRC 5 FAILED \
+CIRC_FAILED = '650 CIRC 5 FAILED \
 $E57A476CD4DFBD99B4EE52A100A58610AD6E80B9=ergebnisoffen \
 BUILD_FLAGS=NEED_CAPACITY \
 PURPOSE=GENERAL \
 TIME_CREATED=2012-11-08T16:48:36.400959 \
 REASON=DESTROYED \
-REMOTE_REASON=OR_CONN_CLOSED"
+REMOTE_REASON=OR_CONN_CLOSED'
 
 # CIRC events from tor v0.2.1.30 without the VERBOSE_NAMES feature
 
-CIRC_LAUNCHED_OLD = "650 CIRC 4 LAUNCHED"
-CIRC_EXTENDED_OLD = "650 CIRC 1 EXTENDED \
-$E57A476CD4DFBD99B4EE52A100A58610AD6E80B9,hamburgerphone"
-CIRC_BUILT_OLD = "650 CIRC 1 BUILT \
-$E57A476CD4DFBD99B4EE52A100A58610AD6E80B9,hamburgerphone,PrivacyRepublic14"
+CIRC_LAUNCHED_OLD = '650 CIRC 4 LAUNCHED'
+CIRC_EXTENDED_OLD = '650 CIRC 1 EXTENDED \
+$E57A476CD4DFBD99B4EE52A100A58610AD6E80B9,hamburgerphone'
+CIRC_BUILT_OLD = '650 CIRC 1 BUILT \
+$E57A476CD4DFBD99B4EE52A100A58610AD6E80B9,hamburgerphone,PrivacyRepublic14'
 
 # CIRC_MINOR event from tor 0.2.3.16.
 
-CIRC_MINOR_EVENT = "650 CIRC_MINOR 7 PURPOSE_CHANGED \
+CIRC_MINOR_EVENT = '650 CIRC_MINOR 7 PURPOSE_CHANGED \
 $67B2BDA4264D8A189D9270E28B1D30A262838243~europa1 \
 BUILD_FLAGS=IS_INTERNAL,NEED_CAPACITY \
 PURPOSE=MEASURE_TIMEOUT \
 TIME_CREATED=2012-12-03T16:45:33.409602 \
-OLD_PURPOSE=TESTING"
+OLD_PURPOSE=TESTING'
 
-CIRC_MINOR_EVENT_BAD_1 = "650 CIRC_MINOR 7 PURPOSE_CHANGED \
+CIRC_MINOR_EVENT_BAD_1 = '650 CIRC_MINOR 7 PURPOSE_CHANGED \
 $67B2BDA4264D8A189D9270E28B1D30A262838243~europa1 \
 BUILD_FLAGS=IS_INTERNAL,NEED_CAPACITY \
 PURPOSE=MEASURE_TIMEOUT \
 TIME_CREATED=20121203T164533409602 \
-OLD_PURPOSE=TESTING"
+OLD_PURPOSE=TESTING'
 
-CIRC_MINOR_EVENT_BAD_2 = "650 CIRC_MINOR toolong8901234567 PURPOSE_CHANGED \
+CIRC_MINOR_EVENT_BAD_2 = '650 CIRC_MINOR toolong8901234567 PURPOSE_CHANGED \
 $67B2BDA4264D8A189D9270E28B1D30A262838243~europa1 \
 BUILD_FLAGS=IS_INTERNAL,NEED_CAPACITY \
 PURPOSE=MEASURE_TIMEOUT \
 TIME_CREATED=2012-12-03T16:45:33.409602 \
-OLD_PURPOSE=TESTING"
+OLD_PURPOSE=TESTING'
 
 # CLIENTS_SEEN example from the spec
 
@@ -188,15 +188,15 @@ CONF_CHANGED_EVENT = """650-CONF_CHANGED
 
 # GUARD events from tor v0.2.1.30.
 
-GUARD_NEW = "650 GUARD ENTRY $36B5DBA788246E8369DBAF58577C6BC044A9A374 NEW"
-GUARD_GOOD = "650 GUARD ENTRY $5D0034A368E0ABAF663D21847E1C9B6CFA09752A GOOD"
-GUARD_BAD = "650 GUARD ENTRY $5D0034A368E0ABAF663D21847E1C9B6CFA09752A=caerSidi BAD"
+GUARD_NEW = '650 GUARD ENTRY $36B5DBA788246E8369DBAF58577C6BC044A9A374 NEW'
+GUARD_GOOD = '650 GUARD ENTRY $5D0034A368E0ABAF663D21847E1C9B6CFA09752A GOOD'
+GUARD_BAD = '650 GUARD ENTRY $5D0034A368E0ABAF663D21847E1C9B6CFA09752A=caerSidi BAD'
 
-HS_DESC_EVENT = "650 HS_DESC REQUESTED ajhb7kljbiru65qo NO_AUTH \
-$67B2BDA4264D8A189D9270E28B1D30A262838243=europa1 b3oeducbhjmbqmgw2i3jtz4fekkrinwj"
+HS_DESC_EVENT = '650 HS_DESC REQUESTED ajhb7kljbiru65qo NO_AUTH \
+$67B2BDA4264D8A189D9270E28B1D30A262838243=europa1 b3oeducbhjmbqmgw2i3jtz4fekkrinwj'
 
-HS_DESC_NO_DESC_ID = "650 HS_DESC REQUESTED ajhb7kljbiru65qo NO_AUTH \
-$67B2BDA4264D8A189D9270E28B1D30A262838243"
+HS_DESC_NO_DESC_ID = '650 HS_DESC REQUESTED ajhb7kljbiru65qo NO_AUTH \
+$67B2BDA4264D8A189D9270E28B1D30A262838243'
 
 # NEWCONSENSUS event from v0.2.1.30.
 
@@ -212,9 +212,9 @@ s Fast Guard Running Stable Valid
 # NEWDESC events. I've never actually seen multiple descriptors in an event,
 # but the spec allows for it.
 
-NEWDESC_SINGLE = "650 NEWDESC $B3FA3110CC6F42443F039220C134CBD2FC4F0493=Sakura"
-NEWDESC_MULTIPLE = "650 NEWDESC $BE938957B2CA5F804B3AFC2C1EE6673170CDBBF8=Moonshine \
-$B4BE08B22D4D2923EDC3970FD1B93D0448C6D8FF~Unnamed"
+NEWDESC_SINGLE = '650 NEWDESC $B3FA3110CC6F42443F039220C134CBD2FC4F0493=Sakura'
+NEWDESC_MULTIPLE = '650 NEWDESC $BE938957B2CA5F804B3AFC2C1EE6673170CDBBF8=Moonshine \
+$B4BE08B22D4D2923EDC3970FD1B93D0448C6D8FF~Unnamed'
 
 # NS event from tor v0.2.1.30.
 
@@ -227,22 +227,22 @@ s Fast HSDir Named Stable V2Dir Valid
 
 # ORCONN events from starting tor 0.2.2.39 via TBB
 
-ORCONN_CLOSED = "650 ORCONN $A1130635A0CDA6F60C276FBF6994EFBD4ECADAB1~tama CLOSED REASON=DONE"
-ORCONN_CONNECTED = "650 ORCONN 127.0.0.1:9000 CONNECTED NCIRCS=20 ID=18"
-ORCONN_LAUNCHED = "650 ORCONN $7ED90E2833EE38A75795BA9237B0A4560E51E1A0=GreenDragon LAUNCHED"
+ORCONN_CLOSED = '650 ORCONN $A1130635A0CDA6F60C276FBF6994EFBD4ECADAB1~tama CLOSED REASON=DONE'
+ORCONN_CONNECTED = '650 ORCONN 127.0.0.1:9000 CONNECTED NCIRCS=20 ID=18'
+ORCONN_LAUNCHED = '650 ORCONN $7ED90E2833EE38A75795BA9237B0A4560E51E1A0=GreenDragon LAUNCHED'
 
-ORCONN_BAD_1 = "650 ORCONN $7ED90E2833EE38A75795BA9237B0A4560E5=GreenD LAUNCHED"
-ORCONN_BAD_2 = "650 ORCONN 127.0.0.1:001 CONNECTED"
-ORCONN_BAD_3 = "650 ORCONN 127.0.0.1:9000 CONNECTED NCIRCS=too_many"
-ORCONN_BAD_4 = "650 ORCONN 127.0.0.1:9000 CONNECTED NCIRCS=20 ID=30635A0CDA6F60C276FBF6994EFBD4ECADA"
+ORCONN_BAD_1 = '650 ORCONN $7ED90E2833EE38A75795BA9237B0A4560E5=GreenD LAUNCHED'
+ORCONN_BAD_2 = '650 ORCONN 127.0.0.1:001 CONNECTED'
+ORCONN_BAD_3 = '650 ORCONN 127.0.0.1:9000 CONNECTED NCIRCS=too_many'
+ORCONN_BAD_4 = '650 ORCONN 127.0.0.1:9000 CONNECTED NCIRCS=20 ID=30635A0CDA6F60C276FBF6994EFBD4ECADA'
 
 # STATUS_* events that I was able to easily trigger. Most came from starting
 # TBB, then listening while it bootstrapped.
 
-STATUS_GENERAL_CONSENSUS_ARRIVED = "650 STATUS_GENERAL NOTICE CONSENSUS_ARRIVED"
+STATUS_GENERAL_CONSENSUS_ARRIVED = '650 STATUS_GENERAL NOTICE CONSENSUS_ARRIVED'
 
-STATUS_CLIENT_ENOUGH_DIR_INFO = "650 STATUS_CLIENT NOTICE ENOUGH_DIR_INFO"
-STATUS_CLIENT_CIRC_ESTABLISHED = "650 STATUS_CLIENT NOTICE CIRCUIT_ESTABLISHED"
+STATUS_CLIENT_ENOUGH_DIR_INFO = '650 STATUS_CLIENT NOTICE ENOUGH_DIR_INFO'
+STATUS_CLIENT_CIRC_ESTABLISHED = '650 STATUS_CLIENT NOTICE CIRCUIT_ESTABLISHED'
 
 STATUS_CLIENT_BOOTSTRAP_DESCRIPTORS = '650 STATUS_CLIENT NOTICE BOOTSTRAP \
 PROGRESS=53 \
@@ -278,78 +278,78 @@ PROGRESS=100 \
 TAG=done \
 SUMMARY="Done"'
 
-STATUS_SERVER_CHECK_REACHABILITY = "650 STATUS_SERVER NOTICE CHECKING_REACHABILITY \
-ORADDRESS=71.35.143.230:9050"
+STATUS_SERVER_CHECK_REACHABILITY = '650 STATUS_SERVER NOTICE CHECKING_REACHABILITY \
+ORADDRESS=71.35.143.230:9050'
 
 STATUS_SERVER_DNS_TIMEOUT = '650 STATUS_SERVER NOTICE NAMESERVER_STATUS \
 NS=205.171.3.25 \
 STATUS=DOWN \
 ERR="request timed out."'
 
-STATUS_SERVER_DNS_DOWN = "650 STATUS_SERVER WARN NAMESERVER_ALL_DOWN"
+STATUS_SERVER_DNS_DOWN = '650 STATUS_SERVER WARN NAMESERVER_ALL_DOWN'
 
-STATUS_SERVER_DNS_UP = "650 STATUS_SERVER NOTICE NAMESERVER_STATUS \
+STATUS_SERVER_DNS_UP = '650 STATUS_SERVER NOTICE NAMESERVER_STATUS \
 NS=205.171.3.25 \
-STATUS=UP"
+STATUS=UP'
 
 # unknown STATUS_* event type
-STATUS_SPECIFIC_CONSENSUS_ARRIVED = "650 STATUS_SPECIFIC NOTICE CONSENSUS_ARRIVED"
+STATUS_SPECIFIC_CONSENSUS_ARRIVED = '650 STATUS_SPECIFIC NOTICE CONSENSUS_ARRIVED'
 
 # STREAM events from tor 0.2.3.16 for visiting the google front page
 
-STREAM_NEW = "650 STREAM 18 NEW 0 \
+STREAM_NEW = '650 STREAM 18 NEW 0 \
 encrypted.google.com:443 \
 SOURCE_ADDR=127.0.0.1:47849 \
-PURPOSE=USER"
+PURPOSE=USER'
 
-STREAM_SENTCONNECT = "650 STREAM 18 SENTCONNECT 26 encrypted.google.com:443"
-STREAM_REMAP = "650 STREAM 18 REMAP 26 74.125.227.129:443 SOURCE=EXIT"
-STREAM_SUCCEEDED = "650 STREAM 18 SUCCEEDED 26 74.125.227.129:443"
-STREAM_CLOSED_RESET = "650 STREAM 21 CLOSED 26 74.125.227.129:443 REASON=CONNRESET"
-STREAM_CLOSED_DONE = "650 STREAM 25 CLOSED 26 199.7.52.72:80 REASON=DONE"
+STREAM_SENTCONNECT = '650 STREAM 18 SENTCONNECT 26 encrypted.google.com:443'
+STREAM_REMAP = '650 STREAM 18 REMAP 26 74.125.227.129:443 SOURCE=EXIT'
+STREAM_SUCCEEDED = '650 STREAM 18 SUCCEEDED 26 74.125.227.129:443'
+STREAM_CLOSED_RESET = '650 STREAM 21 CLOSED 26 74.125.227.129:443 REASON=CONNRESET'
+STREAM_CLOSED_DONE = '650 STREAM 25 CLOSED 26 199.7.52.72:80 REASON=DONE'
 
-STREAM_DIR_FETCH = "650 STREAM 14 NEW 0 \
+STREAM_DIR_FETCH = '650 STREAM 14 NEW 0 \
 176.28.51.238.$649F2D0ACF418F7CFC6539AB2257EB2D5297BAFA.exit:443 \
-SOURCE_ADDR=(Tor_internal):0 PURPOSE=DIR_FETCH"
+SOURCE_ADDR=(Tor_internal):0 PURPOSE=DIR_FETCH'
 
-STREAM_DNS_REQUEST = "650 STREAM 1113 NEW 0 www.google.com:0 \
+STREAM_DNS_REQUEST = '650 STREAM 1113 NEW 0 www.google.com:0 \
 SOURCE_ADDR=127.0.0.1:15297 \
-PURPOSE=DNS_REQUEST"
+PURPOSE=DNS_REQUEST'
 
-STREAM_SENTCONNECT_BAD_1 = "650 STREAM 18 SENTCONNECT 26"
-STREAM_SENTCONNECT_BAD_2 = "650 STREAM 18 SENTCONNECT 26 encrypted.google.com"
-STREAM_SENTCONNECT_BAD_3 = "650 STREAM 18 SENTCONNECT 26 encrypted.google.com:https"
+STREAM_SENTCONNECT_BAD_1 = '650 STREAM 18 SENTCONNECT 26'
+STREAM_SENTCONNECT_BAD_2 = '650 STREAM 18 SENTCONNECT 26 encrypted.google.com'
+STREAM_SENTCONNECT_BAD_3 = '650 STREAM 18 SENTCONNECT 26 encrypted.google.com:https'
 
-STREAM_DNS_REQUEST_BAD_1 = "650 STREAM 1113 NEW 0 www.google.com:0 \
+STREAM_DNS_REQUEST_BAD_1 = '650 STREAM 1113 NEW 0 www.google.com:0 \
 SOURCE_ADDR=127.0.0.1 \
-PURPOSE=DNS_REQUEST"
+PURPOSE=DNS_REQUEST'
 
-STREAM_DNS_REQUEST_BAD_2 = "650 STREAM 1113 NEW 0 www.google.com:0 \
+STREAM_DNS_REQUEST_BAD_2 = '650 STREAM 1113 NEW 0 www.google.com:0 \
 SOURCE_ADDR=127.0.0.1:dns \
-PURPOSE=DNS_REQUEST"
+PURPOSE=DNS_REQUEST'
 
-STREAM_NEWRESOLVE_IP6 = "650 STREAM 23 NEWRESOLVE 0 2001:db8::1:0 PURPOSE=DNS_REQUEST"
+STREAM_NEWRESOLVE_IP6 = '650 STREAM 23 NEWRESOLVE 0 2001:db8::1:0 PURPOSE=DNS_REQUEST'
 
-TRANSPORT_LAUNCHED = "650 TRANSPORT_LAUNCHED server obfs1 127.0.0.1 1111"
-TRANSPORT_LAUNCHED_BAD_TYPE = "650 TRANSPORT_LAUNCHED unicorn obfs1 127.0.0.1 1111"
-TRANSPORT_LAUNCHED_BAD_ADDRESS = "650 TRANSPORT_LAUNCHED server obfs1 127.0.x.y 1111"
-TRANSPORT_LAUNCHED_BAD_PORT = "650 TRANSPORT_LAUNCHED server obfs1 127.0.0.1 my_port"
+TRANSPORT_LAUNCHED = '650 TRANSPORT_LAUNCHED server obfs1 127.0.0.1 1111'
+TRANSPORT_LAUNCHED_BAD_TYPE = '650 TRANSPORT_LAUNCHED unicorn obfs1 127.0.0.1 1111'
+TRANSPORT_LAUNCHED_BAD_ADDRESS = '650 TRANSPORT_LAUNCHED server obfs1 127.0.x.y 1111'
+TRANSPORT_LAUNCHED_BAD_PORT = '650 TRANSPORT_LAUNCHED server obfs1 127.0.0.1 my_port'
 
-CONN_BW = "650 CONN_BW ID=11 TYPE=DIR READ=272 WRITTEN=817"
-CONN_BW_BAD_WRITTEN_VALUE = "650 CONN_BW ID=11 TYPE=DIR READ=272 WRITTEN=817.7"
-CONN_BW_BAD_MISSING_ID = "650 CONN_BW TYPE=DIR READ=272 WRITTEN=817"
+CONN_BW = '650 CONN_BW ID=11 TYPE=DIR READ=272 WRITTEN=817'
+CONN_BW_BAD_WRITTEN_VALUE = '650 CONN_BW ID=11 TYPE=DIR READ=272 WRITTEN=817.7'
+CONN_BW_BAD_MISSING_ID = '650 CONN_BW TYPE=DIR READ=272 WRITTEN=817'
 
-CIRC_BW = "650 CIRC_BW ID=11 READ=272 WRITTEN=817"
-CIRC_BW_BAD_WRITTEN_VALUE = "650 CIRC_BW ID=11 READ=272 WRITTEN=817.7"
-CIRC_BW_BAD_MISSING_ID = "650 CIRC_BW READ=272 WRITTEN=817"
+CIRC_BW = '650 CIRC_BW ID=11 READ=272 WRITTEN=817'
+CIRC_BW_BAD_WRITTEN_VALUE = '650 CIRC_BW ID=11 READ=272 WRITTEN=817.7'
+CIRC_BW_BAD_MISSING_ID = '650 CIRC_BW READ=272 WRITTEN=817'
 
-CELL_STATS_1 = "650 CELL_STATS ID=14 \
+CELL_STATS_1 = '650 CELL_STATS ID=14 \
 OutboundQueue=19403 OutboundConn=15 \
 OutboundAdded=create_fast:1,relay_early:2 \
 OutboundRemoved=create_fast:1,relay_early:2 \
-OutboundTime=create_fast:0,relay_early:0"
+OutboundTime=create_fast:0,relay_early:0'
 
-CELL_STATS_2 = "650 CELL_STATS \
+CELL_STATS_2 = '650 CELL_STATS \
 InboundQueue=19403 InboundConn=32 \
 InboundAdded=relay:1,created_fast:1 \
 InboundRemoved=relay:1,created_fast:1 \
@@ -357,23 +357,23 @@ InboundTime=relay:0,created_fast:0 \
 OutboundQueue=6710 OutboundConn=18 \
 OutboundAdded=create:1,relay_early:1 \
 OutboundRemoved=create:1,relay_early:1 \
-OutboundTime=create:0,relay_early:0"
+OutboundTime=create:0,relay_early:0'
 
-CELL_STATS_BAD_1 = "650 CELL_STATS OutboundAdded=create_fast:-1,relay_early:2"
-CELL_STATS_BAD_2 = "650 CELL_STATS OutboundAdded=create_fast:arg,relay_early:-2"
-CELL_STATS_BAD_3 = "650 CELL_STATS OutboundAdded=create_fast!:1,relay_early:-2"
+CELL_STATS_BAD_1 = '650 CELL_STATS OutboundAdded=create_fast:-1,relay_early:2'
+CELL_STATS_BAD_2 = '650 CELL_STATS OutboundAdded=create_fast:arg,relay_early:-2'
+CELL_STATS_BAD_3 = '650 CELL_STATS OutboundAdded=create_fast!:1,relay_early:-2'
 
-TB_EMPTY_1 = "650 TB_EMPTY ORCONN ID=16 READ=0 WRITTEN=0 LAST=100"
-TB_EMPTY_2 = "650 TB_EMPTY GLOBAL READ=93 WRITTEN=93 LAST=100"
-TB_EMPTY_3 = "650 TB_EMPTY RELAY READ=93 WRITTEN=93 LAST=100"
+TB_EMPTY_1 = '650 TB_EMPTY ORCONN ID=16 READ=0 WRITTEN=0 LAST=100'
+TB_EMPTY_2 = '650 TB_EMPTY GLOBAL READ=93 WRITTEN=93 LAST=100'
+TB_EMPTY_3 = '650 TB_EMPTY RELAY READ=93 WRITTEN=93 LAST=100'
 
-TB_EMPTY_BAD_1 = "650 TB_EMPTY GLOBAL READ=93 WRITTEN=blarg LAST=100"
-TB_EMPTY_BAD_2 = "650 TB_EMPTY GLOBAL READ=93 WRITTEN=93 LAST=-100"
+TB_EMPTY_BAD_1 = '650 TB_EMPTY GLOBAL READ=93 WRITTEN=blarg LAST=100'
+TB_EMPTY_BAD_2 = '650 TB_EMPTY GLOBAL READ=93 WRITTEN=93 LAST=-100'
 
 
 def _get_event(content):
   controller_event = mocking.get_message(content)
-  stem.response.convert("EVENT", controller_event)
+  stem.response.convert('EVENT', controller_event)
   return controller_event
 
 
@@ -387,12 +387,12 @@ class TestEvents(unittest.TestCase):
     from stem.control import Controller, EventType
 
     def print_bw(event):
-      msg = "sent: %i, received: %i" % (event.written, event.read)
-      self.assertEqual("sent: 25, received: 15", msg)
+      msg = 'sent: %i, received: %i' % (event.written, event.read)
+      self.assertEqual('sent: 25, received: 15', msg)
 
     def event_sender():
       for index in xrange(3):
-        print_bw(_get_event("650 BW 15 25"))
+        print_bw(_get_event('650 BW 15 25'))
         time.sleep(0.05)
 
     controller = Mock(spec = Controller)
@@ -407,40 +407,40 @@ class TestEvents(unittest.TestCase):
 
   def test_event(self):
     # synthetic, contrived message construction to reach the blank event check
-    self.assertRaises(ProtocolError, stem.response.convert, "EVENT", stem.response.ControlMessage([('', '', '')], ''))
+    self.assertRaises(ProtocolError, stem.response.convert, 'EVENT', stem.response.ControlMessage([('', '', '')], ''))
 
     # Event._parse_message() on an unknown event type
     event = _get_event('650 NONE SOLID "NON SENSE" condition=MEH quoted="1 2 3"')
-    self.assertEqual("NONE", event.type)
-    self.assertEqual(["SOLID", '"NON', 'SENSE"'], event.positional_args)
-    self.assertEqual({"condition": "MEH", "quoted": "1 2 3"}, event.keyword_args)
+    self.assertEqual('NONE', event.type)
+    self.assertEqual(['SOLID', '"NON', 'SENSE"'], event.positional_args)
+    self.assertEqual({'condition': 'MEH', 'quoted': '1 2 3'}, event.keyword_args)
 
   def test_log_events(self):
-    event = _get_event("650 DEBUG connection_edge_process_relay_cell(): Got an extended cell! Yay.")
+    event = _get_event('650 DEBUG connection_edge_process_relay_cell(): Got an extended cell! Yay.')
 
     self.assertTrue(isinstance(event, stem.response.events.LogEvent))
-    self.assertEqual("DEBUG", event.runlevel)
-    self.assertEqual("connection_edge_process_relay_cell(): Got an extended cell! Yay.", event.message)
+    self.assertEqual('DEBUG', event.runlevel)
+    self.assertEqual('connection_edge_process_relay_cell(): Got an extended cell! Yay.', event.message)
 
-    event = _get_event("650 INFO circuit_finish_handshake(): Finished building circuit hop:")
+    event = _get_event('650 INFO circuit_finish_handshake(): Finished building circuit hop:')
 
     self.assertTrue(isinstance(event, stem.response.events.LogEvent))
-    self.assertEqual("INFO", event.runlevel)
-    self.assertEqual("circuit_finish_handshake(): Finished building circuit hop:", event.message)
+    self.assertEqual('INFO', event.runlevel)
+    self.assertEqual('circuit_finish_handshake(): Finished building circuit hop:', event.message)
 
-    event = _get_event("650+WARN\na multi-line\nwarning message\n.\n650 OK\n")
+    event = _get_event('650+WARN\na multi-line\nwarning message\n.\n650 OK\n')
 
     self.assertTrue(isinstance(event, stem.response.events.LogEvent))
-    self.assertEqual("WARN", event.runlevel)
-    self.assertEqual("a multi-line\nwarning message", event.message)
+    self.assertEqual('WARN', event.runlevel)
+    self.assertEqual('a multi-line\nwarning message', event.message)
 
   def test_addrmap_event(self):
     event = _get_event(ADDRMAP)
 
     self.assertTrue(isinstance(event, stem.response.events.AddrMapEvent))
-    self.assertEqual(ADDRMAP.lstrip("650 "), str(event))
-    self.assertEqual("www.atagar.com", event.hostname)
-    self.assertEqual("75.119.206.243", event.destination)
+    self.assertEqual(ADDRMAP.lstrip('650 '), str(event))
+    self.assertEqual('www.atagar.com', event.hostname)
+    self.assertEqual('75.119.206.243', event.destination)
     self.assertEqual(datetime.datetime(2012, 11, 19, 0, 50, 13), event.expiry)
     self.assertEqual(None, event.error)
     self.assertEqual(datetime.datetime(2012, 11, 19, 8, 50, 13), event.utc_expiry)
@@ -448,9 +448,9 @@ class TestEvents(unittest.TestCase):
     event = _get_event(ADDRMAP_NO_EXPIRATION)
 
     self.assertTrue(isinstance(event, stem.response.events.AddrMapEvent))
-    self.assertEqual(ADDRMAP_NO_EXPIRATION.lstrip("650 "), str(event))
-    self.assertEqual("www.atagar.com", event.hostname)
-    self.assertEqual("75.119.206.243", event.destination)
+    self.assertEqual(ADDRMAP_NO_EXPIRATION.lstrip('650 '), str(event))
+    self.assertEqual('www.atagar.com', event.hostname)
+    self.assertEqual('75.119.206.243', event.destination)
     self.assertEqual(None, event.expiry)
     self.assertEqual(None, event.error)
     self.assertEqual(None, event.utc_expiry)
@@ -458,11 +458,11 @@ class TestEvents(unittest.TestCase):
     event = _get_event(ADDRMAP_ERROR_EVENT)
 
     self.assertTrue(isinstance(event, stem.response.events.AddrMapEvent))
-    self.assertEqual(ADDRMAP_ERROR_EVENT.lstrip("650 "), str(event))
-    self.assertEqual("www.atagar.com", event.hostname)
+    self.assertEqual(ADDRMAP_ERROR_EVENT.lstrip('650 '), str(event))
+    self.assertEqual('www.atagar.com', event.hostname)
     self.assertEqual(None, event.destination)
     self.assertEqual(datetime.datetime(2012, 11, 19, 0, 50, 13), event.expiry)
-    self.assertEqual("yes", event.error)
+    self.assertEqual('yes', event.error)
     self.assertEqual(datetime.datetime(2012, 11, 19, 8, 50, 13), event.utc_expiry)
     self.assertEqual(None, event.cached)
 
@@ -475,13 +475,13 @@ class TestEvents(unittest.TestCase):
     event = _get_event(ADDRMAP_CACHED)
 
     self.assertTrue(isinstance(event, stem.response.events.AddrMapEvent))
-    self.assertEqual("example.com", event.hostname)
+    self.assertEqual('example.com', event.hostname)
     self.assertEqual(True, event.cached)
 
     event = _get_event(ADDRMAP_NOT_CACHED)
 
     self.assertTrue(isinstance(event, stem.response.events.AddrMapEvent))
-    self.assertEqual("example.com", event.hostname)
+    self.assertEqual('example.com', event.hostname)
     self.assertEqual(False, event.cached)
 
     # the CACHED argument should only allow YES or NO
@@ -490,7 +490,7 @@ class TestEvents(unittest.TestCase):
   def test_authdir_newdesc_event(self):
     # TODO: awaiting test data - https://trac.torproject.org/7534
 
-    event = _get_event("650+AUTHDIR_NEWDESCS\nAction\nMessage\nDescriptor\n.\n650 OK\n")
+    event = _get_event('650+AUTHDIR_NEWDESCS\nAction\nMessage\nDescriptor\n.\n650 OK\n')
 
     self.assertTrue(isinstance(event, stem.response.events.AuthDirNewDescEvent))
     self.assertEqual([], event.positional_args)
@@ -500,7 +500,7 @@ class TestEvents(unittest.TestCase):
     event = _get_event(BUILD_TIMEOUT_EVENT)
 
     self.assertTrue(isinstance(event, stem.response.events.BuildTimeoutSetEvent))
-    self.assertEqual(BUILD_TIMEOUT_EVENT.lstrip("650 "), str(event))
+    self.assertEqual(BUILD_TIMEOUT_EVENT.lstrip('650 '), str(event))
     self.assertEqual(TimeoutSetType.COMPUTED, event.set_type)
     self.assertEqual(124, event.total_times)
     self.assertEqual(9019, event.timeout)
@@ -516,13 +516,13 @@ class TestEvents(unittest.TestCase):
     self.assertRaises(ProtocolError, _get_event, BUILD_TIMEOUT_EVENT_BAD_2)
 
   def test_bw_event(self):
-    event = _get_event("650 BW 15 25")
+    event = _get_event('650 BW 15 25')
 
     self.assertTrue(isinstance(event, stem.response.events.BandwidthEvent))
     self.assertEqual(15, event.read)
     self.assertEqual(25, event.written)
 
-    event = _get_event("650 BW 0 0")
+    event = _get_event('650 BW 0 0')
     self.assertEqual(0, event.read)
     self.assertEqual(0, event.written)
 
@@ -531,23 +531,23 @@ class TestEvents(unittest.TestCase):
     # since tor doesn't actually do it yet (and likely never will), but might
     # as well sanity test that it'll be ok.
 
-    event = _get_event("650 BW 10 20 OR=5 EXIT=500")
+    event = _get_event('650 BW 10 20 OR=5 EXIT=500')
     self.assertEqual(10, event.read)
     self.assertEqual(20, event.written)
     self.assertEqual({'OR': '5', 'EXIT': '500'}, event.keyword_args)
 
-    self.assertRaises(ProtocolError, _get_event, "650 BW")
-    self.assertRaises(ProtocolError, _get_event, "650 BW 15")
-    self.assertRaises(ProtocolError, _get_event, "650 BW -15 25")
-    self.assertRaises(ProtocolError, _get_event, "650 BW 15 -25")
-    self.assertRaises(ProtocolError, _get_event, "650 BW x 25")
+    self.assertRaises(ProtocolError, _get_event, '650 BW')
+    self.assertRaises(ProtocolError, _get_event, '650 BW 15')
+    self.assertRaises(ProtocolError, _get_event, '650 BW -15 25')
+    self.assertRaises(ProtocolError, _get_event, '650 BW 15 -25')
+    self.assertRaises(ProtocolError, _get_event, '650 BW x 25')
 
   def test_circ_event(self):
     event = _get_event(CIRC_LAUNCHED)
 
     self.assertTrue(isinstance(event, stem.response.events.CircuitEvent))
-    self.assertEqual(CIRC_LAUNCHED.lstrip("650 "), str(event))
-    self.assertEqual("7", event.id)
+    self.assertEqual(CIRC_LAUNCHED.lstrip('650 '), str(event))
+    self.assertEqual('7', event.id)
     self.assertEqual(CircStatus.LAUNCHED, event.status)
     self.assertEqual((), event.path)
     self.assertEqual((CircBuildFlag.NEED_CAPACITY,), event.build_flags)
@@ -561,10 +561,10 @@ class TestEvents(unittest.TestCase):
     event = _get_event(CIRC_EXTENDED)
 
     self.assertTrue(isinstance(event, stem.response.events.CircuitEvent))
-    self.assertEqual(CIRC_EXTENDED.lstrip("650 "), str(event))
-    self.assertEqual("7", event.id)
+    self.assertEqual(CIRC_EXTENDED.lstrip('650 '), str(event))
+    self.assertEqual('7', event.id)
     self.assertEqual(CircStatus.EXTENDED, event.status)
-    self.assertEqual((("999A226EBED397F331B612FE1E4CFAE5C1F201BA", "piyaz"),), event.path)
+    self.assertEqual((('999A226EBED397F331B612FE1E4CFAE5C1F201BA', 'piyaz'),), event.path)
     self.assertEqual((CircBuildFlag.NEED_CAPACITY,), event.build_flags)
     self.assertEqual(CircPurpose.GENERAL, event.purpose)
     self.assertEqual(None, event.hs_state)
@@ -576,10 +576,10 @@ class TestEvents(unittest.TestCase):
     event = _get_event(CIRC_FAILED)
 
     self.assertTrue(isinstance(event, stem.response.events.CircuitEvent))
-    self.assertEqual(CIRC_FAILED.lstrip("650 "), str(event))
-    self.assertEqual("5", event.id)
+    self.assertEqual(CIRC_FAILED.lstrip('650 '), str(event))
+    self.assertEqual('5', event.id)
     self.assertEqual(CircStatus.FAILED, event.status)
-    self.assertEqual((("E57A476CD4DFBD99B4EE52A100A58610AD6E80B9", "ergebnisoffen"),), event.path)
+    self.assertEqual((('E57A476CD4DFBD99B4EE52A100A58610AD6E80B9', 'ergebnisoffen'),), event.path)
     self.assertEqual((CircBuildFlag.NEED_CAPACITY,), event.build_flags)
     self.assertEqual(CircPurpose.GENERAL, event.purpose)
     self.assertEqual(None, event.hs_state)
@@ -591,8 +591,8 @@ class TestEvents(unittest.TestCase):
     event = _get_event(CIRC_LAUNCHED_OLD)
 
     self.assertTrue(isinstance(event, stem.response.events.CircuitEvent))
-    self.assertEqual(CIRC_LAUNCHED_OLD.lstrip("650 "), str(event))
-    self.assertEqual("4", event.id)
+    self.assertEqual(CIRC_LAUNCHED_OLD.lstrip('650 '), str(event))
+    self.assertEqual('4', event.id)
     self.assertEqual(CircStatus.LAUNCHED, event.status)
     self.assertEqual((), event.path)
     self.assertEqual(None, event.build_flags)
@@ -606,10 +606,10 @@ class TestEvents(unittest.TestCase):
     event = _get_event(CIRC_EXTENDED_OLD)
 
     self.assertTrue(isinstance(event, stem.response.events.CircuitEvent))
-    self.assertEqual(CIRC_EXTENDED_OLD.lstrip("650 "), str(event))
-    self.assertEqual("1", event.id)
+    self.assertEqual(CIRC_EXTENDED_OLD.lstrip('650 '), str(event))
+    self.assertEqual('1', event.id)
     self.assertEqual(CircStatus.EXTENDED, event.status)
-    self.assertEqual((("E57A476CD4DFBD99B4EE52A100A58610AD6E80B9", None), (None, "hamburgerphone")), event.path)
+    self.assertEqual((('E57A476CD4DFBD99B4EE52A100A58610AD6E80B9', None), (None, 'hamburgerphone')), event.path)
     self.assertEqual(None, event.build_flags)
     self.assertEqual(None, event.purpose)
     self.assertEqual(None, event.hs_state)
@@ -621,10 +621,10 @@ class TestEvents(unittest.TestCase):
     event = _get_event(CIRC_BUILT_OLD)
 
     self.assertTrue(isinstance(event, stem.response.events.CircuitEvent))
-    self.assertEqual(CIRC_BUILT_OLD.lstrip("650 "), str(event))
-    self.assertEqual("1", event.id)
+    self.assertEqual(CIRC_BUILT_OLD.lstrip('650 '), str(event))
+    self.assertEqual('1', event.id)
     self.assertEqual(CircStatus.BUILT, event.status)
-    self.assertEqual((("E57A476CD4DFBD99B4EE52A100A58610AD6E80B9", None), (None, "hamburgerphone"), (None, "PrivacyRepublic14")), event.path)
+    self.assertEqual((('E57A476CD4DFBD99B4EE52A100A58610AD6E80B9', None), (None, 'hamburgerphone'), (None, 'PrivacyRepublic14')), event.path)
     self.assertEqual(None, event.build_flags)
     self.assertEqual(None, event.purpose)
     self.assertEqual(None, event.hs_state)
@@ -643,10 +643,10 @@ class TestEvents(unittest.TestCase):
     event = _get_event(CIRC_MINOR_EVENT)
 
     self.assertTrue(isinstance(event, stem.response.events.CircMinorEvent))
-    self.assertEqual(CIRC_MINOR_EVENT.lstrip("650 "), str(event))
-    self.assertEqual("7", event.id)
+    self.assertEqual(CIRC_MINOR_EVENT.lstrip('650 '), str(event))
+    self.assertEqual('7', event.id)
     self.assertEqual(CircEvent.PURPOSE_CHANGED, event.event)
-    self.assertEqual((("67B2BDA4264D8A189D9270E28B1D30A262838243", "europa1"),), event.path)
+    self.assertEqual((('67B2BDA4264D8A189D9270E28B1D30A262838243', 'europa1'),), event.path)
     self.assertEqual((CircBuildFlag.IS_INTERNAL, CircBuildFlag.NEED_CAPACITY), event.build_flags)
     self.assertEqual(CircPurpose.MEASURE_TIMEOUT, event.purpose)
     self.assertEqual(None, event.hs_state)
@@ -665,7 +665,7 @@ class TestEvents(unittest.TestCase):
     event = _get_event(CLIENTS_SEEN_EVENT)
 
     self.assertTrue(isinstance(event, stem.response.events.ClientsSeenEvent))
-    self.assertEqual(CLIENTS_SEEN_EVENT.lstrip("650 "), str(event))
+    self.assertEqual(CLIENTS_SEEN_EVENT.lstrip('650 '), str(event))
     self.assertEqual(datetime.datetime(2008, 12, 25, 23, 50, 43), event.start_time)
     self.assertEqual({'us': 16, 'de': 8, 'uk': 8}, event.locales)
     self.assertEqual({'v4': 16, 'v6': 40}, event.ip_versions)
@@ -704,10 +704,10 @@ class TestEvents(unittest.TestCase):
     # all we can check for is that the event is properly parsed as a
     # DescChangedEvent instance
 
-    event = _get_event("650 DESCCHANGED")
+    event = _get_event('650 DESCCHANGED')
 
     self.assertTrue(isinstance(event, stem.response.events.DescChangedEvent))
-    self.assertEqual("DESCCHANGED", str(event))
+    self.assertEqual('DESCCHANGED', str(event))
     self.assertEqual([], event.positional_args)
     self.assertEqual({}, event.keyword_args)
 
@@ -715,74 +715,74 @@ class TestEvents(unittest.TestCase):
     event = _get_event(GUARD_NEW)
 
     self.assertTrue(isinstance(event, stem.response.events.GuardEvent))
-    self.assertEqual(GUARD_NEW.lstrip("650 "), str(event))
+    self.assertEqual(GUARD_NEW.lstrip('650 '), str(event))
     self.assertEqual(GuardType.ENTRY, event.guard_type)
-    self.assertEqual("$36B5DBA788246E8369DBAF58577C6BC044A9A374", event.endpoint)
-    self.assertEqual("36B5DBA788246E8369DBAF58577C6BC044A9A374", event.endpoint_fingerprint)
+    self.assertEqual('$36B5DBA788246E8369DBAF58577C6BC044A9A374', event.endpoint)
+    self.assertEqual('36B5DBA788246E8369DBAF58577C6BC044A9A374', event.endpoint_fingerprint)
     self.assertEqual(None, event.endpoint_nickname)
     self.assertEqual(GuardStatus.NEW, event.status)
 
     event = _get_event(GUARD_GOOD)
     self.assertEqual(GuardType.ENTRY, event.guard_type)
-    self.assertEqual("$5D0034A368E0ABAF663D21847E1C9B6CFA09752A", event.endpoint)
-    self.assertEqual("5D0034A368E0ABAF663D21847E1C9B6CFA09752A", event.endpoint_fingerprint)
+    self.assertEqual('$5D0034A368E0ABAF663D21847E1C9B6CFA09752A', event.endpoint)
+    self.assertEqual('5D0034A368E0ABAF663D21847E1C9B6CFA09752A', event.endpoint_fingerprint)
     self.assertEqual(None, event.endpoint_nickname)
     self.assertEqual(GuardStatus.GOOD, event.status)
 
     event = _get_event(GUARD_BAD)
     self.assertEqual(GuardType.ENTRY, event.guard_type)
-    self.assertEqual("$5D0034A368E0ABAF663D21847E1C9B6CFA09752A=caerSidi", event.endpoint)
-    self.assertEqual("5D0034A368E0ABAF663D21847E1C9B6CFA09752A", event.endpoint_fingerprint)
-    self.assertEqual("caerSidi", event.endpoint_nickname)
+    self.assertEqual('$5D0034A368E0ABAF663D21847E1C9B6CFA09752A=caerSidi', event.endpoint)
+    self.assertEqual('5D0034A368E0ABAF663D21847E1C9B6CFA09752A', event.endpoint_fingerprint)
+    self.assertEqual('caerSidi', event.endpoint_nickname)
     self.assertEqual(GuardStatus.BAD, event.status)
 
   def test_hs_desc_event(self):
     event = _get_event(HS_DESC_EVENT)
 
     self.assertTrue(isinstance(event, stem.response.events.HSDescEvent))
-    self.assertEqual(HS_DESC_EVENT.lstrip("650 "), str(event))
+    self.assertEqual(HS_DESC_EVENT.lstrip('650 '), str(event))
     self.assertEqual(HSDescAction.REQUESTED, event.action)
-    self.assertEqual("ajhb7kljbiru65qo", event.address)
+    self.assertEqual('ajhb7kljbiru65qo', event.address)
     self.assertEqual(HSAuth.NO_AUTH, event.authentication)
-    self.assertEqual("$67B2BDA4264D8A189D9270E28B1D30A262838243=europa1", event.directory)
-    self.assertEqual("67B2BDA4264D8A189D9270E28B1D30A262838243", event.directory_fingerprint)
-    self.assertEqual("europa1", event.directory_nickname)
-    self.assertEqual("b3oeducbhjmbqmgw2i3jtz4fekkrinwj", event.descriptor_id)
+    self.assertEqual('$67B2BDA4264D8A189D9270E28B1D30A262838243=europa1', event.directory)
+    self.assertEqual('67B2BDA4264D8A189D9270E28B1D30A262838243', event.directory_fingerprint)
+    self.assertEqual('europa1', event.directory_nickname)
+    self.assertEqual('b3oeducbhjmbqmgw2i3jtz4fekkrinwj', event.descriptor_id)
 
     event = _get_event(HS_DESC_NO_DESC_ID)
 
-    self.assertEqual("$67B2BDA4264D8A189D9270E28B1D30A262838243", event.directory)
-    self.assertEqual("67B2BDA4264D8A189D9270E28B1D30A262838243", event.directory_fingerprint)
+    self.assertEqual('$67B2BDA4264D8A189D9270E28B1D30A262838243', event.directory)
+    self.assertEqual('67B2BDA4264D8A189D9270E28B1D30A262838243', event.directory_fingerprint)
     self.assertEqual(None, event.directory_nickname)
     self.assertEqual(None, event.descriptor_id)
 
   def test_newdesc_event(self):
     event = _get_event(NEWDESC_SINGLE)
-    expected_relays = (("B3FA3110CC6F42443F039220C134CBD2FC4F0493", "Sakura"),)
+    expected_relays = (('B3FA3110CC6F42443F039220C134CBD2FC4F0493', 'Sakura'),)
 
     self.assertTrue(isinstance(event, stem.response.events.NewDescEvent))
-    self.assertEqual(NEWDESC_SINGLE.lstrip("650 "), str(event))
+    self.assertEqual(NEWDESC_SINGLE.lstrip('650 '), str(event))
     self.assertEqual(expected_relays, event.relays)
 
     event = _get_event(NEWDESC_MULTIPLE)
-    expected_relays = (("BE938957B2CA5F804B3AFC2C1EE6673170CDBBF8", "Moonshine"),
-                       ("B4BE08B22D4D2923EDC3970FD1B93D0448C6D8FF", "Unnamed"))
+    expected_relays = (('BE938957B2CA5F804B3AFC2C1EE6673170CDBBF8', 'Moonshine'),
+                       ('B4BE08B22D4D2923EDC3970FD1B93D0448C6D8FF', 'Unnamed'))
 
     self.assertTrue(isinstance(event, stem.response.events.NewDescEvent))
-    self.assertEqual(NEWDESC_MULTIPLE.lstrip("650 "), str(event))
+    self.assertEqual(NEWDESC_MULTIPLE.lstrip('650 '), str(event))
     self.assertEqual(expected_relays, event.relays)
 
   def test_new_consensus_event(self):
     expected_desc = []
 
     expected_desc.append(mocking.get_router_status_entry_v3({
-      "r": "Beaver /96bKo4soysolMgKn5Hex2nyFSY pAJH9dSBp/CG6sPhhVY/5bLaVPM 2012-12-02 22:02:45 77.223.43.54 9001 0",
-      "s": "Fast Named Running Stable Valid",
+      'r': 'Beaver /96bKo4soysolMgKn5Hex2nyFSY pAJH9dSBp/CG6sPhhVY/5bLaVPM 2012-12-02 22:02:45 77.223.43.54 9001 0',
+      's': 'Fast Named Running Stable Valid',
     }))
 
     expected_desc.append(mocking.get_router_status_entry_v3({
-      "r": "Unnamed /+fJRWjmIGNAL2C5rRZHq3R91tA 7AnpZjfdBpYzXnMNm+w1bTsFF6Y 2012-12-02 17:51:10 91.121.184.87 9001 0",
-      "s": "Fast Guard Running Stable Valid",
+      'r': 'Unnamed /+fJRWjmIGNAL2C5rRZHq3R91tA 7AnpZjfdBpYzXnMNm+w1bTsFF6Y 2012-12-02 17:51:10 91.121.184.87 9001 0',
+      's': 'Fast Guard Running Stable Valid',
     }))
 
     event = _get_event(NEWCONSENSUS_EVENT)
@@ -792,8 +792,8 @@ class TestEvents(unittest.TestCase):
 
   def test_ns_event(self):
     expected_desc = mocking.get_router_status_entry_v3({
-      "r": "whnetz dbBxYcJriTTrcxsuy4PUZcMRwCA VStM7KAIH/mXXoGDUpoGB1OXufg 2012-12-02 21:03:56 141.70.120.13 9001 9030",
-      "s": "Fast HSDir Named Stable V2Dir Valid",
+      'r': 'whnetz dbBxYcJriTTrcxsuy4PUZcMRwCA VStM7KAIH/mXXoGDUpoGB1OXufg 2012-12-02 21:03:56 141.70.120.13 9001 9030',
+      's': 'Fast HSDir Named Stable V2Dir Valid',
     })
 
     event = _get_event(NS_EVENT)
@@ -805,10 +805,10 @@ class TestEvents(unittest.TestCase):
     event = _get_event(ORCONN_CLOSED)
 
     self.assertTrue(isinstance(event, stem.response.events.ORConnEvent))
-    self.assertEqual(ORCONN_CLOSED.lstrip("650 "), str(event))
-    self.assertEqual("$A1130635A0CDA6F60C276FBF6994EFBD4ECADAB1~tama", event.endpoint)
-    self.assertEqual("A1130635A0CDA6F60C276FBF6994EFBD4ECADAB1", event.endpoint_fingerprint)
-    self.assertEqual("tama", event.endpoint_nickname)
+    self.assertEqual(ORCONN_CLOSED.lstrip('650 '), str(event))
+    self.assertEqual('$A1130635A0CDA6F60C276FBF6994EFBD4ECADAB1~tama', event.endpoint)
+    self.assertEqual('A1130635A0CDA6F60C276FBF6994EFBD4ECADAB1', event.endpoint_fingerprint)
+    self.assertEqual('tama', event.endpoint_nickname)
     self.assertEqual(None, event.endpoint_address)
     self.assertEqual(None, event.endpoint_port)
     self.assertEqual(ORStatus.CLOSED, event.status)
@@ -819,8 +819,8 @@ class TestEvents(unittest.TestCase):
     event = _get_event(ORCONN_CONNECTED)
 
     self.assertTrue(isinstance(event, stem.response.events.ORConnEvent))
-    self.assertEqual(ORCONN_CONNECTED.lstrip("650 "), str(event))
-    self.assertEqual("127.0.0.1:9000", event.endpoint)
+    self.assertEqual(ORCONN_CONNECTED.lstrip('650 '), str(event))
+    self.assertEqual('127.0.0.1:9000', event.endpoint)
     self.assertEqual(None, event.endpoint_fingerprint)
     self.assertEqual(None, event.endpoint_nickname)
     self.assertEqual('127.0.0.1', event.endpoint_address)
@@ -833,10 +833,10 @@ class TestEvents(unittest.TestCase):
     event = _get_event(ORCONN_LAUNCHED)
 
     self.assertTrue(isinstance(event, stem.response.events.ORConnEvent))
-    self.assertEqual(ORCONN_LAUNCHED.lstrip("650 "), str(event))
-    self.assertEqual("$7ED90E2833EE38A75795BA9237B0A4560E51E1A0=GreenDragon", event.endpoint)
-    self.assertEqual("7ED90E2833EE38A75795BA9237B0A4560E51E1A0", event.endpoint_fingerprint)
-    self.assertEqual("GreenDragon", event.endpoint_nickname)
+    self.assertEqual(ORCONN_LAUNCHED.lstrip('650 '), str(event))
+    self.assertEqual('$7ED90E2833EE38A75795BA9237B0A4560E51E1A0=GreenDragon', event.endpoint)
+    self.assertEqual('7ED90E2833EE38A75795BA9237B0A4560E51E1A0', event.endpoint_fingerprint)
+    self.assertEqual('GreenDragon', event.endpoint_nickname)
     self.assertEqual(None, event.endpoint_address)
     self.assertEqual(None, event.endpoint_port)
     self.assertEqual(ORStatus.LAUNCHED, event.status)
@@ -856,43 +856,43 @@ class TestEvents(unittest.TestCase):
     self.assertRaises(ProtocolError, _get_event, ORCONN_BAD_4)
 
   def test_signal_event(self):
-    event = _get_event("650 SIGNAL DEBUG")
+    event = _get_event('650 SIGNAL DEBUG')
     self.assertTrue(isinstance(event, stem.response.events.SignalEvent))
-    self.assertEqual("SIGNAL DEBUG", str(event))
+    self.assertEqual('SIGNAL DEBUG', str(event))
     self.assertEqual(Signal.DEBUG, event.signal)
 
-    event = _get_event("650 SIGNAL DUMP")
+    event = _get_event('650 SIGNAL DUMP')
     self.assertEqual(Signal.DUMP, event.signal)
 
   def test_status_event_consensus_arrived(self):
     event = _get_event(STATUS_GENERAL_CONSENSUS_ARRIVED)
 
     self.assertTrue(isinstance(event, stem.response.events.StatusEvent))
-    self.assertEqual(STATUS_GENERAL_CONSENSUS_ARRIVED.lstrip("650 "), str(event))
+    self.assertEqual(STATUS_GENERAL_CONSENSUS_ARRIVED.lstrip('650 '), str(event))
     self.assertEqual(StatusType.GENERAL, event.status_type)
     self.assertEqual(Runlevel.NOTICE, event.runlevel)
-    self.assertEqual("CONSENSUS_ARRIVED", event.action)
+    self.assertEqual('CONSENSUS_ARRIVED', event.action)
 
   def test_status_event_enough_dir_info(self):
     event = _get_event(STATUS_CLIENT_ENOUGH_DIR_INFO)
 
     self.assertEqual(StatusType.CLIENT, event.status_type)
     self.assertEqual(Runlevel.NOTICE, event.runlevel)
-    self.assertEqual("ENOUGH_DIR_INFO", event.action)
+    self.assertEqual('ENOUGH_DIR_INFO', event.action)
 
   def test_status_event_circuit_established(self):
     event = _get_event(STATUS_CLIENT_CIRC_ESTABLISHED)
 
     self.assertEqual(StatusType.CLIENT, event.status_type)
     self.assertEqual(Runlevel.NOTICE, event.runlevel)
-    self.assertEqual("CIRCUIT_ESTABLISHED", event.action)
+    self.assertEqual('CIRCUIT_ESTABLISHED', event.action)
 
   def test_status_event_bootstrap_descriptors(self):
     event = _get_event(STATUS_CLIENT_BOOTSTRAP_DESCRIPTORS)
 
     self.assertEqual(StatusType.CLIENT, event.status_type)
     self.assertEqual(Runlevel.NOTICE, event.runlevel)
-    self.assertEqual("BOOTSTRAP", event.action)
+    self.assertEqual('BOOTSTRAP', event.action)
 
     expected_attr = {
       'PROGRESS': '53',
@@ -907,7 +907,7 @@ class TestEvents(unittest.TestCase):
 
     self.assertEqual(StatusType.CLIENT, event.status_type)
     self.assertEqual(Runlevel.WARN, event.runlevel)
-    self.assertEqual("BOOTSTRAP", event.action)
+    self.assertEqual('BOOTSTRAP', event.action)
 
     expected_attr = {
       'PROGRESS': '80',
@@ -926,7 +926,7 @@ class TestEvents(unittest.TestCase):
 
     self.assertEqual(StatusType.CLIENT, event.status_type)
     self.assertEqual(Runlevel.NOTICE, event.runlevel)
-    self.assertEqual("BOOTSTRAP", event.action)
+    self.assertEqual('BOOTSTRAP', event.action)
 
     expected_attr = {
       'PROGRESS': '80',
@@ -941,7 +941,7 @@ class TestEvents(unittest.TestCase):
 
     self.assertEqual(StatusType.CLIENT, event.status_type)
     self.assertEqual(Runlevel.NOTICE, event.runlevel)
-    self.assertEqual("BOOTSTRAP", event.action)
+    self.assertEqual('BOOTSTRAP', event.action)
 
     expected_attr = {
       'PROGRESS': '85',
@@ -956,7 +956,7 @@ class TestEvents(unittest.TestCase):
 
     self.assertEqual(StatusType.CLIENT, event.status_type)
     self.assertEqual(Runlevel.NOTICE, event.runlevel)
-    self.assertEqual("BOOTSTRAP", event.action)
+    self.assertEqual('BOOTSTRAP', event.action)
 
     expected_attr = {
       'PROGRESS': '90',
@@ -971,7 +971,7 @@ class TestEvents(unittest.TestCase):
 
     self.assertEqual(StatusType.CLIENT, event.status_type)
     self.assertEqual(Runlevel.NOTICE, event.runlevel)
-    self.assertEqual("BOOTSTRAP", event.action)
+    self.assertEqual('BOOTSTRAP', event.action)
 
     expected_attr = {
       'PROGRESS': '100',
@@ -986,7 +986,7 @@ class TestEvents(unittest.TestCase):
 
     self.assertEqual(StatusType.SERVER, event.status_type)
     self.assertEqual(Runlevel.NOTICE, event.runlevel)
-    self.assertEqual("CHECKING_REACHABILITY", event.action)
+    self.assertEqual('CHECKING_REACHABILITY', event.action)
 
     expected_attr = {
       'ORADDRESS': '71.35.143.230:9050',
@@ -999,7 +999,7 @@ class TestEvents(unittest.TestCase):
 
     self.assertEqual(StatusType.SERVER, event.status_type)
     self.assertEqual(Runlevel.NOTICE, event.runlevel)
-    self.assertEqual("NAMESERVER_STATUS", event.action)
+    self.assertEqual('NAMESERVER_STATUS', event.action)
 
     expected_attr = {
       'NS': '205.171.3.25',
@@ -1014,14 +1014,14 @@ class TestEvents(unittest.TestCase):
 
     self.assertEqual(StatusType.SERVER, event.status_type)
     self.assertEqual(Runlevel.WARN, event.runlevel)
-    self.assertEqual("NAMESERVER_ALL_DOWN", event.action)
+    self.assertEqual('NAMESERVER_ALL_DOWN', event.action)
 
   def test_status_event_dns_up(self):
     event = _get_event(STATUS_SERVER_DNS_UP)
 
     self.assertEqual(StatusType.SERVER, event.status_type)
     self.assertEqual(Runlevel.NOTICE, event.runlevel)
-    self.assertEqual("NAMESERVER_STATUS", event.action)
+    self.assertEqual('NAMESERVER_STATUS', event.action)
 
     expected_attr = {
       'NS': '205.171.3.25',
@@ -1040,30 +1040,30 @@ class TestEvents(unittest.TestCase):
     event = _get_event(STREAM_NEW)
 
     self.assertTrue(isinstance(event, stem.response.events.StreamEvent))
-    self.assertEqual(STREAM_NEW.lstrip("650 "), str(event))
-    self.assertEqual("18", event.id)
+    self.assertEqual(STREAM_NEW.lstrip('650 '), str(event))
+    self.assertEqual('18', event.id)
     self.assertEqual(StreamStatus.NEW, event.status)
     self.assertEqual(None, event.circ_id)
-    self.assertEqual("encrypted.google.com:443", event.target)
-    self.assertEqual("encrypted.google.com", event.target_address)
+    self.assertEqual('encrypted.google.com:443', event.target)
+    self.assertEqual('encrypted.google.com', event.target_address)
     self.assertEqual(443, event.target_port)
     self.assertEqual(None, event.reason)
     self.assertEqual(None, event.remote_reason)
     self.assertEqual(None, event.source)
-    self.assertEqual("127.0.0.1:47849", event.source_addr)
-    self.assertEqual("127.0.0.1", event.source_address)
+    self.assertEqual('127.0.0.1:47849', event.source_addr)
+    self.assertEqual('127.0.0.1', event.source_address)
     self.assertEqual(47849, event.source_port)
     self.assertEqual(StreamPurpose.USER, event.purpose)
 
     event = _get_event(STREAM_SENTCONNECT)
 
     self.assertTrue(isinstance(event, stem.response.events.StreamEvent))
-    self.assertEqual(STREAM_SENTCONNECT.lstrip("650 "), str(event))
-    self.assertEqual("18", event.id)
+    self.assertEqual(STREAM_SENTCONNECT.lstrip('650 '), str(event))
+    self.assertEqual('18', event.id)
     self.assertEqual(StreamStatus.SENTCONNECT, event.status)
-    self.assertEqual("26", event.circ_id)
-    self.assertEqual("encrypted.google.com:443", event.target)
-    self.assertEqual("encrypted.google.com", event.target_address)
+    self.assertEqual('26', event.circ_id)
+    self.assertEqual('encrypted.google.com:443', event.target)
+    self.assertEqual('encrypted.google.com', event.target_address)
     self.assertEqual(443, event.target_port)
     self.assertEqual(None, event.reason)
     self.assertEqual(None, event.remote_reason)
@@ -1076,12 +1076,12 @@ class TestEvents(unittest.TestCase):
     event = _get_event(STREAM_REMAP)
 
     self.assertTrue(isinstance(event, stem.response.events.StreamEvent))
-    self.assertEqual(STREAM_REMAP.lstrip("650 "), str(event))
-    self.assertEqual("18", event.id)
+    self.assertEqual(STREAM_REMAP.lstrip('650 '), str(event))
+    self.assertEqual('18', event.id)
     self.assertEqual(StreamStatus.REMAP, event.status)
-    self.assertEqual("26", event.circ_id)
-    self.assertEqual("74.125.227.129:443", event.target)
-    self.assertEqual("74.125.227.129", event.target_address)
+    self.assertEqual('26', event.circ_id)
+    self.assertEqual('74.125.227.129:443', event.target)
+    self.assertEqual('74.125.227.129', event.target_address)
     self.assertEqual(443, event.target_port)
     self.assertEqual(None, event.reason)
     self.assertEqual(None, event.remote_reason)
@@ -1094,12 +1094,12 @@ class TestEvents(unittest.TestCase):
     event = _get_event(STREAM_SUCCEEDED)
 
     self.assertTrue(isinstance(event, stem.response.events.StreamEvent))
-    self.assertEqual(STREAM_SUCCEEDED.lstrip("650 "), str(event))
-    self.assertEqual("18", event.id)
+    self.assertEqual(STREAM_SUCCEEDED.lstrip('650 '), str(event))
+    self.assertEqual('18', event.id)
     self.assertEqual(StreamStatus.SUCCEEDED, event.status)
-    self.assertEqual("26", event.circ_id)
-    self.assertEqual("74.125.227.129:443", event.target)
-    self.assertEqual("74.125.227.129", event.target_address)
+    self.assertEqual('26', event.circ_id)
+    self.assertEqual('74.125.227.129:443', event.target)
+    self.assertEqual('74.125.227.129', event.target_address)
     self.assertEqual(443, event.target_port)
     self.assertEqual(None, event.reason)
     self.assertEqual(None, event.remote_reason)
@@ -1112,12 +1112,12 @@ class TestEvents(unittest.TestCase):
     event = _get_event(STREAM_CLOSED_RESET)
 
     self.assertTrue(isinstance(event, stem.response.events.StreamEvent))
-    self.assertEqual(STREAM_CLOSED_RESET.lstrip("650 "), str(event))
-    self.assertEqual("21", event.id)
+    self.assertEqual(STREAM_CLOSED_RESET.lstrip('650 '), str(event))
+    self.assertEqual('21', event.id)
     self.assertEqual(StreamStatus.CLOSED, event.status)
-    self.assertEqual("26", event.circ_id)
-    self.assertEqual("74.125.227.129:443", event.target)
-    self.assertEqual("74.125.227.129", event.target_address)
+    self.assertEqual('26', event.circ_id)
+    self.assertEqual('74.125.227.129:443', event.target)
+    self.assertEqual('74.125.227.129', event.target_address)
     self.assertEqual(443, event.target_port)
     self.assertEqual(StreamClosureReason.CONNRESET, event.reason)
     self.assertEqual(None, event.remote_reason)
@@ -1130,12 +1130,12 @@ class TestEvents(unittest.TestCase):
     event = _get_event(STREAM_CLOSED_DONE)
 
     self.assertTrue(isinstance(event, stem.response.events.StreamEvent))
-    self.assertEqual(STREAM_CLOSED_DONE.lstrip("650 "), str(event))
-    self.assertEqual("25", event.id)
+    self.assertEqual(STREAM_CLOSED_DONE.lstrip('650 '), str(event))
+    self.assertEqual('25', event.id)
     self.assertEqual(StreamStatus.CLOSED, event.status)
-    self.assertEqual("26", event.circ_id)
-    self.assertEqual("199.7.52.72:80", event.target)
-    self.assertEqual("199.7.52.72", event.target_address)
+    self.assertEqual('26', event.circ_id)
+    self.assertEqual('199.7.52.72:80', event.target)
+    self.assertEqual('199.7.52.72', event.target_address)
     self.assertEqual(80, event.target_port)
     self.assertEqual(StreamClosureReason.DONE, event.reason)
     self.assertEqual(None, event.remote_reason)
@@ -1148,36 +1148,36 @@ class TestEvents(unittest.TestCase):
     event = _get_event(STREAM_DIR_FETCH)
 
     self.assertTrue(isinstance(event, stem.response.events.StreamEvent))
-    self.assertEqual(STREAM_DIR_FETCH.lstrip("650 "), str(event))
-    self.assertEqual("14", event.id)
+    self.assertEqual(STREAM_DIR_FETCH.lstrip('650 '), str(event))
+    self.assertEqual('14', event.id)
     self.assertEqual(StreamStatus.NEW, event.status)
     self.assertEqual(None, event.circ_id)
-    self.assertEqual("176.28.51.238.$649F2D0ACF418F7CFC6539AB2257EB2D5297BAFA.exit:443", event.target)
-    self.assertEqual("176.28.51.238.$649F2D0ACF418F7CFC6539AB2257EB2D5297BAFA.exit", event.target_address)
+    self.assertEqual('176.28.51.238.$649F2D0ACF418F7CFC6539AB2257EB2D5297BAFA.exit:443', event.target)
+    self.assertEqual('176.28.51.238.$649F2D0ACF418F7CFC6539AB2257EB2D5297BAFA.exit', event.target_address)
     self.assertEqual(443, event.target_port)
     self.assertEqual(None, event.reason)
     self.assertEqual(None, event.remote_reason)
     self.assertEqual(None, event.source)
-    self.assertEqual("(Tor_internal):0", event.source_addr)
-    self.assertEqual("(Tor_internal)", event.source_address)
+    self.assertEqual('(Tor_internal):0', event.source_addr)
+    self.assertEqual('(Tor_internal)', event.source_address)
     self.assertEqual(0, event.source_port)
     self.assertEqual(StreamPurpose.DIR_FETCH, event.purpose)
 
     event = _get_event(STREAM_DNS_REQUEST)
 
     self.assertTrue(isinstance(event, stem.response.events.StreamEvent))
-    self.assertEqual(STREAM_DNS_REQUEST.lstrip("650 "), str(event))
-    self.assertEqual("1113", event.id)
+    self.assertEqual(STREAM_DNS_REQUEST.lstrip('650 '), str(event))
+    self.assertEqual('1113', event.id)
     self.assertEqual(StreamStatus.NEW, event.status)
     self.assertEqual(None, event.circ_id)
-    self.assertEqual("www.google.com:0", event.target)
-    self.assertEqual("www.google.com", event.target_address)
+    self.assertEqual('www.google.com:0', event.target)
+    self.assertEqual('www.google.com', event.target_address)
     self.assertEqual(0, event.target_port)
     self.assertEqual(None, event.reason)
     self.assertEqual(None, event.remote_reason)
     self.assertEqual(None, event.source)
-    self.assertEqual("127.0.0.1:15297", event.source_addr)
-    self.assertEqual("127.0.0.1", event.source_address)
+    self.assertEqual('127.0.0.1:15297', event.source_addr)
+    self.assertEqual('127.0.0.1', event.source_address)
     self.assertEqual(15297, event.source_port)
     self.assertEqual(StreamPurpose.DNS_REQUEST, event.purpose)
 
@@ -1200,12 +1200,12 @@ class TestEvents(unittest.TestCase):
     event = _get_event(STREAM_NEWRESOLVE_IP6)
 
     self.assertTrue(isinstance(event, stem.response.events.StreamEvent))
-    self.assertEqual(STREAM_NEWRESOLVE_IP6.lstrip("650 "), str(event))
-    self.assertEqual("23", event.id)
+    self.assertEqual(STREAM_NEWRESOLVE_IP6.lstrip('650 '), str(event))
+    self.assertEqual('23', event.id)
     self.assertEqual(StreamStatus.NEWRESOLVE, event.status)
     self.assertEqual(None, event.circ_id)
-    self.assertEqual("2001:db8::1:0", event.target)
-    self.assertEqual("2001:db8::1", event.target_address)
+    self.assertEqual('2001:db8::1:0', event.target)
+    self.assertEqual('2001:db8::1', event.target_address)
     self.assertEqual(0, event.target_port)
     self.assertEqual(None, event.reason)
     self.assertEqual(None, event.remote_reason)
@@ -1216,35 +1216,35 @@ class TestEvents(unittest.TestCase):
     self.assertEqual(StreamPurpose.DNS_REQUEST, event.purpose)
 
   def test_stream_bw_event(self):
-    event = _get_event("650 STREAM_BW 2 15 25")
+    event = _get_event('650 STREAM_BW 2 15 25')
 
     self.assertTrue(isinstance(event, stem.response.events.StreamBwEvent))
-    self.assertEqual("2", event.id)
+    self.assertEqual('2', event.id)
     self.assertEqual(15, event.written)
     self.assertEqual(25, event.read)
 
-    event = _get_event("650 STREAM_BW Stream02 0 0")
-    self.assertEqual("Stream02", event.id)
+    event = _get_event('650 STREAM_BW Stream02 0 0')
+    self.assertEqual('Stream02', event.id)
     self.assertEqual(0, event.written)
     self.assertEqual(0, event.read)
 
-    self.assertRaises(ProtocolError, _get_event, "650 STREAM_BW")
-    self.assertRaises(ProtocolError, _get_event, "650 STREAM_BW 2")
-    self.assertRaises(ProtocolError, _get_event, "650 STREAM_BW 2 15")
-    self.assertRaises(ProtocolError, _get_event, "650 STREAM_BW - 15 25")
-    self.assertRaises(ProtocolError, _get_event, "650 STREAM_BW 12345678901234567 15 25")
-    self.assertRaises(ProtocolError, _get_event, "650 STREAM_BW 2 -15 25")
-    self.assertRaises(ProtocolError, _get_event, "650 STREAM_BW 2 15 -25")
-    self.assertRaises(ProtocolError, _get_event, "650 STREAM_BW 2 x 25")
+    self.assertRaises(ProtocolError, _get_event, '650 STREAM_BW')
+    self.assertRaises(ProtocolError, _get_event, '650 STREAM_BW 2')
+    self.assertRaises(ProtocolError, _get_event, '650 STREAM_BW 2 15')
+    self.assertRaises(ProtocolError, _get_event, '650 STREAM_BW - 15 25')
+    self.assertRaises(ProtocolError, _get_event, '650 STREAM_BW 12345678901234567 15 25')
+    self.assertRaises(ProtocolError, _get_event, '650 STREAM_BW 2 -15 25')
+    self.assertRaises(ProtocolError, _get_event, '650 STREAM_BW 2 15 -25')
+    self.assertRaises(ProtocolError, _get_event, '650 STREAM_BW 2 x 25')
 
   def test_transport_launched_event(self):
     event = _get_event(TRANSPORT_LAUNCHED)
 
     self.assertTrue(isinstance(event, stem.response.events.TransportLaunchedEvent))
-    self.assertEqual(TRANSPORT_LAUNCHED.lstrip("650 "), str(event))
-    self.assertEqual("server", event.type)
-    self.assertEqual("obfs1", event.name)
-    self.assertEqual("127.0.0.1", event.address)
+    self.assertEqual(TRANSPORT_LAUNCHED.lstrip('650 '), str(event))
+    self.assertEqual('server', event.type)
+    self.assertEqual('obfs1', event.name)
+    self.assertEqual('127.0.0.1', event.address)
     self.assertEqual(1111, event.port)
 
     self.assertRaises(ProtocolError, _get_event, TRANSPORT_LAUNCHED_BAD_TYPE)
@@ -1255,8 +1255,8 @@ class TestEvents(unittest.TestCase):
     event = _get_event(CONN_BW)
 
     self.assertTrue(isinstance(event, stem.response.events.ConnectionBandwidthEvent))
-    self.assertEqual(CONN_BW.lstrip("650 "), str(event))
-    self.assertEqual("11", event.id)
+    self.assertEqual(CONN_BW.lstrip('650 '), str(event))
+    self.assertEqual('11', event.id)
     self.assertEqual(stem.ConnectionType.DIR, event.type)
     self.assertEqual(272, event.read)
     self.assertEqual(817, event.written)
@@ -1268,8 +1268,8 @@ class TestEvents(unittest.TestCase):
     event = _get_event(CIRC_BW)
 
     self.assertTrue(isinstance(event, stem.response.events.CircuitBandwidthEvent))
-    self.assertEqual(CIRC_BW.lstrip("650 "), str(event))
-    self.assertEqual("11", event.id)
+    self.assertEqual(CIRC_BW.lstrip('650 '), str(event))
+    self.assertEqual('11', event.id)
     self.assertEqual(272, event.read)
     self.assertEqual(817, event.written)
 
@@ -1280,15 +1280,15 @@ class TestEvents(unittest.TestCase):
     event = _get_event(CELL_STATS_1)
 
     self.assertTrue(isinstance(event, stem.response.events.CellStatsEvent))
-    self.assertEqual(CELL_STATS_1.lstrip("650 "), str(event))
-    self.assertEqual("14", event.id)
+    self.assertEqual(CELL_STATS_1.lstrip('650 '), str(event))
+    self.assertEqual('14', event.id)
     self.assertEqual(None, event.inbound_queue)
     self.assertEqual(None, event.inbound_connection)
     self.assertEqual(None, event.inbound_added)
     self.assertEqual(None, event.inbound_removed)
     self.assertEqual(None, event.inbound_time)
-    self.assertEqual("19403", event.outbound_queue)
-    self.assertEqual("15", event.outbound_connection)
+    self.assertEqual('19403', event.outbound_queue)
+    self.assertEqual('15', event.outbound_connection)
     self.assertEqual({'create_fast': 1, 'relay_early': 2}, event.outbound_added)
     self.assertEqual({'create_fast': 1, 'relay_early': 2}, event.outbound_removed)
     self.assertEqual({'create_fast': 0, 'relay_early': 0}, event.outbound_time)
@@ -1296,15 +1296,15 @@ class TestEvents(unittest.TestCase):
     event = _get_event(CELL_STATS_2)
 
     self.assertTrue(isinstance(event, stem.response.events.CellStatsEvent))
-    self.assertEqual(CELL_STATS_2.lstrip("650 "), str(event))
+    self.assertEqual(CELL_STATS_2.lstrip('650 '), str(event))
     self.assertEqual(None, event.id)
-    self.assertEqual("19403", event.inbound_queue)
-    self.assertEqual("32", event.inbound_connection)
+    self.assertEqual('19403', event.inbound_queue)
+    self.assertEqual('32', event.inbound_connection)
     self.assertEqual({'relay': 1, 'created_fast': 1}, event.inbound_added)
     self.assertEqual({'relay': 1, 'created_fast': 1}, event.inbound_removed)
     self.assertEqual({'relay': 0, 'created_fast': 0}, event.inbound_time)
-    self.assertEqual("6710", event.outbound_queue)
-    self.assertEqual("18", event.outbound_connection)
+    self.assertEqual('6710', event.outbound_queue)
+    self.assertEqual('18', event.outbound_connection)
     self.assertEqual({'create': 1, 'relay_early': 1}, event.outbound_added)
     self.assertEqual({'create': 1, 'relay_early': 1}, event.outbound_removed)
     self.assertEqual({'create': 0, 'relay_early': 0}, event.outbound_time)
@@ -1319,9 +1319,9 @@ class TestEvents(unittest.TestCase):
     event = _get_event(TB_EMPTY_1)
 
     self.assertTrue(isinstance(event, stem.response.events.TokenBucketEmptyEvent))
-    self.assertEqual(TB_EMPTY_1.lstrip("650 "), str(event))
+    self.assertEqual(TB_EMPTY_1.lstrip('650 '), str(event))
     self.assertEqual(stem.TokenBucket.ORCONN, event.bucket)
-    self.assertEqual("16", event.id)
+    self.assertEqual('16', event.id)
     self.assertEqual(0, event.read)
     self.assertEqual(0, event.written)
     self.assertEqual(100, event.last_refill)
@@ -1329,7 +1329,7 @@ class TestEvents(unittest.TestCase):
     event = _get_event(TB_EMPTY_2)
 
     self.assertTrue(isinstance(event, stem.response.events.TokenBucketEmptyEvent))
-    self.assertEqual(TB_EMPTY_2.lstrip("650 "), str(event))
+    self.assertEqual(TB_EMPTY_2.lstrip('650 '), str(event))
     self.assertEqual(stem.TokenBucket.GLOBAL, event.bucket)
     self.assertEqual(None, event.id)
     self.assertEqual(93, event.read)
@@ -1339,7 +1339,7 @@ class TestEvents(unittest.TestCase):
     event = _get_event(TB_EMPTY_3)
 
     self.assertTrue(isinstance(event, stem.response.events.TokenBucketEmptyEvent))
-    self.assertEqual(TB_EMPTY_3.lstrip("650 "), str(event))
+    self.assertEqual(TB_EMPTY_3.lstrip('650 '), str(event))
     self.assertEqual(stem.TokenBucket.RELAY, event.bucket)
     self.assertEqual(None, event.id)
     self.assertEqual(93, event.read)
@@ -1367,10 +1367,10 @@ class TestEvents(unittest.TestCase):
 
     # Parse an invalid runlevel.
 
-    _get_event(STATUS_GENERAL_CONSENSUS_ARRIVED.replace("NOTICE", "OMEGA_CRITICAL!!!"))
+    _get_event(STATUS_GENERAL_CONSENSUS_ARRIVED.replace('NOTICE', 'OMEGA_CRITICAL!!!'))
     logged_events = list(logging_buffer)
 
     self.assertEqual(1, len(logged_events))
-    self.assertTrue("STATUS_GENERAL event had an unrecognized runlevel" in logged_events[0])
+    self.assertTrue('STATUS_GENERAL event had an unrecognized runlevel' in logged_events[0])
 
     stem_logger.removeHandler(logging_buffer)
diff --git a/test/unit/response/getconf.py b/test/unit/response/getconf.py
index de7beb5..07c89fd 100644
--- a/test/unit/response/getconf.py
+++ b/test/unit/response/getconf.py
@@ -10,7 +10,7 @@ import stem.socket
 
 from test import mocking
 
-EMPTY_RESPONSE = "250 OK"
+EMPTY_RESPONSE = '250 OK'
 
 SINGLE_RESPONSE = """\
 250 DataDirectory=/home/neena/.tor"""
@@ -43,7 +43,7 @@ class TestGetConfResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(EMPTY_RESPONSE)
-    stem.response.convert("GETCONF", control_message)
+    stem.response.convert('GETCONF', control_message)
 
     # now this should be a GetConfResponse (ControlMessage subclass)
     self.assertTrue(isinstance(control_message, stem.response.ControlMessage))
@@ -57,8 +57,8 @@ class TestGetConfResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(SINGLE_RESPONSE)
-    stem.response.convert("GETCONF", control_message)
-    self.assertEqual({"DataDirectory": ["/home/neena/.tor"]}, control_message.entries)
+    stem.response.convert('GETCONF', control_message)
+    self.assertEqual({'DataDirectory': ['/home/neena/.tor']}, control_message.entries)
 
   def test_batch_response(self):
     """
@@ -66,13 +66,13 @@ class TestGetConfResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(BATCH_RESPONSE)
-    stem.response.convert("GETCONF", control_message)
+    stem.response.convert('GETCONF', control_message)
 
     expected = {
-      "CookieAuthentication": ["0"],
-      "ControlPort": ["9100"],
-      "DataDirectory": ["/tmp/fake dir"],
-      "DirPort": [],
+      'CookieAuthentication': ['0'],
+      'ControlPort': ['9100'],
+      'DataDirectory': ['/tmp/fake dir'],
+      'DirPort': [],
     }
 
     self.assertEqual(expected, control_message.entries)
@@ -83,11 +83,11 @@ class TestGetConfResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(MULTIVALUE_RESPONSE)
-    stem.response.convert("GETCONF", control_message)
+    stem.response.convert('GETCONF', control_message)
 
     expected = {
-      "ControlPort": ["9100"],
-      "ExitPolicy": ["accept 34.3.4.5", "accept 3.4.53.3", "accept 3.4.53.3", "reject 23.245.54.3"]
+      'ControlPort': ['9100'],
+      'ExitPolicy': ['accept 34.3.4.5', 'accept 3.4.53.3', 'accept 3.4.53.3', 'reject 23.245.54.3']
     }
 
     self.assertEqual(expected, control_message.entries)
@@ -98,12 +98,12 @@ class TestGetConfResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(UNRECOGNIZED_KEY_RESPONSE)
-    self.assertRaises(stem.InvalidArguments, stem.response.convert, "GETCONF", control_message)
+    self.assertRaises(stem.InvalidArguments, stem.response.convert, 'GETCONF', control_message)
 
     try:
-      stem.response.convert("GETCONF", control_message)
+      stem.response.convert('GETCONF', control_message)
     except stem.InvalidArguments as exc:
-      self.assertEqual(exc.arguments, ["brickroad", "submarine"])
+      self.assertEqual(exc.arguments, ['brickroad', 'submarine'])
 
   def test_invalid_content(self):
     """
@@ -113,4 +113,4 @@ class TestGetConfResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(INVALID_RESPONSE)
-    self.assertRaises(stem.ProtocolError, stem.response.convert, "GETCONF", control_message)
+    self.assertRaises(stem.ProtocolError, stem.response.convert, 'GETCONF', control_message)
diff --git a/test/unit/response/getinfo.py b/test/unit/response/getinfo.py
index 082bafc..afd0748 100644
--- a/test/unit/response/getinfo.py
+++ b/test/unit/response/getinfo.py
@@ -11,7 +11,7 @@ import stem.util.str_tools
 
 from test import mocking
 
-EMPTY_RESPONSE = "250 OK"
+EMPTY_RESPONSE = '250 OK'
 
 SINGLE_RESPONSE = """\
 250-version=0.2.3.11-alpha-dev
@@ -58,7 +58,7 @@ class TestGetInfoResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(EMPTY_RESPONSE)
-    stem.response.convert("GETINFO", control_message)
+    stem.response.convert('GETINFO', control_message)
 
     # now this should be a GetInfoResponse (ControlMessage subclass)
     self.assertTrue(isinstance(control_message, stem.response.ControlMessage))
@@ -72,8 +72,8 @@ class TestGetInfoResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(SINGLE_RESPONSE)
-    stem.response.convert("GETINFO", control_message)
-    self.assertEqual({"version": b"0.2.3.11-alpha-dev"}, control_message.entries)
+    stem.response.convert('GETINFO', control_message)
+    self.assertEqual({'version': b'0.2.3.11-alpha-dev'}, control_message.entries)
 
   def test_batch_response(self):
     """
@@ -81,12 +81,12 @@ class TestGetInfoResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(BATCH_RESPONSE)
-    stem.response.convert("GETINFO", control_message)
+    stem.response.convert('GETINFO', control_message)
 
     expected = {
-      "version": b"0.2.3.11-alpha-dev",
-      "address": b"67.137.76.214",
-      "fingerprint": b"5FDE0422045DF0E1879A3738D09099EB4A0C5BA0",
+      'version': b'0.2.3.11-alpha-dev',
+      'address': b'67.137.76.214',
+      'fingerprint': b'5FDE0422045DF0E1879A3738D09099EB4A0C5BA0',
     }
 
     self.assertEqual(expected, control_message.entries)
@@ -98,11 +98,11 @@ class TestGetInfoResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(MULTILINE_RESPONSE)
-    stem.response.convert("GETINFO", control_message)
+    stem.response.convert('GETINFO', control_message)
 
     expected = {
-      "version": b"0.2.3.11-alpha-dev (git-ef0bc7f8f26a917c)",
-      "config-text": b"\n".join(stem.util.str_tools._to_bytes(MULTILINE_RESPONSE).splitlines()[2:8]),
+      'version': b'0.2.3.11-alpha-dev (git-ef0bc7f8f26a917c)',
+      'config-text': b'\n'.join(stem.util.str_tools._to_bytes(MULTILINE_RESPONSE).splitlines()[2:8]),
     }
 
     self.assertEqual(expected, control_message.entries)
@@ -114,7 +114,7 @@ class TestGetInfoResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(NON_KEY_VALUE_ENTRY)
-    self.assertRaises(stem.ProtocolError, stem.response.convert, "GETINFO", control_message)
+    self.assertRaises(stem.ProtocolError, stem.response.convert, 'GETINFO', control_message)
 
   def test_unrecognized_key_response(self):
     """
@@ -122,12 +122,12 @@ class TestGetInfoResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(UNRECOGNIZED_KEY_ENTRY)
-    self.assertRaises(stem.InvalidArguments, stem.response.convert, "GETINFO", control_message)
+    self.assertRaises(stem.InvalidArguments, stem.response.convert, 'GETINFO', control_message)
 
     try:
-      stem.response.convert("GETINFO", control_message)
+      stem.response.convert('GETINFO', control_message)
     except stem.InvalidArguments as exc:
-      self.assertEqual(exc.arguments, ["blackhole"])
+      self.assertEqual(exc.arguments, ['blackhole'])
 
   def test_invalid_multiline_content(self):
     """
@@ -137,4 +137,4 @@ class TestGetInfoResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(MISSING_MULTILINE_NEWLINE)
-    self.assertRaises(stem.ProtocolError, stem.response.convert, "GETINFO", control_message)
+    self.assertRaises(stem.ProtocolError, stem.response.convert, 'GETINFO', control_message)
diff --git a/test/unit/response/mapaddress.py b/test/unit/response/mapaddress.py
index d0ac30e..753f2e6 100644
--- a/test/unit/response/mapaddress.py
+++ b/test/unit/response/mapaddress.py
@@ -18,8 +18,8 @@ BATCH_RESPONSE = """\
 250-gzzz=bzz
 250 120.23.23.2=torproject.org"""
 
-INVALID_EMPTY_RESPONSE = "250 OK"
-INVALID_RESPONSE = "250 foo is bar"
+INVALID_EMPTY_RESPONSE = '250 OK'
+INVALID_RESPONSE = '250 foo is bar'
 
 PARTIAL_FAILURE_RESPONSE = """512-syntax error: mapping '2389' is not of expected form 'foo=bar'
 512-syntax error: mapping '23' is not of expected form 'foo=bar'.
@@ -27,7 +27,7 @@ PARTIAL_FAILURE_RESPONSE = """512-syntax error: mapping '2389' is not of expecte
 
 UNRECOGNIZED_KEYS_RESPONSE = "512 syntax error: mapping '2389' is not of expected form 'foo=bar'"
 
-FAILED_RESPONSE = "451 Resource exhausted"
+FAILED_RESPONSE = '451 Resource exhausted'
 
 
 class TestMapAddressResponse(unittest.TestCase):
@@ -37,8 +37,8 @@ class TestMapAddressResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(SINGLE_RESPONSE)
-    stem.response.convert("MAPADDRESS", control_message)
-    self.assertEqual({"foo": "bar"}, control_message.entries)
+    stem.response.convert('MAPADDRESS', control_message)
+    self.assertEqual({'foo': 'bar'}, control_message.entries)
 
   def test_batch_response(self):
     """
@@ -46,13 +46,13 @@ class TestMapAddressResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(BATCH_RESPONSE)
-    stem.response.convert("MAPADDRESS", control_message)
+    stem.response.convert('MAPADDRESS', control_message)
 
     expected = {
-      "foo": "bar",
-      "baz": "quux",
-      "gzzz": "bzz",
-      "120.23.23.2": "torproject.org"
+      'foo': 'bar',
+      'baz': 'quux',
+      'gzzz': 'bzz',
+      '120.23.23.2': 'torproject.org'
     }
 
     self.assertEqual(expected, control_message.entries)
@@ -63,11 +63,11 @@ class TestMapAddressResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(UNRECOGNIZED_KEYS_RESPONSE)
-    self.assertRaises(stem.InvalidRequest, stem.response.convert, "MAPADDRESS", control_message)
-    expected = {"23": "324"}
+    self.assertRaises(stem.InvalidRequest, stem.response.convert, 'MAPADDRESS', control_message)
+    expected = {'23': '324'}
 
     control_message = mocking.get_message(PARTIAL_FAILURE_RESPONSE)
-    stem.response.convert("MAPADDRESS", control_message)
+    stem.response.convert('MAPADDRESS', control_message)
     self.assertEqual(expected, control_message.entries)
 
   def test_invalid_response(self):
@@ -78,7 +78,7 @@ class TestMapAddressResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(INVALID_EMPTY_RESPONSE)
-    self.assertRaises(stem.ProtocolError, stem.response.convert, "MAPADDRESS", control_message)
+    self.assertRaises(stem.ProtocolError, stem.response.convert, 'MAPADDRESS', control_message)
 
     control_message = mocking.get_message(INVALID_RESPONSE)
-    self.assertRaises(stem.ProtocolError, stem.response.convert, "MAPADDRESS", control_message)
+    self.assertRaises(stem.ProtocolError, stem.response.convert, 'MAPADDRESS', control_message)
diff --git a/test/unit/response/protocolinfo.py b/test/unit/response/protocolinfo.py
index 0eed900..15c7f97 100644
--- a/test/unit/response/protocolinfo.py
+++ b/test/unit/response/protocolinfo.py
@@ -64,23 +64,23 @@ class TestProtocolInfoResponse(unittest.TestCase):
 
     # working case
     control_message = mocking.get_message(NO_AUTH)
-    stem.response.convert("PROTOCOLINFO", control_message)
+    stem.response.convert('PROTOCOLINFO', control_message)
 
     # now this should be a ProtocolInfoResponse (ControlMessage subclass)
     self.assertTrue(isinstance(control_message, stem.response.ControlMessage))
     self.assertTrue(isinstance(control_message, stem.response.protocolinfo.ProtocolInfoResponse))
 
     # exercise some of the ControlMessage functionality
-    raw_content = (NO_AUTH + "\n").replace("\n", "\r\n")
+    raw_content = (NO_AUTH + '\n').replace('\n', '\r\n')
     self.assertEquals(raw_content, control_message.raw_content())
-    self.assertTrue(str(control_message).startswith("PROTOCOLINFO 1"))
+    self.assertTrue(str(control_message).startswith('PROTOCOLINFO 1'))
 
     # attempt to convert the wrong type
-    self.assertRaises(TypeError, stem.response.convert, "PROTOCOLINFO", "hello world")
+    self.assertRaises(TypeError, stem.response.convert, 'PROTOCOLINFO', 'hello world')
 
     # attempt to convert a different message type
-    bw_event_control_message = mocking.get_message("650 BW 32326 2856")
-    self.assertRaises(stem.ProtocolError, stem.response.convert, "PROTOCOLINFO", bw_event_control_message)
+    bw_event_control_message = mocking.get_message('650 BW 32326 2856')
+    self.assertRaises(stem.ProtocolError, stem.response.convert, 'PROTOCOLINFO', bw_event_control_message)
 
   def test_no_auth(self):
     """
@@ -88,10 +88,10 @@ class TestProtocolInfoResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(NO_AUTH)
-    stem.response.convert("PROTOCOLINFO", control_message)
+    stem.response.convert('PROTOCOLINFO', control_message)
 
     self.assertEquals(1, control_message.protocol_version)
-    self.assertEquals(stem.version.Version("0.2.1.30"), control_message.tor_version)
+    self.assertEquals(stem.version.Version('0.2.1.30'), control_message.tor_version)
     self.assertEquals((AuthMethod.NONE, ), control_message.auth_methods)
     self.assertEquals((), control_message.unknown_auth_methods)
     self.assertEquals(None, control_message.cookie_path)
@@ -102,7 +102,7 @@ class TestProtocolInfoResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(PASSWORD_AUTH)
-    stem.response.convert("PROTOCOLINFO", control_message)
+    stem.response.convert('PROTOCOLINFO', control_message)
     self.assertEquals((AuthMethod.PASSWORD, ), control_message.auth_methods)
 
   def test_cookie_auth(self):
@@ -112,9 +112,9 @@ class TestProtocolInfoResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(COOKIE_AUTH)
-    stem.response.convert("PROTOCOLINFO", control_message)
+    stem.response.convert('PROTOCOLINFO', control_message)
     self.assertEquals((AuthMethod.COOKIE, ), control_message.auth_methods)
-    self.assertEquals("/tmp/my data\\\"dir//control_auth_cookie", control_message.cookie_path)
+    self.assertEquals('/tmp/my data\\"dir//control_auth_cookie', control_message.cookie_path)
 
   def test_multiple_auth(self):
     """
@@ -122,9 +122,9 @@ class TestProtocolInfoResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(MULTIPLE_AUTH)
-    stem.response.convert("PROTOCOLINFO", control_message)
+    stem.response.convert('PROTOCOLINFO', control_message)
     self.assertEquals((AuthMethod.COOKIE, AuthMethod.PASSWORD), control_message.auth_methods)
-    self.assertEquals("/home/atagar/.tor/control_auth_cookie", control_message.cookie_path)
+    self.assertEquals('/home/atagar/.tor/control_auth_cookie', control_message.cookie_path)
 
   def test_unknown_auth(self):
     """
@@ -132,9 +132,9 @@ class TestProtocolInfoResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(UNKNOWN_AUTH)
-    stem.response.convert("PROTOCOLINFO", control_message)
+    stem.response.convert('PROTOCOLINFO', control_message)
     self.assertEquals((AuthMethod.UNKNOWN, AuthMethod.PASSWORD), control_message.auth_methods)
-    self.assertEquals(("MAGIC", "PIXIE_DUST"), control_message.unknown_auth_methods)
+    self.assertEquals(('MAGIC', 'PIXIE_DUST'), control_message.unknown_auth_methods)
 
   def test_minimum_response(self):
     """
@@ -143,7 +143,7 @@ class TestProtocolInfoResponse(unittest.TestCase):
     """
 
     control_message = mocking.get_message(MINIMUM_RESPONSE)
-    stem.response.convert("PROTOCOLINFO", control_message)
+    stem.response.convert('PROTOCOLINFO', control_message)
 
     self.assertEquals(5, control_message.protocol_version)
     self.assertEquals(None, control_message.tor_version)
@@ -165,25 +165,25 @@ class TestProtocolInfoResponse(unittest.TestCase):
     # - using that to get tor's cwd
 
     def call_function(command, default):
-      if command == stem.util.system.GET_PID_BY_NAME_PGREP % "tor":
-        return ["10"]
+      if command == stem.util.system.GET_PID_BY_NAME_PGREP % 'tor':
+        return ['10']
       elif command == stem.util.system.GET_CWD_PWDX % 10:
-        return ["10: /tmp/foo"]
+        return ['10: /tmp/foo']
 
     with patch('stem.util.system.call') as call_mock:
       call_mock.side_effect = call_function
 
       control_message = mocking.get_message(RELATIVE_COOKIE_PATH)
-      stem.response.convert("PROTOCOLINFO", control_message)
+      stem.response.convert('PROTOCOLINFO', control_message)
 
-      stem.connection._expand_cookie_path(control_message, stem.util.system.get_pid_by_name, "tor")
+      stem.connection._expand_cookie_path(control_message, stem.util.system.get_pid_by_name, 'tor')
 
-      self.assertEquals(os.path.join("/tmp/foo", "tor-browser_en-US", "Data", "control_auth_cookie"), control_message.cookie_path)
+      self.assertEquals(os.path.join('/tmp/foo', 'tor-browser_en-US', 'Data', 'control_auth_cookie'), control_message.cookie_path)
 
     # exercise cookie expansion where both calls fail (should work, just
     # leaving the path unexpanded)
 
     with patch('stem.util.system.call', Mock(return_value = None)):
       control_message = mocking.get_message(RELATIVE_COOKIE_PATH)
-      stem.response.convert("PROTOCOLINFO", control_message)
-      self.assertEquals("./tor-browser_en-US/Data/control_auth_cookie", control_message.cookie_path)
+      stem.response.convert('PROTOCOLINFO', control_message)
+      self.assertEquals('./tor-browser_en-US/Data/control_auth_cookie', control_message.cookie_path)
diff --git a/test/unit/response/singleline.py b/test/unit/response/singleline.py
index 57dec83..3567d59 100644
--- a/test/unit/response/singleline.py
+++ b/test/unit/response/singleline.py
@@ -15,22 +15,22 @@ MULTILINE_RESPONSE = """250-MULTI
 
 class TestSingleLineResponse(unittest.TestCase):
   def test_single_line_response(self):
-    message = mocking.get_message("552 NOTOK")
-    stem.response.convert("SINGLELINE", message)
+    message = mocking.get_message('552 NOTOK')
+    stem.response.convert('SINGLELINE', message)
     self.assertEqual(False, message.is_ok())
 
-    message = mocking.get_message("250 KK")
-    stem.response.convert("SINGLELINE", message)
+    message = mocking.get_message('250 KK')
+    stem.response.convert('SINGLELINE', message)
     self.assertEqual(True, message.is_ok())
 
-    message = mocking.get_message("250 OK")
-    stem.response.convert("SINGLELINE", message)
+    message = mocking.get_message('250 OK')
+    stem.response.convert('SINGLELINE', message)
     self.assertEqual(True, message.is_ok(True))
 
-    message = mocking.get_message("250 HMM")
-    stem.response.convert("SINGLELINE", message)
+    message = mocking.get_message('250 HMM')
+    stem.response.convert('SINGLELINE', message)
     self.assertEqual(False, message.is_ok(True))
 
   def test_multi_line_response(self):
     message = mocking.get_message(MULTILINE_RESPONSE)
-    self.assertRaises(stem.ProtocolError, stem.response.convert, "SINGLELINE", message)
+    self.assertRaises(stem.ProtocolError, stem.response.convert, 'SINGLELINE', message)
diff --git a/test/unit/tutorial.py b/test/unit/tutorial.py
index 8c76de7..f666d4c 100644
--- a/test/unit/tutorial.py
+++ b/test/unit/tutorial.py
@@ -34,10 +34,10 @@ class TestTutorial(unittest.TestCase):
       with Controller.from_port(control_port = 9051) as controller:
         controller.authenticate()  # provide the password here if you set one
 
-        bytes_read = controller.get_info("traffic/read")
-        bytes_written = controller.get_info("traffic/written")
+        bytes_read = controller.get_info('traffic/read')
+        bytes_written = controller.get_info('traffic/written')
 
-        print "My Tor relay has read %s bytes and written %s." % (bytes_read, bytes_written)
+        print 'My Tor relay has read %s bytes and written %s.' % (bytes_read, bytes_written)
 
     controller = from_port_mock().__enter__()
     controller.get_info.side_effect = lambda arg: {
@@ -46,7 +46,7 @@ class TestTutorial(unittest.TestCase):
     }[arg]
 
     tutorial_example()
-    self.assertEqual("My Tor relay has read 33406 bytes and written 29649.\n", stdout_mock.getvalue())
+    self.assertEqual('My Tor relay has read 33406 bytes and written 29649.\n', stdout_mock.getvalue())
 
   @patch('sys.stdout', new_callable = StringIO.StringIO)
   @patch('stem.descriptor.remote.DescriptorDownloader')
@@ -58,14 +58,14 @@ class TestTutorial(unittest.TestCase):
 
       try:
         for desc in downloader.get_consensus().run():
-          print "found relay %s (%s)" % (desc.nickname, desc.fingerprint)
+          print 'found relay %s (%s)' % (desc.nickname, desc.fingerprint)
       except Exception as exc:
-        print "Unable to retrieve the consensus: %s" % exc
+        print 'Unable to retrieve the consensus: %s' % exc
 
     downloader_mock().get_consensus().run.return_value = [mocking.get_router_status_entry_v2()]
 
     tutorial_example()
-    self.assertEqual("found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n", stdout_mock.getvalue())
+    self.assertEqual('found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
 
   @patch('sys.stdout', new_callable = StringIO.StringIO)
   @patch('stem.control.Controller.from_port', spec = Controller)
@@ -77,13 +77,13 @@ class TestTutorial(unittest.TestCase):
         controller.authenticate()
 
         for desc in controller.get_network_statuses():
-          print "found relay %s (%s)" % (desc.nickname, desc.fingerprint)
+          print 'found relay %s (%s)' % (desc.nickname, desc.fingerprint)
 
     controller = from_port_mock().__enter__()
     controller.get_network_statuses.return_value = [mocking.get_router_status_entry_v2()]
 
     tutorial_example()
-    self.assertEqual("found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n", stdout_mock.getvalue())
+    self.assertEqual('found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
 
   @patch('sys.stdout', new_callable = StringIO.StringIO)
   @patch('%s.open' % __name__, create = True)
@@ -91,19 +91,19 @@ class TestTutorial(unittest.TestCase):
     def tutorial_example():
       from stem.descriptor import parse_file
 
-      for desc in parse_file(open("/home/atagar/.tor/cached-consensus")):
-        print "found relay %s (%s)" % (desc.nickname, desc.fingerprint)
+      for desc in parse_file(open('/home/atagar/.tor/cached-consensus')):
+        print 'found relay %s (%s)' % (desc.nickname, desc.fingerprint)
 
     test_file = io.BytesIO(mocking.get_network_status_document_v3(
       routers = [mocking.get_router_status_entry_v3()],
       content = True,
     ))
 
-    test_file.name = "/home/atagar/.tor/cached-consensus"
+    test_file.name = '/home/atagar/.tor/cached-consensus'
     open_mock.return_value = test_file
 
     tutorial_example()
-    self.assertEqual("found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n", stdout_mock.getvalue())
+    self.assertEqual('found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
 
   @patch('sys.stdout', new_callable = StringIO.StringIO)
   @patch('stem.descriptor.reader.DescriptorReader', spec = DescriptorReader)
@@ -112,15 +112,15 @@ class TestTutorial(unittest.TestCase):
     def tutorial_example():
       from stem.descriptor.reader import DescriptorReader
 
-      with DescriptorReader(["/home/atagar/server-descriptors-2013-03.tar"]) as reader:
+      with DescriptorReader(['/home/atagar/server-descriptors-2013-03.tar']) as reader:
         for desc in reader:
-          print "found relay %s (%s)" % (desc.nickname, desc.fingerprint)
+          print 'found relay %s (%s)' % (desc.nickname, desc.fingerprint)
 
     reader = reader_mock().__enter__()
     reader.__iter__.return_value = iter([mocking.get_relay_server_descriptor()])
 
     tutorial_example()
-    self.assertEqual("found relay caerSidi (None)\n", stdout_mock.getvalue())
+    self.assertEqual('found relay caerSidi (None)\n', stdout_mock.getvalue())
 
   @patch('sys.stdout', new_callable = StringIO.StringIO)
   @patch('stem.descriptor.remote.DescriptorDownloader')
@@ -141,7 +141,7 @@ class TestTutorial(unittest.TestCase):
             if desc.exit_policy.is_exiting_allowed():
               bw_to_relay.setdefault(desc.observed_bandwidth, []).append(desc.nickname)
         except Exception as exc:
-          print "Unable to retrieve the server descriptors: %s" % exc
+          print 'Unable to retrieve the server descriptors: %s' % exc
 
         return bw_to_relay
 
@@ -152,7 +152,7 @@ class TestTutorial(unittest.TestCase):
 
       for bw_value in sorted(bw_to_relay.keys(), reverse = True):
         for nickname in bw_to_relay[bw_value]:
-          print "%i. %s (%s/s)" % (count, nickname, str_tools.get_size_label(bw_value, 2))
+          print '%i. %s (%s/s)' % (count, nickname, str_tools.get_size_label(bw_value, 2))
           count += 1
 
           if count > 15:
diff --git a/test/unit/util/__init__.py b/test/unit/util/__init__.py
index a5faacf..04ab051 100644
--- a/test/unit/util/__init__.py
+++ b/test/unit/util/__init__.py
@@ -3,11 +3,11 @@ Unit tests for stem.util.* contents.
 """
 
 __all__ = [
-  "conf",
-  "connection",
-  "enum",
-  "proc",
-  "str_tools",
-  "system",
-  "tor_tools",
+  'conf',
+  'connection',
+  'enum',
+  'proc',
+  'str_tools',
+  'system',
+  'tor_tools',
 ]
diff --git a/test/unit/util/conf.py b/test/unit/util/conf.py
index e0e92a5..9519c8d 100644
--- a/test/unit/util/conf.py
+++ b/test/unit/util/conf.py
@@ -13,7 +13,7 @@ from stem.util.conf import parse_enum, parse_enum_csv
 class TestConf(unittest.TestCase):
   def tearDown(self):
     # clears the config contents
-    test_config = stem.util.conf.get_config("unit_testing")
+    test_config = stem.util.conf.get_config('unit_testing')
     test_config.clear()
     test_config.clear_listeners()
 
@@ -23,112 +23,112 @@ class TestConf(unittest.TestCase):
     """
 
     my_config = {
-      "bool_value": False,
-      "int_value": 5,
-      "str_value": "hello",
-      "list_value": [],
+      'bool_value': False,
+      'int_value': 5,
+      'str_value': 'hello',
+      'list_value': [],
     }
 
-    test_config = stem.util.conf.get_config("unit_testing")
+    test_config = stem.util.conf.get_config('unit_testing')
 
     # checks that sync causes existing contents to be applied
-    test_config.set("bool_value", "true")
-    my_config = stem.util.conf.config_dict("unit_testing", my_config)
-    self.assertEquals(True, my_config["bool_value"])
+    test_config.set('bool_value', 'true')
+    my_config = stem.util.conf.config_dict('unit_testing', my_config)
+    self.assertEquals(True, my_config['bool_value'])
 
     # check a basic synchronize
-    test_config.set("str_value", "me")
-    self.assertEquals("me", my_config["str_value"])
+    test_config.set('str_value', 'me')
+    self.assertEquals('me', my_config['str_value'])
 
     # synchronize with a type mismatch, should keep the old value
-    test_config.set("int_value", "7a")
-    self.assertEquals(5, my_config["int_value"])
+    test_config.set('int_value', '7a')
+    self.assertEquals(5, my_config['int_value'])
 
     # changes for a collection
-    test_config.set("list_value", "a", False)
-    self.assertEquals(["a"], my_config["list_value"])
+    test_config.set('list_value', 'a', False)
+    self.assertEquals(['a'], my_config['list_value'])
 
-    test_config.set("list_value", "b", False)
-    self.assertEquals(["a", "b"], my_config["list_value"])
+    test_config.set('list_value', 'b', False)
+    self.assertEquals(['a', 'b'], my_config['list_value'])
 
-    test_config.set("list_value", "c", False)
-    self.assertEquals(["a", "b", "c"], my_config["list_value"])
+    test_config.set('list_value', 'c', False)
+    self.assertEquals(['a', 'b', 'c'], my_config['list_value'])
 
   def test_parse_enum(self):
     """
     Tests the parse_enum function.
     """
 
-    Insects = stem.util.enum.Enum("BUTTERFLY", "LADYBUG", "CRICKET")
-    self.assertEqual(Insects.LADYBUG, parse_enum("my_option", "ladybug", Insects))
-    self.assertRaises(ValueError, parse_enum, "my_option", "ugabuga", Insects)
-    self.assertRaises(ValueError, parse_enum, "my_option", "ladybug, cricket", Insects)
+    Insects = stem.util.enum.Enum('BUTTERFLY', 'LADYBUG', 'CRICKET')
+    self.assertEqual(Insects.LADYBUG, parse_enum('my_option', 'ladybug', Insects))
+    self.assertRaises(ValueError, parse_enum, 'my_option', 'ugabuga', Insects)
+    self.assertRaises(ValueError, parse_enum, 'my_option', 'ladybug, cricket', Insects)
 
   def test_parse_enum_csv(self):
     """
     Tests the parse_enum_csv function.
     """
 
-    Insects = stem.util.enum.Enum("BUTTERFLY", "LADYBUG", "CRICKET")
+    Insects = stem.util.enum.Enum('BUTTERFLY', 'LADYBUG', 'CRICKET')
 
     # check the case insensitivity
 
-    self.assertEqual([Insects.LADYBUG], parse_enum_csv("my_option", "ladybug", Insects))
-    self.assertEqual([Insects.LADYBUG], parse_enum_csv("my_option", "Ladybug", Insects))
-    self.assertEqual([Insects.LADYBUG], parse_enum_csv("my_option", "LaDyBuG", Insects))
-    self.assertEqual([Insects.LADYBUG], parse_enum_csv("my_option", "LADYBUG", Insects))
+    self.assertEqual([Insects.LADYBUG], parse_enum_csv('my_option', 'ladybug', Insects))
+    self.assertEqual([Insects.LADYBUG], parse_enum_csv('my_option', 'Ladybug', Insects))
+    self.assertEqual([Insects.LADYBUG], parse_enum_csv('my_option', 'LaDyBuG', Insects))
+    self.assertEqual([Insects.LADYBUG], parse_enum_csv('my_option', 'LADYBUG', Insects))
 
     # various number of values
 
-    self.assertEqual([], parse_enum_csv("my_option", "", Insects))
-    self.assertEqual([Insects.LADYBUG], parse_enum_csv("my_option", "ladybug", Insects))
+    self.assertEqual([], parse_enum_csv('my_option', '', Insects))
+    self.assertEqual([Insects.LADYBUG], parse_enum_csv('my_option', 'ladybug', Insects))
 
     self.assertEqual(
       [Insects.LADYBUG, Insects.BUTTERFLY],
-      parse_enum_csv("my_option", "ladybug, butterfly", Insects)
+      parse_enum_csv('my_option', 'ladybug, butterfly', Insects)
     )
 
     self.assertEqual(
       [Insects.LADYBUG, Insects.BUTTERFLY, Insects.CRICKET],
-      parse_enum_csv("my_option", "ladybug, butterfly, cricket", Insects)
+      parse_enum_csv('my_option', 'ladybug, butterfly, cricket', Insects)
     )
 
     # edge cases for count argument where things are ok
 
     self.assertEqual(
       [Insects.LADYBUG, Insects.BUTTERFLY],
-      parse_enum_csv("my_option", "ladybug, butterfly", Insects, 2)
+      parse_enum_csv('my_option', 'ladybug, butterfly', Insects, 2)
     )
 
     self.assertEqual(
       [Insects.LADYBUG, Insects.BUTTERFLY],
-      parse_enum_csv("my_option", "ladybug, butterfly", Insects, (1, 2))
+      parse_enum_csv('my_option', 'ladybug, butterfly', Insects, (1, 2))
     )
 
     self.assertEqual(
       [Insects.LADYBUG, Insects.BUTTERFLY],
-      parse_enum_csv("my_option", "ladybug, butterfly", Insects, (2, 3))
+      parse_enum_csv('my_option', 'ladybug, butterfly', Insects, (2, 3))
     )
 
     self.assertEqual(
       [Insects.LADYBUG, Insects.BUTTERFLY],
-      parse_enum_csv("my_option", "ladybug, butterfly", Insects, (2, 2))
+      parse_enum_csv('my_option', 'ladybug, butterfly', Insects, (2, 2))
     )
 
     # failure cases
 
-    self.assertRaises(ValueError, parse_enum_csv, "my_option", "ugabuga", Insects)
-    self.assertRaises(ValueError, parse_enum_csv, "my_option", "ladybug, ugabuga", Insects)
-    self.assertRaises(ValueError, parse_enum_csv, "my_option", "ladybug butterfly", Insects)  # no comma
-    self.assertRaises(ValueError, parse_enum_csv, "my_option", "ladybug", Insects, 2)
-    self.assertRaises(ValueError, parse_enum_csv, "my_option", "ladybug", Insects, (2, 3))
+    self.assertRaises(ValueError, parse_enum_csv, 'my_option', 'ugabuga', Insects)
+    self.assertRaises(ValueError, parse_enum_csv, 'my_option', 'ladybug, ugabuga', Insects)
+    self.assertRaises(ValueError, parse_enum_csv, 'my_option', 'ladybug butterfly', Insects)  # no comma
+    self.assertRaises(ValueError, parse_enum_csv, 'my_option', 'ladybug', Insects, 2)
+    self.assertRaises(ValueError, parse_enum_csv, 'my_option', 'ladybug', Insects, (2, 3))
 
   def test_clear(self):
     """
     Tests the clear method.
     """
 
-    test_config = stem.util.conf.get_config("unit_testing")
+    test_config = stem.util.conf.get_config('unit_testing')
     self.assertEquals([], test_config.keys())
 
     # tests clearing when we're already empty
@@ -136,8 +136,8 @@ class TestConf(unittest.TestCase):
     self.assertEquals([], test_config.keys())
 
     # tests clearing when we have contents
-    test_config.set("hello", "world")
-    self.assertEquals(["hello"], test_config.keys())
+    test_config.set('hello', 'world')
+    self.assertEquals(['hello'], test_config.keys())
 
     test_config.clear()
     self.assertEquals([], test_config.keys())
@@ -150,37 +150,37 @@ class TestConf(unittest.TestCase):
     listener_received_keys = []
 
     def test_listener(config, key):
-      self.assertEquals(config, stem.util.conf.get_config("unit_testing"))
+      self.assertEquals(config, stem.util.conf.get_config('unit_testing'))
       listener_received_keys.append(key)
 
-    test_config = stem.util.conf.get_config("unit_testing")
+    test_config = stem.util.conf.get_config('unit_testing')
     test_config.add_listener(test_listener)
 
     self.assertEquals([], listener_received_keys)
-    test_config.set("hello", "world")
-    self.assertEquals(["hello"], listener_received_keys)
+    test_config.set('hello', 'world')
+    self.assertEquals(['hello'], listener_received_keys)
 
     test_config.clear_listeners()
 
-    test_config.set("foo", "bar")
-    self.assertEquals(["hello"], listener_received_keys)
+    test_config.set('foo', 'bar')
+    self.assertEquals(['hello'], listener_received_keys)
 
   def test_unused_keys(self):
     """
     Tests the unused_keys method.
     """
 
-    test_config = stem.util.conf.get_config("unit_testing")
-    test_config.set("hello", "world")
-    test_config.set("foo", "bar")
-    test_config.set("pw", "12345")
+    test_config = stem.util.conf.get_config('unit_testing')
+    test_config.set('hello', 'world')
+    test_config.set('foo', 'bar')
+    test_config.set('pw', '12345')
 
-    test_config.get("hello")
-    test_config.get_value("foo")
+    test_config.get('hello')
+    test_config.get_value('foo')
 
-    self.assertEquals(set(["pw"]), test_config.unused_keys())
+    self.assertEquals(set(['pw']), test_config.unused_keys())
 
-    test_config.get("pw")
+    test_config.get('pw')
     self.assertEquals(set(), test_config.unused_keys())
 
   def test_get(self):
@@ -188,39 +188,39 @@ class TestConf(unittest.TestCase):
     Tests the get and get_value methods.
     """
 
-    test_config = stem.util.conf.get_config("unit_testing")
-    test_config.set("bool_value", "true")
-    test_config.set("int_value", "11")
-    test_config.set("float_value", "11.1")
-    test_config.set("str_value", "world")
-    test_config.set("list_value", "a", False)
-    test_config.set("list_value", "b", False)
-    test_config.set("list_value", "c", False)
-    test_config.set("map_value", "foo => bar")
+    test_config = stem.util.conf.get_config('unit_testing')
+    test_config.set('bool_value', 'true')
+    test_config.set('int_value', '11')
+    test_config.set('float_value', '11.1')
+    test_config.set('str_value', 'world')
+    test_config.set('list_value', 'a', False)
+    test_config.set('list_value', 'b', False)
+    test_config.set('list_value', 'c', False)
+    test_config.set('map_value', 'foo => bar')
 
     # check that we get the default for type mismatch or missing values
 
-    self.assertEquals(5, test_config.get("foo", 5))
-    self.assertEquals(5, test_config.get("bool_value", 5))
+    self.assertEquals(5, test_config.get('foo', 5))
+    self.assertEquals(5, test_config.get('bool_value', 5))
 
     # checks that we get a string when no default is supplied
 
-    self.assertEquals("11", test_config.get("int_value"))
+    self.assertEquals('11', test_config.get('int_value'))
 
     # exercise type casting for each of the supported types
 
-    self.assertEquals(True, test_config.get("bool_value", False))
-    self.assertEquals(11, test_config.get("int_value", 0))
-    self.assertEquals(11.1, test_config.get("float_value", 0.0))
-    self.assertEquals("world", test_config.get("str_value", ""))
-    self.assertEquals(["a", "b", "c"], test_config.get("list_value", []))
-    self.assertEquals(("a", "b", "c"), test_config.get("list_value", ()))
-    self.assertEquals({"foo": "bar"}, test_config.get("map_value", {}))
+    self.assertEquals(True, test_config.get('bool_value', False))
+    self.assertEquals(11, test_config.get('int_value', 0))
+    self.assertEquals(11.1, test_config.get('float_value', 0.0))
+    self.assertEquals('world', test_config.get('str_value', ''))
+    self.assertEquals(['a', 'b', 'c'], test_config.get('list_value', []))
+    self.assertEquals(('a', 'b', 'c'), test_config.get('list_value', ()))
+    self.assertEquals({'foo': 'bar'}, test_config.get('map_value', {}))
 
     # the get_value is similar, though only provides back a string or list
 
-    self.assertEquals("c", test_config.get_value("list_value"))
-    self.assertEquals(["a", "b", "c"], test_config.get_value("list_value", multiple = True))
+    self.assertEquals('c', test_config.get_value('list_value'))
+    self.assertEquals(['a', 'b', 'c'], test_config.get_value('list_value', multiple = True))
 
-    self.assertEquals(None, test_config.get_value("foo"))
-    self.assertEquals("hello", test_config.get_value("foo", "hello"))
+    self.assertEquals(None, test_config.get_value('foo'))
+    self.assertEquals('hello', test_config.get_value('foo', 'hello'))
diff --git a/test/unit/util/connection.py b/test/unit/util/connection.py
index e42a41a..dc1a9eb 100644
--- a/test/unit/util/connection.py
+++ b/test/unit/util/connection.py
@@ -306,19 +306,19 @@ class TestConnection(unittest.TestCase):
     """
 
     valid_addresses = (
-      "0.0.0.0",
-      "1.2.3.4",
-      "192.168.0.1",
-      "255.255.255.255",
+      '0.0.0.0',
+      '1.2.3.4',
+      '192.168.0.1',
+      '255.255.255.255',
     )
 
     invalid_addresses = (
-      "0.0.00.0",
-      "0.0.0",
-      "1.2.3.256",
-      "1.2.3.-1",
-      "0.0.0.a",
-      "a.b.c.d",
+      '0.0.00.0',
+      '0.0.0',
+      '1.2.3.256',
+      '1.2.3.-1',
+      '0.0.0.a',
+      'a.b.c.d',
     )
 
     for address in valid_addresses:
@@ -333,19 +333,19 @@ class TestConnection(unittest.TestCase):
     """
 
     valid_addresses = (
-      "fe80:0000:0000:0000:0202:b3ff:fe1e:8329",
-      "fe80:0:0:0:202:b3ff:fe1e:8329",
-      "fe80::202:b3ff:fe1e:8329",
-      "::",
+      'fe80:0000:0000:0000:0202:b3ff:fe1e:8329',
+      'fe80:0:0:0:202:b3ff:fe1e:8329',
+      'fe80::202:b3ff:fe1e:8329',
+      '::',
     )
 
     invalid_addresses = (
-      "fe80:0000:0000:0000:0202:b3ff:fe1e:829g",
-      "fe80:0000:0000:0000:0202:b3ff:fe1e: 8329",
-      "2001:db8::aaaa::1",
-      ":::",
-      ":",
-      "",
+      'fe80:0000:0000:0000:0202:b3ff:fe1e:829g',
+      'fe80:0000:0000:0000:0202:b3ff:fe1e: 8329',
+      '2001:db8::aaaa::1',
+      ':::',
+      ':',
+      '',
     )
 
     for address in valid_addresses:
@@ -359,8 +359,8 @@ class TestConnection(unittest.TestCase):
     Checks the is_valid_port function.
     """
 
-    valid_ports = (1, "1", 1234, "1234", 65535, "65535")
-    invalid_ports = (0, "0", 65536, "65536", "abc", "*", " 15", "01")
+    valid_ports = (1, '1', 1234, '1234', 65535, '65535')
+    invalid_ports = (0, '0', 65536, '65536', 'abc', '*', ' 15', '01')
 
     for port in valid_ports:
       self.assertTrue(stem.util.connection.is_valid_port(port))
@@ -369,7 +369,7 @@ class TestConnection(unittest.TestCase):
       self.assertFalse(stem.util.connection.is_valid_port(port))
 
     self.assertTrue(stem.util.connection.is_valid_port(0, allow_zero = True))
-    self.assertTrue(stem.util.connection.is_valid_port("0", allow_zero = True))
+    self.assertTrue(stem.util.connection.is_valid_port('0', allow_zero = True))
 
   def test_is_private_address(self):
     """
@@ -397,26 +397,26 @@ class TestConnection(unittest.TestCase):
     """
 
     test_values = {
-      "2001:db8::ff00:42:8329": "2001:0db8:0000:0000:0000:ff00:0042:8329",
-      "::": "0000:0000:0000:0000:0000:0000:0000:0000",
-      "::1": "0000:0000:0000:0000:0000:0000:0000:0001",
-      "1::1": "0001:0000:0000:0000:0000:0000:0000:0001",
+      '2001:db8::ff00:42:8329': '2001:0db8:0000:0000:0000:ff00:0042:8329',
+      '::': '0000:0000:0000:0000:0000:0000:0000:0000',
+      '::1': '0000:0000:0000:0000:0000:0000:0000:0001',
+      '1::1': '0001:0000:0000:0000:0000:0000:0000:0001',
     }
 
     for test_arg, expected in test_values.items():
       self.assertEquals(expected, stem.util.connection.expand_ipv6_address(test_arg))
 
-    self.assertRaises(ValueError, stem.util.connection.expand_ipv6_address, "127.0.0.1")
+    self.assertRaises(ValueError, stem.util.connection.expand_ipv6_address, '127.0.0.1')
 
   def test_get_mask_ipv4(self):
     """
     Checks the get_mask_ipv4 function.
     """
 
-    self.assertEquals("255.255.255.255", stem.util.connection.get_mask_ipv4(32))
-    self.assertEquals("255.255.255.248", stem.util.connection.get_mask_ipv4(29))
-    self.assertEquals("255.255.254.0", stem.util.connection.get_mask_ipv4(23))
-    self.assertEquals("0.0.0.0", stem.util.connection.get_mask_ipv4(0))
+    self.assertEquals('255.255.255.255', stem.util.connection.get_mask_ipv4(32))
+    self.assertEquals('255.255.255.248', stem.util.connection.get_mask_ipv4(29))
+    self.assertEquals('255.255.254.0', stem.util.connection.get_mask_ipv4(23))
+    self.assertEquals('0.0.0.0', stem.util.connection.get_mask_ipv4(0))
 
     self.assertRaises(ValueError, stem.util.connection.get_mask_ipv4, -1)
     self.assertRaises(ValueError, stem.util.connection.get_mask_ipv4, 33)
@@ -426,9 +426,9 @@ class TestConnection(unittest.TestCase):
     Checks the get_mask_ipv6 function.
     """
 
-    self.assertEquals("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", stem.util.connection.get_mask_ipv6(128))
-    self.assertEquals("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFE:0000", stem.util.connection.get_mask_ipv6(111))
-    self.assertEquals("0000:0000:0000:0000:0000:0000:0000:0000", stem.util.connection.get_mask_ipv6(0))
+    self.assertEquals('FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF', stem.util.connection.get_mask_ipv6(128))
+    self.assertEquals('FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFE:0000', stem.util.connection.get_mask_ipv6(111))
+    self.assertEquals('0000:0000:0000:0000:0000:0000:0000:0000', stem.util.connection.get_mask_ipv6(0))
 
     self.assertRaises(ValueError, stem.util.connection.get_mask_ipv6, -1)
     self.assertRaises(ValueError, stem.util.connection.get_mask_ipv6, 129)
@@ -438,13 +438,13 @@ class TestConnection(unittest.TestCase):
     Checks the _get_masked_bits function.
     """
 
-    self.assertEquals(32, stem.util.connection._get_masked_bits("255.255.255.255"))
-    self.assertEquals(29, stem.util.connection._get_masked_bits("255.255.255.248"))
-    self.assertEquals(23, stem.util.connection._get_masked_bits("255.255.254.0"))
-    self.assertEquals(0, stem.util.connection._get_masked_bits("0.0.0.0"))
+    self.assertEquals(32, stem.util.connection._get_masked_bits('255.255.255.255'))
+    self.assertEquals(29, stem.util.connection._get_masked_bits('255.255.255.248'))
+    self.assertEquals(23, stem.util.connection._get_masked_bits('255.255.254.0'))
+    self.assertEquals(0, stem.util.connection._get_masked_bits('0.0.0.0'))
 
-    self.assertRaises(ValueError, stem.util.connection._get_masked_bits, "blarg")
-    self.assertRaises(ValueError, stem.util.connection._get_masked_bits, "255.255.0.255")
+    self.assertRaises(ValueError, stem.util.connection._get_masked_bits, 'blarg')
+    self.assertRaises(ValueError, stem.util.connection._get_masked_bits, '255.255.0.255')
 
   def test_get_address_binary(self):
     """
@@ -452,18 +452,18 @@ class TestConnection(unittest.TestCase):
     """
 
     test_values = {
-      "0.0.0.0": "00000000000000000000000000000000",
-      "1.2.3.4": "00000001000000100000001100000100",
-      "127.0.0.1": "01111111000000000000000000000001",
-      "255.255.255.255": "11111111111111111111111111111111",
-      "::": "0" * 128,
-      "::1": ("0" * 127) + "1",
-      "1::1": "0000000000000001" + ("0" * 111) + "1",
-      "2001:db8::ff00:42:8329": "00100000000000010000110110111000000000000000000000000000000000000000000000000000111111110000000000000000010000101000001100101001",
+      '0.0.0.0': '00000000000000000000000000000000',
+      '1.2.3.4': '00000001000000100000001100000100',
+      '127.0.0.1': '01111111000000000000000000000001',
+      '255.255.255.255': '11111111111111111111111111111111',
+      '::': '0' * 128,
+      '::1': ('0' * 127) + '1',
+      '1::1': '0000000000000001' + ('0' * 111) + '1',
+      '2001:db8::ff00:42:8329': '00100000000000010000110110111000000000000000000000000000000000000000000000000000111111110000000000000000010000101000001100101001',
     }
 
     for test_arg, expected in test_values.items():
       self.assertEquals(expected, stem.util.connection._get_address_binary(test_arg))
 
-    self.assertRaises(ValueError, stem.util.connection._get_address_binary, "")
-    self.assertRaises(ValueError, stem.util.connection._get_address_binary, "blarg")
+    self.assertRaises(ValueError, stem.util.connection._get_address_binary, '')
+    self.assertRaises(ValueError, stem.util.connection._get_address_binary, 'blarg')
diff --git a/test/unit/util/enum.py b/test/unit/util/enum.py
index 0e562b3..23f5b97 100644
--- a/test/unit/util/enum.py
+++ b/test/unit/util/enum.py
@@ -13,13 +13,13 @@ class TestEnum(unittest.TestCase):
     Checks that the pydoc examples are accurate.
     """
 
-    insects = stem.util.enum.Enum("ANT", "WASP", "LADYBUG", "FIREFLY")
-    self.assertEquals("Ant", insects.ANT)
-    self.assertEquals(("Ant", "Wasp", "Ladybug", "Firefly"), tuple(insects))
+    insects = stem.util.enum.Enum('ANT', 'WASP', 'LADYBUG', 'FIREFLY')
+    self.assertEquals('Ant', insects.ANT)
+    self.assertEquals(('Ant', 'Wasp', 'Ladybug', 'Firefly'), tuple(insects))
 
-    pets = stem.util.enum.Enum(("DOG", "Skippy"), "CAT", ("FISH", "Nemo"))
-    self.assertEquals("Skippy", pets.DOG)
-    self.assertEquals("Cat", pets.CAT)
+    pets = stem.util.enum.Enum(('DOG', 'Skippy'), 'CAT', ('FISH', 'Nemo'))
+    self.assertEquals('Skippy', pets.DOG)
+    self.assertEquals('Cat', pets.CAT)
 
   def test_uppercase_enum_example(self):
     """
@@ -27,15 +27,15 @@ class TestEnum(unittest.TestCase):
     accurate.
     """
 
-    runlevels = stem.util.enum.UppercaseEnum("DEBUG", "INFO", "NOTICE", "WARN", "ERROR")
-    self.assertEquals("DEBUG", runlevels.DEBUG)
+    runlevels = stem.util.enum.UppercaseEnum('DEBUG', 'INFO', 'NOTICE', 'WARN', 'ERROR')
+    self.assertEquals('DEBUG', runlevels.DEBUG)
 
   def test_enum_methods(self):
     """
     Exercises enumeration methods.
     """
 
-    insects = stem.util.enum.Enum("ANT", "WASP", "LADYBUG", "FIREFLY")
+    insects = stem.util.enum.Enum('ANT', 'WASP', 'LADYBUG', 'FIREFLY')
 
     # next method
     self.assertEquals(insects.WASP, insects.next(insects.ANT))
@@ -46,4 +46,4 @@ class TestEnum(unittest.TestCase):
     self.assertEquals(insects.LADYBUG, insects.previous(insects.FIREFLY))
 
     # keys method
-    self.assertEquals(["ANT", "WASP", "LADYBUG", "FIREFLY"], insects.keys())
+    self.assertEquals(['ANT', 'WASP', 'LADYBUG', 'FIREFLY'], insects.keys())
diff --git a/test/unit/util/proc.py b/test/unit/util/proc.py
index 55ed9e7..c682853 100644
--- a/test/unit/util/proc.py
+++ b/test/unit/util/proc.py
@@ -62,7 +62,7 @@ class TestProc(unittest.TestCase):
       pid, uid = test_value
 
       get_line_mock.side_effect = lambda *params: {
-        ("/proc/%s/status" % pid, 'Uid:', 'uid'): 'Uid: %s' % uid,
+        ('/proc/%s/status' % pid, 'Uid:', 'uid'): 'Uid: %s' % uid,
       }[params]
 
       self.assertEquals(uid, proc.get_uid(pid))
@@ -96,7 +96,7 @@ class TestProc(unittest.TestCase):
       ('start time', '10.21'),
     ])
 
-    stat_path = "/proc/24062/stat"
+    stat_path = '/proc/24062/stat'
     stat = '1 (test_program) 2 3 4 5 6 7 8 9 10 11 12 13.0 14.0 15 16 17 18 19 20 21.0 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43'
 
     # tests the case where no stat_types are specified
diff --git a/test/unit/util/str_tools.py b/test/unit/util/str_tools.py
index 550edeb..82d5a97 100644
--- a/test/unit/util/str_tools.py
+++ b/test/unit/util/str_tools.py
@@ -15,15 +15,15 @@ class TestStrTools(unittest.TestCase):
     """
 
     # test the pydoc example
-    self.assertEquals("I Like Pepperjack!", str_tools._to_camel_case("I_LIKE_PEPPERJACK!"))
+    self.assertEquals('I Like Pepperjack!', str_tools._to_camel_case('I_LIKE_PEPPERJACK!'))
 
     # check a few edge cases
-    self.assertEquals("", str_tools._to_camel_case(""))
-    self.assertEquals("Hello", str_tools._to_camel_case("hello"))
-    self.assertEquals("Hello", str_tools._to_camel_case("HELLO"))
-    self.assertEquals("Hello  World", str_tools._to_camel_case("hello__world"))
-    self.assertEquals("Hello\tworld", str_tools._to_camel_case("hello\tWORLD"))
-    self.assertEquals("Hello\t\tWorld", str_tools._to_camel_case("hello__world", "_", "\t"))
+    self.assertEquals('', str_tools._to_camel_case(''))
+    self.assertEquals('Hello', str_tools._to_camel_case('hello'))
+    self.assertEquals('Hello', str_tools._to_camel_case('HELLO'))
+    self.assertEquals('Hello  World', str_tools._to_camel_case('hello__world'))
+    self.assertEquals('Hello\tworld', str_tools._to_camel_case('hello\tWORLD'))
+    self.assertEquals('Hello\t\tWorld', str_tools._to_camel_case('hello__world', '_', '\t'))
 
   def test_get_size_label(self):
     """
diff --git a/test/unit/util/system.py b/test/unit/util/system.py
index d36546d..7324c2b 100644
--- a/test/unit/util/system.py
+++ b/test/unit/util/system.py
@@ -22,50 +22,50 @@ except ImportError:
 # 'multiple_results' entries are filled in by tests.
 
 GET_PID_BY_NAME_BASE_RESULTS = {
-  "success": [],
-  "multiple_results": [],
-  "malformed_data": ["bad data"],
-  "no_results": [],
-  "command_fails": None,
+  'success': [],
+  'multiple_results': [],
+  'malformed_data': ['bad data'],
+  'no_results': [],
+  'command_fails': None,
 }
 
 # testing output for system calls
 
 GET_PID_BY_NAME_PS_BSD = [
-  "  PID   TT  STAT      TIME COMMAND",
-  "    1   ??  Ss     9:00.22 launchd",
-  "   10   ??  Ss     0:09.97 kextd",
-  "   11   ??  Ss     5:47.36 DirectoryService",
-  "   12   ??  Ss     3:01.44 notifyd"]
+  '  PID   TT  STAT      TIME COMMAND',
+  '    1   ??  Ss     9:00.22 launchd',
+  '   10   ??  Ss     0:09.97 kextd',
+  '   11   ??  Ss     5:47.36 DirectoryService',
+  '   12   ??  Ss     3:01.44 notifyd']
 
 GET_PID_BY_NAME_PS_BSD_MULTIPLE = [
-  "  PID   TT  STAT      TIME COMMAND",
-  "    1   ??  Ss     9:00.22 launchd",
-  "   10   ??  Ss     0:09.97 kextd",
-  "   41   ??  Ss     9:00.22 launchd"]
+  '  PID   TT  STAT      TIME COMMAND',
+  '    1   ??  Ss     9:00.22 launchd',
+  '   10   ??  Ss     0:09.97 kextd',
+  '   41   ??  Ss     9:00.22 launchd']
 
 GET_PID_BY_PORT_NETSTAT_RESULTS = [
-  "Active Internet connections (only servers)",
-  "Proto Recv-Q Send-Q Local Address           Foreign Address   State    PID/Program name",
-  "tcp        0      0 127.0.0.1:631           0.0.0.0:*         LISTEN   -     ",
-  "tcp        0      0 127.0.0.1:9051          0.0.0.0:*         LISTEN   1641/tor  ",
-  "tcp6       0      0 ::1:631                 :::*              LISTEN   -     ",
-  "udp        0      0 0.0.0.0:5353            0.0.0.0:*                  -     ",
-  "udp6       0      0 fe80::7ae4:ff:fe2f::123 :::*                       -     "]
+  'Active Internet connections (only servers)',
+  'Proto Recv-Q Send-Q Local Address           Foreign Address   State    PID/Program name',
+  'tcp        0      0 127.0.0.1:631           0.0.0.0:*         LISTEN   -     ',
+  'tcp        0      0 127.0.0.1:9051          0.0.0.0:*         LISTEN   1641/tor  ',
+  'tcp6       0      0 ::1:631                 :::*              LISTEN   -     ',
+  'udp        0      0 0.0.0.0:5353            0.0.0.0:*                  -     ',
+  'udp6       0      0 fe80::7ae4:ff:fe2f::123 :::*                       -     ']
 
 GET_PID_BY_PORT_SOCKSTAT_RESULTS = [
-  "_tor     tor        4397  7  tcp4   51.64.7.84:9051    *:*",
-  "_tor     tor        4397  12 tcp4   51.64.7.84:54011   80.3.121.7:9051",
-  "_tor     tor        4397  15 tcp4   51.64.7.84:59374   7.42.1.102:9051"]
+  '_tor     tor        4397  7  tcp4   51.64.7.84:9051    *:*',
+  '_tor     tor        4397  12 tcp4   51.64.7.84:54011   80.3.121.7:9051',
+  '_tor     tor        4397  15 tcp4   51.64.7.84:59374   7.42.1.102:9051']
 
 GET_PID_BY_PORT_LSOF_RESULTS = [
-  "COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME",
-  "tor     1745 atagar    6u  IPv4  14229      0t0  TCP 127.0.0.1:9051 (LISTEN)",
-  "apache   329 atagar    6u  IPv4  14229      0t0  TCP 127.0.0.1:80 (LISTEN)"]
+  'COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME',
+  'tor     1745 atagar    6u  IPv4  14229      0t0  TCP 127.0.0.1:9051 (LISTEN)',
+  'apache   329 atagar    6u  IPv4  14229      0t0  TCP 127.0.0.1:80 (LISTEN)']
 
 GET_BSD_JAIL_PATH_RESULTS = [
-  "   JID  IP Address      Hostname      Path",
-  "     1  10.0.0.2        tor-jail      /usr/jails/tor-jail",
+  '   JID  IP Address      Hostname      Path',
+  '     1  10.0.0.2        tor-jail      /usr/jails/tor-jail',
 ]
 
 
@@ -77,20 +77,18 @@ def mock_call(base_cmd, responses):
   - Simple usage is for base_cmd is the system call we want to respond to and
     responses is a list containing the respnose. For instance...
 
-    mock_call("ls my_dir", ["file1", "file2", "file3"])
+    mock_call('ls my_dir', ['file1', 'file2', 'file3'])
 
   - The base_cmd can be a formatted string and responses are a dictionary of
     completions for tat string to the responses. For instance...
 
-    mock_call("ls %s", {"dir1": ["file1", "file2"], "dir2": ["file3", "file4"]})
+    mock_call('ls %s', {'dir1': ['file1', 'file2'], 'dir2': ['file3', 'file4']})
 
-  Arguments:
-    base_cmd (str)         - command to match against
-    responses (list, dict) - either list with the response, or mapping of
-                             base_cmd formatted string completions to responses
+  :param str base_cmd: command to match against
+  :param list,dict responses: either list with the response, or mapping of
+    base_cmd formatted string completions to responses
 
-  Returns:
-    functor to override stem.util.system.call with
+  :returns: **functor** to override stem.util.system.call with
   """
 
   def _mock_call(base_cmd, responses, command, default = None):
@@ -118,24 +116,24 @@ class TestSystem(unittest.TestCase):
     """
 
     # mock response with a linux and bsd resolver
-    running_commands = [u"irssi", u"moc", u"tor", u"ps", u"  firefox  "]
+    running_commands = [u'irssi', u'moc', u'tor', u'ps', u'  firefox  ']
 
     for ps_cmd in (system.IS_RUNNING_PS_LINUX, system.IS_RUNNING_PS_BSD):
       call_mock.side_effect = mock_call(ps_cmd, running_commands)
 
-      self.assertTrue(system.is_running("irssi"))
-      self.assertTrue(system.is_running("moc"))
-      self.assertTrue(system.is_running("tor"))
-      self.assertTrue(system.is_running("ps"))
-      self.assertTrue(system.is_running("firefox"))
-      self.assertEqual(False, system.is_running("something_else"))
+      self.assertTrue(system.is_running('irssi'))
+      self.assertTrue(system.is_running('moc'))
+      self.assertTrue(system.is_running('tor'))
+      self.assertTrue(system.is_running('ps'))
+      self.assertTrue(system.is_running('firefox'))
+      self.assertEqual(False, system.is_running('something_else'))
 
     # mock both calls failing
 
     call_mock.return_value = None
     call_mock.side_effect = None
-    self.assertFalse(system.is_running("irssi"))
-    self.assertEquals(None, system.is_running("irssi"))
+    self.assertFalse(system.is_running('irssi'))
+    self.assertEquals(None, system.is_running('irssi'))
 
   @patch('stem.util.system.call')
   @patch('stem.util.proc.is_available', Mock(return_value = False))
@@ -146,18 +144,18 @@ class TestSystem(unittest.TestCase):
     """
 
     responses = {
-      "success": ["COMMAND", "vim"],
-      "malformed_command_1": ["COMMAND"],
-      "malformed_command_2": ["foobar"],
-      "malformed_command_3": ["NOT_COMMAND", "vim"],
-      "no_results": [],
-      "command_fails": None,
+      'success': ['COMMAND', 'vim'],
+      'malformed_command_1': ['COMMAND'],
+      'malformed_command_2': ['foobar'],
+      'malformed_command_3': ['NOT_COMMAND', 'vim'],
+      'no_results': [],
+      'command_fails': None,
     }
 
     call_mock.side_effect = mock_call(system.GET_NAME_BY_PID_PS, responses)
 
     for test_input in responses:
-      expected_response = "vim" if test_input == "success" else None
+      expected_response = 'vim' if test_input == 'success' else None
       self.assertEquals(expected_response, system.get_name_by_pid(test_input))
 
   @patch('stem.util.system.call')
@@ -168,15 +166,15 @@ class TestSystem(unittest.TestCase):
     """
 
     responses = dict(GET_PID_BY_NAME_BASE_RESULTS)
-    responses["success"] = ["1111"]
-    responses["multiple_results"] = ["123", "456", "789"]
+    responses['success'] = ['1111']
+    responses['multiple_results'] = ['123', '456', '789']
     call_mock.side_effect = mock_call(system.GET_PID_BY_NAME_PGREP, responses)
 
     for test_input in responses:
-      expected_response = 1111 if test_input == "success" else None
+      expected_response = 1111 if test_input == 'success' else None
       self.assertEquals(expected_response, system.get_pid_by_name(test_input))
 
-    self.assertEquals([123, 456, 789], system.get_pid_by_name("multiple_results", multiple = True))
+    self.assertEquals([123, 456, 789], system.get_pid_by_name('multiple_results', multiple = True))
 
   @patch('stem.util.system.call')
   @patch('stem.util.system.is_available', Mock(return_value = True))
@@ -186,15 +184,15 @@ class TestSystem(unittest.TestCase):
     """
 
     responses = dict(GET_PID_BY_NAME_BASE_RESULTS)
-    responses["success"] = ["1111"]
-    responses["multiple_results"] = ["123 456 789"]
+    responses['success'] = ['1111']
+    responses['multiple_results'] = ['123 456 789']
     call_mock.side_effect = mock_call(system.GET_PID_BY_NAME_PIDOF, responses)
 
     for test_input in responses:
-      expected_response = 1111 if test_input == "success" else None
+      expected_response = 1111 if test_input == 'success' else None
       self.assertEquals(expected_response, system.get_pid_by_name(test_input))
 
-    self.assertEquals([123, 456, 789], system.get_pid_by_name("multiple_results", multiple = True))
+    self.assertEquals([123, 456, 789], system.get_pid_by_name('multiple_results', multiple = True))
 
   @patch('stem.util.system.call')
   @patch('stem.util.system.is_bsd', Mock(return_value = False))
@@ -205,15 +203,15 @@ class TestSystem(unittest.TestCase):
     """
 
     responses = dict(GET_PID_BY_NAME_BASE_RESULTS)
-    responses["success"] = ["PID", " 1111"]
-    responses["multiple_results"] = ["PID", " 123", " 456", " 789"]
+    responses['success'] = ['PID', ' 1111']
+    responses['multiple_results'] = ['PID', ' 123', ' 456', ' 789']
     call_mock.side_effect = mock_call(system.GET_PID_BY_NAME_PS_LINUX, responses)
 
     for test_input in responses:
-      expected_response = 1111 if test_input == "success" else None
+      expected_response = 1111 if test_input == 'success' else None
       self.assertEquals(expected_response, system.get_pid_by_name(test_input))
 
-    self.assertEquals([123, 456, 789], system.get_pid_by_name("multiple_results", multiple = True))
+    self.assertEquals([123, 456, 789], system.get_pid_by_name('multiple_results', multiple = True))
 
   @patch('stem.util.system.call')
   @patch('stem.util.system.is_bsd', Mock(return_value = True))
@@ -224,13 +222,13 @@ class TestSystem(unittest.TestCase):
     """
 
     call_mock.side_effect = mock_call(system.GET_PID_BY_NAME_PS_BSD, GET_PID_BY_NAME_PS_BSD)
-    self.assertEquals(1, system.get_pid_by_name("launchd"))
-    self.assertEquals(11, system.get_pid_by_name("DirectoryService"))
-    self.assertEquals(None, system.get_pid_by_name("blarg"))
+    self.assertEquals(1, system.get_pid_by_name('launchd'))
+    self.assertEquals(11, system.get_pid_by_name('DirectoryService'))
+    self.assertEquals(None, system.get_pid_by_name('blarg'))
 
     call_mock.side_effect = mock_call(system.GET_PID_BY_NAME_PS_BSD, GET_PID_BY_NAME_PS_BSD_MULTIPLE)
 
-    self.assertEquals([1, 41], system.get_pid_by_name("launchd", multiple = True))
+    self.assertEquals([1, 41], system.get_pid_by_name('launchd', multiple = True))
 
   @patch('stem.util.system.call')
   @patch('stem.util.system.is_available', Mock(return_value = True))
@@ -240,15 +238,15 @@ class TestSystem(unittest.TestCase):
     """
 
     responses = dict(GET_PID_BY_NAME_BASE_RESULTS)
-    responses["success"] = ["1111"]
-    responses["multiple_results"] = ["123", "456", "789"]
+    responses['success'] = ['1111']
+    responses['multiple_results'] = ['123', '456', '789']
     call_mock.side_effect = mock_call(system.GET_PID_BY_NAME_LSOF, responses)
 
     for test_input in responses:
-      expected_response = 1111 if test_input == "success" else None
+      expected_response = 1111 if test_input == 'success' else None
       self.assertEquals(expected_response, system.get_pid_by_name(test_input))
 
-    self.assertEquals([123, 456, 789], system.get_pid_by_name("multiple_results", multiple = True))
+    self.assertEquals([123, 456, 789], system.get_pid_by_name('multiple_results', multiple = True))
 
   @patch('stem.util.system.call')
   @patch('stem.util.system.is_available', Mock(return_value = True))
@@ -259,7 +257,7 @@ class TestSystem(unittest.TestCase):
 
     call_mock.side_effect = mock_call(system.GET_PID_BY_PORT_NETSTAT, GET_PID_BY_PORT_NETSTAT_RESULTS)
     self.assertEquals(1641, system.get_pid_by_port(9051))
-    self.assertEquals(1641, system.get_pid_by_port("9051"))
+    self.assertEquals(1641, system.get_pid_by_port('9051'))
     self.assertEquals(None, system.get_pid_by_port(631))
     self.assertEquals(None, system.get_pid_by_port(123))
 
@@ -272,7 +270,7 @@ class TestSystem(unittest.TestCase):
 
     call_mock.side_effect = mock_call(system.GET_PID_BY_PORT_SOCKSTAT % 9051, GET_PID_BY_PORT_SOCKSTAT_RESULTS)
     self.assertEquals(4397, system.get_pid_by_port(9051))
-    self.assertEquals(4397, system.get_pid_by_port("9051"))
+    self.assertEquals(4397, system.get_pid_by_port('9051'))
     self.assertEquals(None, system.get_pid_by_port(123))
 
   @patch('stem.util.system.call')
@@ -284,7 +282,7 @@ class TestSystem(unittest.TestCase):
 
     call_mock.side_effect = mock_call(system.GET_PID_BY_PORT_LSOF, GET_PID_BY_PORT_LSOF_RESULTS)
     self.assertEquals(1745, system.get_pid_by_port(9051))
-    self.assertEquals(1745, system.get_pid_by_port("9051"))
+    self.assertEquals(1745, system.get_pid_by_port('9051'))
     self.assertEquals(329, system.get_pid_by_port(80))
     self.assertEquals(None, system.get_pid_by_port(123))
 
@@ -295,13 +293,13 @@ class TestSystem(unittest.TestCase):
     Tests the get_pid_by_open_file function with a lsof response.
     """
 
-    lsof_query = system.GET_PID_BY_FILE_LSOF % "/tmp/foo"
-    call_mock.side_effect = mock_call(lsof_query, ["4762"])
-    self.assertEquals(4762, system.get_pid_by_open_file("/tmp/foo"))
+    lsof_query = system.GET_PID_BY_FILE_LSOF % '/tmp/foo'
+    call_mock.side_effect = mock_call(lsof_query, ['4762'])
+    self.assertEquals(4762, system.get_pid_by_open_file('/tmp/foo'))
 
     call_mock.return_value = []
     call_mock.side_effect = None
-    self.assertEquals(None, system.get_pid_by_open_file("/tmp/somewhere_else"))
+    self.assertEquals(None, system.get_pid_by_open_file('/tmp/somewhere_else'))
 
   @patch('stem.util.system.call')
   @patch('stem.util.proc.is_available', Mock(return_value = False))
@@ -312,16 +310,16 @@ class TestSystem(unittest.TestCase):
     """
 
     responses = {
-      "3799": ["3799: /home/atagar"],
-      "5839": ["5839: No such process"],
-      "1234": ["malformed output"],
-      "7878": None,
+      '3799': ['3799: /home/atagar'],
+      '5839': ['5839: No such process'],
+      '1234': ['malformed output'],
+      '7878': None,
     }
 
     call_mock.side_effect = mock_call(system.GET_CWD_PWDX, responses)
 
     for test_input in responses:
-      expected_response = "/home/atagar" if test_input == "3799" else None
+      expected_response = '/home/atagar' if test_input == '3799' else None
       self.assertEquals(expected_response, system.get_cwd(test_input))
 
   @patch('stem.util.system.call')
@@ -333,15 +331,15 @@ class TestSystem(unittest.TestCase):
     """
 
     responses = {
-      "75717": ["p75717", "n/Users/atagar/tor/src/or"],
-      "1234": ["malformed output"],
-      "7878": [],
+      '75717': ['p75717', 'n/Users/atagar/tor/src/or'],
+      '1234': ['malformed output'],
+      '7878': [],
     }
 
     call_mock.side_effect = mock_call(system.GET_CWD_LSOF, responses)
 
     for test_input in responses:
-      expected_response = "/Users/atagar/tor/src/or" if test_input == "75717" else None
+      expected_response = '/Users/atagar/tor/src/or' if test_input == '75717' else None
       self.assertEquals(expected_response, system.get_cwd(test_input))
 
   @patch('stem.util.system.call')
@@ -352,18 +350,18 @@ class TestSystem(unittest.TestCase):
     """
 
     responses = {
-      "1111": ["JID", " 1"],
-      "2222": ["JID", " 0"],
-      "3333": ["JID", "bad data"],
-      "4444": ["bad data"],
-      "5555": [],
-      "6666": []
+      '1111': ['JID', ' 1'],
+      '2222': ['JID', ' 0'],
+      '3333': ['JID', 'bad data'],
+      '4444': ['bad data'],
+      '5555': [],
+      '6666': []
     }
 
     call_mock.side_effect = mock_call(system.GET_BSD_JAIL_ID_PS, responses)
 
     for test_input in responses:
-      expected_response = 1 if test_input == "1111" else 0
+      expected_response = 1 if test_input == '1111' else 0
       self.assertEquals(expected_response, system.get_bsd_jail_id(test_input))
 
   @patch('stem.util.system.call')
@@ -379,7 +377,7 @@ class TestSystem(unittest.TestCase):
     self.assertEquals(None, system.get_bsd_jail_path(1))
 
     call_mock.side_effect = mock_call(system.GET_BSD_JAIL_PATH % '1', GET_BSD_JAIL_PATH_RESULTS)
-    self.assertEquals("/usr/jails/tor-jail", system.get_bsd_jail_path(1))
+    self.assertEquals('/usr/jails/tor-jail', system.get_bsd_jail_path(1))
 
   @patch('platform.system', Mock(return_value = 'Linux'))
   @patch('os.path.join', Mock(side_effect = posixpath.join))
@@ -390,13 +388,13 @@ class TestSystem(unittest.TestCase):
     tests).
     """
 
-    self.assertEquals("", system.expand_path(""))
-    self.assertEquals("/tmp", system.expand_path("/tmp"))
-    self.assertEquals("/tmp", system.expand_path("/tmp/"))
-    self.assertEquals("/tmp", system.expand_path(".", "/tmp"))
-    self.assertEquals("/tmp", system.expand_path("./", "/tmp"))
-    self.assertEquals("/tmp/foo", system.expand_path("foo", "/tmp"))
-    self.assertEquals("/tmp/foo", system.expand_path("./foo", "/tmp"))
+    self.assertEquals('', system.expand_path(''))
+    self.assertEquals('/tmp', system.expand_path('/tmp'))
+    self.assertEquals('/tmp', system.expand_path('/tmp/'))
+    self.assertEquals('/tmp', system.expand_path('.', '/tmp'))
+    self.assertEquals('/tmp', system.expand_path('./', '/tmp'))
+    self.assertEquals('/tmp/foo', system.expand_path('foo', '/tmp'))
+    self.assertEquals('/tmp/foo', system.expand_path('./foo', '/tmp'))
 
   @patch('platform.system', Mock(return_value = 'Windows'))
   @patch('os.path.join', Mock(side_effect = ntpath.join))
@@ -407,10 +405,10 @@ class TestSystem(unittest.TestCase):
     (that's left to integ tests).
     """
 
-    self.assertEquals("", system.expand_path(""))
-    self.assertEquals("C:\\tmp", system.expand_path("C:\\tmp"))
-    self.assertEquals("C:\\tmp", system.expand_path("C:\\tmp\\"))
-    self.assertEquals("C:\\tmp", system.expand_path(".", "C:\\tmp"))
-    self.assertEquals("C:\\tmp", system.expand_path(".\\", "C:\\tmp"))
-    self.assertEquals("C:\\tmp\\foo", system.expand_path("foo", "C:\\tmp"))
-    self.assertEquals("C:\\tmp\\foo", system.expand_path(".\\foo", "C:\\tmp"))
+    self.assertEquals('', system.expand_path(''))
+    self.assertEquals('C:\\tmp', system.expand_path('C:\\tmp'))
+    self.assertEquals('C:\\tmp', system.expand_path('C:\\tmp\\'))
+    self.assertEquals('C:\\tmp', system.expand_path('.', 'C:\\tmp'))
+    self.assertEquals('C:\\tmp', system.expand_path('.\\', 'C:\\tmp'))
+    self.assertEquals('C:\\tmp\\foo', system.expand_path('foo', 'C:\\tmp'))
+    self.assertEquals('C:\\tmp\\foo', system.expand_path('.\\foo', 'C:\\tmp'))
diff --git a/test/unit/util/tor_tools.py b/test/unit/util/tor_tools.py
index c322431..6e3af86 100644
--- a/test/unit/util/tor_tools.py
+++ b/test/unit/util/tor_tools.py
@@ -14,16 +14,16 @@ class TestTorTools(unittest.TestCase):
     """
 
     valid_fingerprints = (
-      "$A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB",
-      "$a7569a83b5706ab1b1a9cb52eff7d2d32e4553eb",
+      '$A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB',
+      '$a7569a83b5706ab1b1a9cb52eff7d2d32e4553eb',
     )
 
     invalid_fingerprints = (
-      "",
-      "A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB",
-      "$A7569A83B5706AB1B1A9CB52EFF7D2D32E4553E",
-      "$A7569A83B5706AB1B1A9CB52EFF7D2D32E4553E33",
-      "$A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EG",
+      '',
+      'A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB',
+      '$A7569A83B5706AB1B1A9CB52EFF7D2D32E4553E',
+      '$A7569A83B5706AB1B1A9CB52EFF7D2D32E4553E33',
+      '$A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EG',
     )
 
     for fingerprint in valid_fingerprints:
@@ -38,16 +38,16 @@ class TestTorTools(unittest.TestCase):
     """
 
     valid_nicknames = (
-      "caerSidi",
-      "a",
-      "abcABC123",
+      'caerSidi',
+      'a',
+      'abcABC123',
     )
 
     invalid_nicknames = (
       None,
-      "",
-      "toolongggggggggggggg",
-      "bad_character",
+      '',
+      'toolongggggggggggggg',
+      'bad_character',
     )
 
     for nickname in valid_nicknames:
@@ -62,18 +62,18 @@ class TestTorTools(unittest.TestCase):
     """
 
     valid_circuit_ids = (
-      "0",
-      "2",
-      "abcABC123",
+      '0',
+      '2',
+      'abcABC123',
     )
 
     invalid_circuit_ids = (
       None,
-      "",
+      '',
       0,
       2,
-      "toolonggggggggggg",
-      "bad_character",
+      'toolonggggggggggg',
+      'bad_character',
     )
 
     for circuit_id in valid_circuit_ids:
diff --git a/test/unit/version.py b/test/unit/version.py
index 77551aa..df5b57e 100644
--- a/test/unit/version.py
+++ b/test/unit/version.py
@@ -29,8 +29,8 @@ class TestVersion(unittest.TestCase):
 
     version = stem.version.get_system_tor_version()
 
-    self.assert_versions_match(version, 0, 2, 2, 35, None, "git-73ff13ab3cc9570d")
-    self.assertEqual("73ff13ab3cc9570d", version.git_commit)
+    self.assert_versions_match(version, 0, 2, 2, 35, None, 'git-73ff13ab3cc9570d')
+    self.assertEqual('73ff13ab3cc9570d', version.git_commit)
     call_mock.assert_called_once_with('tor --version')
 
     self.assertEqual({'tor': version}, stem.version.VERSION_CACHE)
@@ -42,44 +42,44 @@ class TestVersion(unittest.TestCase):
 
     # valid versions with various number of compontents to the version
 
-    version = Version("0.1.2.3-tag")
-    self.assert_versions_match(version, 0, 1, 2, 3, "tag", None)
+    version = Version('0.1.2.3-tag')
+    self.assert_versions_match(version, 0, 1, 2, 3, 'tag', None)
 
-    version = Version("0.1.2.3")
+    version = Version('0.1.2.3')
     self.assert_versions_match(version, 0, 1, 2, 3, None, None)
 
-    version = Version("0.1.2-tag")
-    self.assert_versions_match(version, 0, 1, 2, None, "tag", None)
+    version = Version('0.1.2-tag')
+    self.assert_versions_match(version, 0, 1, 2, None, 'tag', None)
 
-    version = Version("0.1.2")
+    version = Version('0.1.2')
     self.assert_versions_match(version, 0, 1, 2, None, None, None)
 
     # checks an empty tag
-    version = Version("0.1.2.3-")
-    self.assert_versions_match(version, 0, 1, 2, 3, "", None)
+    version = Version('0.1.2.3-')
+    self.assert_versions_match(version, 0, 1, 2, 3, '', None)
 
-    version = Version("0.1.2-")
-    self.assert_versions_match(version, 0, 1, 2, None, "", None)
+    version = Version('0.1.2-')
+    self.assert_versions_match(version, 0, 1, 2, None, '', None)
 
     # check with extra informaton
-    version = Version("0.1.2.3-tag (git-73ff13ab3cc9570d)")
-    self.assert_versions_match(version, 0, 1, 2, 3, "tag", "git-73ff13ab3cc9570d")
-    self.assertEqual("73ff13ab3cc9570d", version.git_commit)
+    version = Version('0.1.2.3-tag (git-73ff13ab3cc9570d)')
+    self.assert_versions_match(version, 0, 1, 2, 3, 'tag', 'git-73ff13ab3cc9570d')
+    self.assertEqual('73ff13ab3cc9570d', version.git_commit)
 
-    version = Version("0.1.2.3-tag ()")
-    self.assert_versions_match(version, 0, 1, 2, 3, "tag", "")
+    version = Version('0.1.2.3-tag ()')
+    self.assert_versions_match(version, 0, 1, 2, 3, 'tag', '')
 
-    version = Version("0.1.2 (git-73ff13ab3cc9570d)")
-    self.assert_versions_match(version, 0, 1, 2, None, None, "git-73ff13ab3cc9570d")
+    version = Version('0.1.2 (git-73ff13ab3cc9570d)')
+    self.assert_versions_match(version, 0, 1, 2, None, None, 'git-73ff13ab3cc9570d')
 
     # checks invalid version strings
-    self.assertRaises(ValueError, stem.version.Version, "")
-    self.assertRaises(ValueError, stem.version.Version, "1.2.3.4nodash")
-    self.assertRaises(ValueError, stem.version.Version, "1.2.3.a")
-    self.assertRaises(ValueError, stem.version.Version, "1.2.a.4")
-    self.assertRaises(ValueError, stem.version.Version, "1x2x3x4")
-    self.assertRaises(ValueError, stem.version.Version, "12.3")
-    self.assertRaises(ValueError, stem.version.Version, "1.-2.3")
+    self.assertRaises(ValueError, stem.version.Version, '')
+    self.assertRaises(ValueError, stem.version.Version, '1.2.3.4nodash')
+    self.assertRaises(ValueError, stem.version.Version, '1.2.3.a')
+    self.assertRaises(ValueError, stem.version.Version, '1.2.a.4')
+    self.assertRaises(ValueError, stem.version.Version, '1x2x3x4')
+    self.assertRaises(ValueError, stem.version.Version, '12.3')
+    self.assertRaises(ValueError, stem.version.Version, '1.-2.3')
 
   def test_comparison(self):
     """
@@ -87,28 +87,28 @@ class TestVersion(unittest.TestCase):
     """
 
     # check for basic incrementing in each portion
-    self.assert_version_is_greater("1.1.2.3-tag", "0.1.2.3-tag")
-    self.assert_version_is_greater("0.2.2.3-tag", "0.1.2.3-tag")
-    self.assert_version_is_greater("0.1.3.3-tag", "0.1.2.3-tag")
-    self.assert_version_is_greater("0.1.2.4-tag", "0.1.2.3-tag")
-    self.assert_version_is_greater("0.1.2.3-ugg", "0.1.2.3-tag")
-    self.assert_version_is_equal("0.1.2.3-tag", "0.1.2.3-tag")
+    self.assert_version_is_greater('1.1.2.3-tag', '0.1.2.3-tag')
+    self.assert_version_is_greater('0.2.2.3-tag', '0.1.2.3-tag')
+    self.assert_version_is_greater('0.1.3.3-tag', '0.1.2.3-tag')
+    self.assert_version_is_greater('0.1.2.4-tag', '0.1.2.3-tag')
+    self.assert_version_is_greater('0.1.2.3-ugg', '0.1.2.3-tag')
+    self.assert_version_is_equal('0.1.2.3-tag', '0.1.2.3-tag')
 
     # check with common tags
-    self.assert_version_is_greater("0.1.2.3-beta", "0.1.2.3-alpha")
-    self.assert_version_is_greater("0.1.2.3-rc", "0.1.2.3-beta")
+    self.assert_version_is_greater('0.1.2.3-beta', '0.1.2.3-alpha')
+    self.assert_version_is_greater('0.1.2.3-rc', '0.1.2.3-beta')
 
     # checks that a missing patch level equals zero
-    self.assert_version_is_equal("0.1.2", "0.1.2.0")
-    self.assert_version_is_equal("0.1.2-tag", "0.1.2.0-tag")
+    self.assert_version_is_equal('0.1.2', '0.1.2.0')
+    self.assert_version_is_equal('0.1.2-tag', '0.1.2.0-tag')
 
     # checks for missing patch or status
-    self.assert_version_is_greater("0.1.2.3-tag", "0.1.2.3")
-    self.assert_version_is_greater("0.1.2.3-tag", "0.1.2-tag")
-    self.assert_version_is_greater("0.1.2.3-tag", "0.1.2")
+    self.assert_version_is_greater('0.1.2.3-tag', '0.1.2.3')
+    self.assert_version_is_greater('0.1.2.3-tag', '0.1.2-tag')
+    self.assert_version_is_greater('0.1.2.3-tag', '0.1.2')
 
-    self.assert_version_is_equal("0.1.2.3", "0.1.2.3")
-    self.assert_version_is_equal("0.1.2", "0.1.2")
+    self.assert_version_is_equal('0.1.2.3', '0.1.2.3')
+    self.assert_version_is_equal('0.1.2', '0.1.2')
 
   def test_nonversion_comparison(self):
     """
@@ -118,7 +118,7 @@ class TestVersion(unittest.TestCase):
     comparisons result in a TypeError.
     """
 
-    test_version = Version("0.1.2.3")
+    test_version = Version('0.1.2.3')
     self.assertNotEqual(test_version, None)
     self.assertNotEqual(test_version, 5)
 
@@ -128,9 +128,9 @@ class TestVersion(unittest.TestCase):
     """
 
     # checks conversion with various numbers of arguments
-    self.assert_string_matches("0.1.2.3-tag")
-    self.assert_string_matches("0.1.2.3")
-    self.assert_string_matches("0.1.2")
+    self.assert_string_matches('0.1.2.3-tag')
+    self.assert_string_matches('0.1.2.3')
+    self.assert_string_matches('0.1.2')
 
   def test_requirements_greater_than(self):
     """
@@ -138,20 +138,20 @@ class TestVersion(unittest.TestCase):
     """
 
     requirements = stem.version._VersionRequirements()
-    requirements.greater_than(Version("0.2.2.36"))
+    requirements.greater_than(Version('0.2.2.36'))
 
-    self.assertTrue(Version("0.2.2.36") >= requirements)
-    self.assertTrue(Version("0.2.2.37") >= requirements)
-    self.assertTrue(Version("0.2.3.36") >= requirements)
-    self.assertFalse(Version("0.2.2.35") >= requirements)
-    self.assertFalse(Version("0.2.1.38") >= requirements)
+    self.assertTrue(Version('0.2.2.36') >= requirements)
+    self.assertTrue(Version('0.2.2.37') >= requirements)
+    self.assertTrue(Version('0.2.3.36') >= requirements)
+    self.assertFalse(Version('0.2.2.35') >= requirements)
+    self.assertFalse(Version('0.2.1.38') >= requirements)
 
     requirements = stem.version._VersionRequirements()
-    requirements.greater_than(Version("0.2.2.36"), False)
+    requirements.greater_than(Version('0.2.2.36'), False)
 
-    self.assertFalse(Version("0.2.2.35") >= requirements)
-    self.assertFalse(Version("0.2.2.36") >= requirements)
-    self.assertTrue(Version("0.2.2.37") >= requirements)
+    self.assertFalse(Version('0.2.2.35') >= requirements)
+    self.assertFalse(Version('0.2.2.36') >= requirements)
+    self.assertTrue(Version('0.2.2.37') >= requirements)
 
   def test_requirements_less_than(self):
     """
@@ -159,20 +159,20 @@ class TestVersion(unittest.TestCase):
     """
 
     requirements = stem.version._VersionRequirements()
-    requirements.less_than(Version("0.2.2.36"))
+    requirements.less_than(Version('0.2.2.36'))
 
-    self.assertTrue(Version("0.2.2.36") >= requirements)
-    self.assertTrue(Version("0.2.2.35") >= requirements)
-    self.assertTrue(Version("0.2.1.38") >= requirements)
-    self.assertFalse(Version("0.2.2.37") >= requirements)
-    self.assertFalse(Version("0.2.3.36") >= requirements)
+    self.assertTrue(Version('0.2.2.36') >= requirements)
+    self.assertTrue(Version('0.2.2.35') >= requirements)
+    self.assertTrue(Version('0.2.1.38') >= requirements)
+    self.assertFalse(Version('0.2.2.37') >= requirements)
+    self.assertFalse(Version('0.2.3.36') >= requirements)
 
     requirements = stem.version._VersionRequirements()
-    requirements.less_than(Version("0.2.2.36"), False)
+    requirements.less_than(Version('0.2.2.36'), False)
 
-    self.assertFalse(Version("0.2.2.37") >= requirements)
-    self.assertFalse(Version("0.2.2.36") >= requirements)
-    self.assertTrue(Version("0.2.2.35") >= requirements)
+    self.assertFalse(Version('0.2.2.37') >= requirements)
+    self.assertFalse(Version('0.2.2.36') >= requirements)
+    self.assertTrue(Version('0.2.2.35') >= requirements)
 
   def test_requirements_in_range(self):
     """
@@ -180,19 +180,19 @@ class TestVersion(unittest.TestCase):
     """
 
     requirements = stem.version._VersionRequirements()
-    requirements.in_range(Version("0.2.2.36"), Version("0.2.2.38"))
+    requirements.in_range(Version('0.2.2.36'), Version('0.2.2.38'))
 
-    self.assertFalse(Version("0.2.2.35") >= requirements)
-    self.assertTrue(Version("0.2.2.36") >= requirements)
-    self.assertTrue(Version("0.2.2.37") >= requirements)
-    self.assertFalse(Version("0.2.2.38") >= requirements)
+    self.assertFalse(Version('0.2.2.35') >= requirements)
+    self.assertTrue(Version('0.2.2.36') >= requirements)
+    self.assertTrue(Version('0.2.2.37') >= requirements)
+    self.assertFalse(Version('0.2.2.38') >= requirements)
 
     # rule for 'anything in the 0.2.2.x series'
     requirements = stem.version._VersionRequirements()
-    requirements.in_range(Version("0.2.2.0"), Version("0.2.3.0"))
+    requirements.in_range(Version('0.2.2.0'), Version('0.2.3.0'))
 
     for index in xrange(0, 100):
-      self.assertTrue(Version("0.2.2.%i" % index) >= requirements)
+      self.assertTrue(Version('0.2.2.%i' % index) >= requirements)
 
   def test_requirements_multiple_rules(self):
     """
@@ -201,14 +201,14 @@ class TestVersion(unittest.TestCase):
 
     # rule to say 'anything but the 0.2.2.x series'
     requirements = stem.version._VersionRequirements()
-    requirements.greater_than(Version("0.2.3.0"))
-    requirements.less_than(Version("0.2.2.0"), False)
+    requirements.greater_than(Version('0.2.3.0'))
+    requirements.less_than(Version('0.2.2.0'), False)
 
-    self.assertTrue(Version("0.2.3.0") >= requirements)
-    self.assertFalse(Version("0.2.2.0") >= requirements)
+    self.assertTrue(Version('0.2.3.0') >= requirements)
+    self.assertFalse(Version('0.2.2.0') >= requirements)
 
     for index in xrange(0, 100):
-      self.assertFalse(Version("0.2.2.%i" % index) >= requirements)
+      self.assertFalse(Version('0.2.2.%i' % index) >= requirements)
 
   def assert_versions_match(self, version, major, minor, micro, patch, status, extra):
     """
diff --git a/test/util.py b/test/util.py
index 52ea8f8..714d949 100644
--- a/test/util.py
+++ b/test/util.py
@@ -52,29 +52,29 @@ import test.output
 
 from test.output import STATUS, ERROR, NO_NL, println
 
-CONFIG = stem.util.conf.config_dict("test", {
-  "msg.help": "",
-  "target.description": {},
-  "target.prereq": {},
-  "target.torrc": {},
-  "integ.test_directory": "./test/data",
-  "test.unit_tests": "",
-  "test.integ_tests": "",
+CONFIG = stem.util.conf.config_dict('test', {
+  'msg.help': '',
+  'target.description': {},
+  'target.prereq': {},
+  'target.torrc': {},
+  'integ.test_directory': './test/data',
+  'test.unit_tests': '',
+  'test.integ_tests': '',
 })
 
 Target = stem.util.enum.UppercaseEnum(
-  "ONLINE",
-  "RELATIVE",
-  "CHROOT",
-  "RUN_NONE",
-  "RUN_OPEN",
-  "RUN_PASSWORD",
-  "RUN_COOKIE",
-  "RUN_MULTIPLE",
-  "RUN_SOCKET",
-  "RUN_SCOOKIE",
-  "RUN_PTRACE",
-  "RUN_ALL",
+  'ONLINE',
+  'RELATIVE',
+  'CHROOT',
+  'RUN_NONE',
+  'RUN_OPEN',
+  'RUN_PASSWORD',
+  'RUN_COOKIE',
+  'RUN_MULTIPLE',
+  'RUN_SOCKET',
+  'RUN_SCOOKIE',
+  'RUN_PTRACE',
+  'RUN_ALL',
 )
 
 # We make some paths relative to stem's base directory (the one above us)
@@ -92,7 +92,7 @@ def get_unit_tests(module_substring = None):
   :returns: an **iterator** for our unit tests
   """
 
-  return _get_tests(CONFIG["test.unit_tests"].splitlines(), module_substring)
+  return _get_tests(CONFIG['test.unit_tests'].splitlines(), module_substring)
 
 
 def get_integ_tests(module_substring = None):
@@ -104,7 +104,7 @@ def get_integ_tests(module_substring = None):
   :returns: an **iterator** for our integration tests
   """
 
-  return _get_tests(CONFIG["test.integ_tests"].splitlines(), module_substring)
+  return _get_tests(CONFIG['test.integ_tests'].splitlines(), module_substring)
 
 
 def _get_tests(modules, module_substring):
@@ -124,7 +124,7 @@ def _get_tests(modules, module_substring):
       module_name = '.'.join(import_name.split('.')[:-1])
       module = __import__(module_name)
 
-      for subcomponent in import_name.split(".")[1:]:
+      for subcomponent in import_name.split('.')[1:]:
         module = getattr(module, subcomponent)
 
       yield module
@@ -138,16 +138,16 @@ def get_help_message():
   :returns: **str** with our usage information
   """
 
-  help_msg = CONFIG["msg.help"]
+  help_msg = CONFIG['msg.help']
 
   # gets the longest target length so we can show the entries in columns
   target_name_length = max(map(len, Target))
-  description_format = "\n    %%-%is - %%s" % target_name_length
+  description_format = '\n    %%-%is - %%s' % target_name_length
 
   for target in Target:
-    help_msg += description_format % (target, CONFIG["target.description"].get(target, ""))
+    help_msg += description_format % (target, CONFIG['target.description'].get(target, ''))
 
-  help_msg += "\n"
+  help_msg += '\n'
 
   return help_msg
 
@@ -163,7 +163,7 @@ def get_prereq(target):
     **None** if there is no prerequisite
   """
 
-  target_prereq = CONFIG["target.prereq"].get(target)
+  target_prereq = CONFIG['target.prereq'].get(target)
 
   if target_prereq:
     return stem.version.Requirement[target_prereq]
@@ -185,7 +185,7 @@ def get_torrc_entries(target):
 
   # converts the 'target.torrc' csv into a list of test.runner.Torrc enums
 
-  config_csv = CONFIG["target.torrc"].get(target)
+  config_csv = CONFIG['target.torrc'].get(target)
   torrc_opts = []
 
   if config_csv:
@@ -208,7 +208,7 @@ def get_python3_destination():
   :returns: **str** with the relative path to our python 3 location
   """
 
-  return os.path.join(CONFIG["integ.test_directory"], "python3")
+  return os.path.join(CONFIG['integ.test_directory'], 'python3')
 
 
 def check_stem_version():
@@ -224,7 +224,7 @@ def check_pycrypto_version():
     import Crypto
     return Crypto.__version__
   else:
-    return "missing"
+    return 'missing'
 
 
 def check_mock_version():
@@ -236,7 +236,7 @@ def check_mock_version():
 
     return mock.__version__
   else:
-    return "missing"
+    return 'missing'
 
 
 def check_pyflakes_version():
@@ -244,7 +244,7 @@ def check_pyflakes_version():
     import pyflakes
     return pyflakes.__version__
   except ImportError:
-    return "missing"
+    return 'missing'
 
 
 def check_pep8_version():
@@ -252,7 +252,7 @@ def check_pep8_version():
     import pep8
     return pep8.__version__
   except ImportError:
-    return "missing"
+    return 'missing'
 
 
 def clean_orphaned_pyc(paths):
@@ -262,7 +262,7 @@ def clean_orphaned_pyc(paths):
   :param list paths: paths to search for orphaned pyc files
   """
 
-  return ["removed %s" % path for path in stem.util.test_tools.clean_orphaned_pyc(paths)]
+  return ['removed %s' % path for path in stem.util.test_tools.clean_orphaned_pyc(paths)]
 
 
 def check_for_unused_tests(paths):
@@ -288,7 +288,7 @@ def check_for_unused_tests(paths):
       with open(py_path) as f:
         file_contents = f.read()
 
-      test_match = re.search("^class (\S*)\(unittest.TestCase\):$", file_contents, re.MULTILINE)
+      test_match = re.search('^class (\S*)\(unittest.TestCase\):$', file_contents, re.MULTILINE)
 
       if test_match:
         class_name = test_match.groups()[0]
@@ -298,11 +298,11 @@ def check_for_unused_tests(paths):
           unused_tests.append(module_name)
 
   if unused_tests:
-    raise ValueError("Test modules are missing from our test/settings.cfg:\n%s" % "\n".join(unused_tests))
+    raise ValueError('Test modules are missing from our test/settings.cfg:\n%s' % '\n'.join(unused_tests))
 
 
 def python3_prereq():
-  for required_cmd in ("2to3", "python3"):
+  for required_cmd in ('2to3', 'python3'):
     if not stem.util.system.is_available(required_cmd):
       raise ValueError("Unable to test python 3 because %s isn't in your path" % required_cmd)
 
@@ -311,19 +311,19 @@ def python3_clean(skip = False):
   location = get_python3_destination()
 
   if not os.path.exists(location):
-    return "skipped"
+    return 'skipped'
   elif skip:
     return ["Reusing '%s'. Run again with '--clean' if you want a fresh copy." % location]
   else:
     shutil.rmtree(location, ignore_errors = True)
-    return "done"
+    return 'done'
 
 
 def python3_copy_stem():
   destination = get_python3_destination()
 
   if os.path.exists(destination):
-    return "skipped"
+    return 'skipped'
 
   # skips the python3 destination (to avoid an infinite loop)
   def _ignore(src, names):
@@ -336,22 +336,22 @@ def python3_copy_stem():
   shutil.copytree('stem', os.path.join(destination, 'stem'))
   shutil.copytree('test', os.path.join(destination, 'test'), ignore = _ignore)
   shutil.copy('run_tests.py', os.path.join(destination, 'run_tests.py'))
-  stem.util.system.call("2to3 --write --nobackups --no-diffs %s" % get_python3_destination())
+  stem.util.system.call('2to3 --write --nobackups --no-diffs %s' % get_python3_destination())
 
-  return "done"
+  return 'done'
 
 
 def python3_run_tests():
   println()
   println()
 
-  python3_runner = os.path.join(get_python3_destination(), "run_tests.py")
-  exit_status = os.system("python3 %s %s" % (python3_runner, " ".join(sys.argv[1:])))
+  python3_runner = os.path.join(get_python3_destination(), 'run_tests.py')
+  exit_status = os.system('python3 %s %s' % (python3_runner, ' '.join(sys.argv[1:])))
   sys.exit(exit_status)
 
 
 def _is_test_data(path):
-  return os.path.normpath(CONFIG["integ.test_directory"]) in path
+  return os.path.normpath(CONFIG['integ.test_directory']) in path
 
 
 def run_tasks(category, *tasks):
@@ -373,7 +373,7 @@ def run_tasks(category, *tasks):
     task.run()
 
     if task.is_required and task.error:
-      println("\n%s\n" % task.error, ERROR)
+      println('\n%s\n' % task.error, ERROR)
       sys.exit(1)
 
   println()
@@ -399,10 +399,10 @@ class Task(object):
     self.result = None
 
   def run(self):
-    println("  %s..." % self.label, STATUS, NO_NL)
+    println('  %s...' % self.label, STATUS, NO_NL)
 
     padding = 50 - len(self.label)
-    println(" " * padding, NO_NL)
+    println(' ' * padding, NO_NL)
 
     try:
       if self.args:
@@ -411,7 +411,7 @@ class Task(object):
         self.result = self.runner()
 
       self.is_successful = True
-      output_msg = "done"
+      output_msg = 'done'
 
       if self.print_result and isinstance(self.result, str):
         output_msg = self.result
@@ -420,12 +420,12 @@ class Task(object):
 
       if self.print_result and isinstance(self.result, (list, tuple)):
         for line in self.result:
-          println("    %s" % line, STATUS)
+          println('    %s' % line, STATUS)
     except Exception as exc:
       output_msg = str(exc)
 
       if not output_msg or self.is_required:
-        output_msg = "failed"
+        output_msg = 'failed'
 
       println(output_msg, ERROR)
       self.error = exc




_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits