commit b3c00c4a6d0565939745e6eba2064b17aaff491a Author: Damian Johnson atagar@torproject.org Date: Sat Mar 23 15:55:13 2013 -0700
Dropping python 2.5 compatibility hacks
As discussed on tor-dev@ there's a lot of arguments against maintaining support for python 2.5 and precious few for...
https://lists.torproject.org/pipermail/tor-dev/2013-March/004551.html
Dropping all the hacks we adopted to support it. --- stem/connection.py | 2 - stem/control.py | 15 ++---- stem/descriptor/reader.py | 19 ++----- stem/process.py | 2 - stem/response/__init__.py | 2 - stem/socket.py | 1 - stem/util/conf.py | 3 - stem/util/enum.py | 8 +-- stem/util/log.py | 2 +- test/integ/connection/authentication.py | 2 - test/integ/control/base_controller.py | 2 - test/integ/control/controller.py | 2 - test/integ/descriptor/extrainfo_descriptor.py | 2 - test/integ/descriptor/microdescriptor.py | 2 - test/integ/descriptor/networkstatus.py | 2 - test/integ/descriptor/reader.py | 6 +- test/integ/descriptor/server_descriptor.py | 2 - test/integ/response/protocolinfo.py | 2 - test/integ/socket/control_message.py | 2 - test/integ/socket/control_socket.py | 2 - test/integ/util/proc.py | 2 - test/mocking.py | 58 --------------------- test/runner.py | 2 - test/static_checks.py | 16 ------ test/unit/descriptor/networkstatus/document_v3.py | 14 ++--- test/unit/descriptor/server_descriptor.py | 4 +- test/unit/tutorial.py | 5 +- 27 files changed, 26 insertions(+), 155 deletions(-)
diff --git a/stem/connection.py b/stem/connection.py index 4f63378..d1aa3e5 100644 --- a/stem/connection.py +++ b/stem/connection.py @@ -102,8 +102,6 @@ fine-grained control over the authentication process. For instance... ============== =========== """
-from __future__ import with_statement - import binascii import getpass import os diff --git a/stem/control.py b/stem/control.py index 02072d0..82cff41 100644 --- a/stem/control.py +++ b/stem/control.py @@ -134,8 +134,6 @@ providing its own for interacting at a higher level. ===================== =========== """
-from __future__ import with_statement - import io import os import Queue @@ -220,10 +218,6 @@ CACHEABLE_GETINFO_PARAMS = ( # is unavailable GEOIP_FAILURE_THRESHOLD = 5
-# TODO: The Thread's isAlive() method and threading's currentThread() was -# changed to the more conventional is_alive() and current_thread() in python -# 2.6 and above. We should use that when dropping python 2.5 compatibility. -
class BaseController(object): """ @@ -495,7 +489,7 @@ class BaseController(object): # joins on our threads if it's safe to do so
for t in (self._reader_thread, self._event_thread): - if t and t.isAlive() and threading.currentThread() != t: + if t and t.is_alive() and threading.current_thread() != t: t.join()
self._notify_status_listeners(State.CLOSED) @@ -516,7 +510,6 @@ class BaseController(object): # Any changes to our is_alive() state happen under the send lock, so we # need to have it to ensure it doesn't change beneath us.
- # TODO: when we drop python 2.5 compatibility we can simplify this with self._socket._get_send_lock(): with self._status_listeners_lock: # States imply that our socket is either alive or not, which may not @@ -559,12 +552,12 @@ class BaseController(object): # single thread, which would cause an unexpected exception. Best be safe.
with self._socket._get_send_lock(): - if not self._reader_thread or not self._reader_thread.isAlive(): + 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.setDaemon(True) self._reader_thread.start()
- if not self._event_thread or not self._event_thread.isAlive(): + 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.setDaemon(True) self._event_thread.start() @@ -1184,7 +1177,7 @@ class Controller(BaseController):
try: # TODO: We should iterate over the descriptors as they're read from the - # socket rather than reading the whole thing into memeory. + # socket rather than reading the whole thing into memory. # # https://trac.torproject.org/8248
diff --git a/stem/descriptor/reader.py b/stem/descriptor/reader.py index 01a2a3b..023777a 100644 --- a/stem/descriptor/reader.py +++ b/stem/descriptor/reader.py @@ -77,8 +77,6 @@ and picks up where it left off if ran again... +- FileMissing - File does not exist """
-from __future__ import with_statement - import mimetypes import os import Queue @@ -91,11 +89,6 @@ import stem.prereq # flag to indicate when the reader thread is out of descriptor files to read FINISHED = "DONE"
-# TODO: The threading.Event's isSet() method was changed to the more -# conventional is_set() in python 2.6 and above. We should use that when -# dropping python 2.5 compatibility... -# http://docs.python.org/library/threading.html#threading.Event.is_set -
class FileSkipped(Exception): "Base error when we can't provide descriptor data from a file." @@ -417,7 +410,7 @@ class DescriptorReader(object): new_processed_files = {} remaining_files = list(self._targets)
- while remaining_files and not self._is_stopped.isSet(): + while remaining_files and not self._is_stopped.is_set(): target = remaining_files.pop(0)
if not os.path.exists(target): @@ -436,14 +429,14 @@ class DescriptorReader(object):
self._processed_files = new_processed_files
- if not self._is_stopped.isSet(): + if not self._is_stopped.is_set(): self._unreturned_descriptors.put(FINISHED)
self._iter_notice.set()
def __iter__(self): with self._iter_lock: - while not self._is_stopped.isSet(): + while not self._is_stopped.is_set(): try: descriptor = self._unreturned_descriptors.get_nowait()
@@ -461,7 +454,7 @@ class DescriptorReader(object): self._handle_file(os.path.join(root, filename), new_processed_files)
# this can take a while if, say, we're including the root directory - if self._is_stopped.isSet(): + if self._is_stopped.is_set(): return
def _handle_file(self, target, new_processed_files): @@ -521,7 +514,7 @@ class DescriptorReader(object):
with open(target, 'rb') as target_file: for desc in stem.descriptor.parse_file(target_file, validate = self._validate, document_handler = self._document_handler): - if self._is_stopped.isSet(): + if self._is_stopped.is_set(): return
self._unreturned_descriptors.put(desc) @@ -550,7 +543,7 @@ class DescriptorReader(object):
try: for desc in stem.descriptor.parse_file(entry, validate = self._validate, document_handler = self._document_handler): - if self._is_stopped.isSet(): + if self._is_stopped.is_set(): return
desc._set_path(os.path.abspath(target)) diff --git a/stem/process.py b/stem/process.py index e848140..45a064a 100644 --- a/stem/process.py +++ b/stem/process.py @@ -18,8 +18,6 @@ Helper functions for working with tor as a process. launch_tor_with_config - starts a tor process with a custom torrc """
-from __future__ import with_statement - import os import re import signal diff --git a/stem/response/__init__.py b/stem/response/__init__.py index c59c9bd..1f2957a 100644 --- a/stem/response/__init__.py +++ b/stem/response/__init__.py @@ -30,8 +30,6 @@ Parses replies from the control socket. SingleLineResponse - Simple tor response only including a single line of information. """
-from __future__ import with_statement - __all__ = [ "events", "getinfo", diff --git a/stem/socket.py b/stem/socket.py index d459fb7..0cd4b0d 100644 --- a/stem/socket.py +++ b/stem/socket.py @@ -32,7 +32,6 @@ as instances of the :class:`~stem.response.ControlMessage` class. send_formatting - Performs the formatting expected from sent messages. """
-from __future__ import with_statement from __future__ import absolute_import
import re diff --git a/stem/util/conf.py b/stem/util/conf.py index 795cd82..eaad09b 100644 --- a/stem/util/conf.py +++ b/stem/util/conf.py @@ -157,8 +157,6 @@ Here's an expanation of what happened... +- get_value - provides the value for a given key as a string """
-from __future__ import with_statement - import threading
from stem.util import log @@ -478,7 +476,6 @@ class Config(object): elif not self._path: raise ValueError("Unable to save configuration: no path provided")
- # TODO: when we drop python 2.5 compatibility we can simplify this with self._contents_lock: with open(self._path, 'w') as output_file: for entry_key in sorted(self.keys()): diff --git a/stem/util/enum.py b/stem/util/enum.py index b39f675..917cca1 100644 --- a/stem/util/enum.py +++ b/stem/util/enum.py @@ -124,9 +124,7 @@ class Enum(object): if not value in self._values: raise ValueError("No such enumeration exists: %s (options: %s)" % (value, ", ".join(self._values)))
- # TODO: python 2.5 lacks an index method on tuples, when we drop support - # we can drop this hack - next_index = (list(self._values).index(value) + 1) % len(self._values) + next_index = (self._values.index(value) + 1) % len(self._values) return self._values[next_index]
def previous(self, value): @@ -143,9 +141,7 @@ class Enum(object): if not value in self._values: raise ValueError("No such enumeration exists: %s (options: %s)" % (value, ", ".join(self._values)))
- # TODO: python 2.5 lacks an index method on tuples, when we drop support - # we can drop this hack - prev_index = (list(self._values).index(value) - 1) % len(self._values) + prev_index = (self._values.index(value) - 1) % len(self._values) return self._values[prev_index]
def __getitem__(self, item): diff --git a/stem/util/log.py b/stem/util/log.py index 5dc54be..498c489 100644 --- a/stem/util/log.py +++ b/stem/util/log.py @@ -195,7 +195,7 @@ class LogBuffer(logging.Handler): """
def __init__(self, runlevel): - # TODO: At least in python 2.5 logging.Handler has a bug in that it doesn't + # TODO: At least in python 2.6 logging.Handler has a bug in that it doesn't # extend object, causing our super() call to fail. When we drop python 2.5 # support we should switch back to using super() instead. #super(LogBuffer, self).__init__(level = logging_level(runlevel)) diff --git a/test/integ/connection/authentication.py b/test/integ/connection/authentication.py index 36b8af6..438fca7 100644 --- a/test/integ/connection/authentication.py +++ b/test/integ/connection/authentication.py @@ -3,8 +3,6 @@ Integration tests for authenticating to the control socket via stem.connection.authenticate* functions. """
-from __future__ import with_statement - import os import unittest
diff --git a/test/integ/control/base_controller.py b/test/integ/control/base_controller.py index 9b275e4..b91dd24 100644 --- a/test/integ/control/base_controller.py +++ b/test/integ/control/base_controller.py @@ -2,8 +2,6 @@ Integration tests for the stem.control.BaseController class. """
-from __future__ import with_statement - import re import threading import time diff --git a/test/integ/control/controller.py b/test/integ/control/controller.py index 804565a..3255fb3 100644 --- a/test/integ/control/controller.py +++ b/test/integ/control/controller.py @@ -2,8 +2,6 @@ Integration tests for the stem.control.Controller class. """
-from __future__ import with_statement - import shutil import socket import tempfile diff --git a/test/integ/descriptor/extrainfo_descriptor.py b/test/integ/descriptor/extrainfo_descriptor.py index ab47a2b..35faec9 100644 --- a/test/integ/descriptor/extrainfo_descriptor.py +++ b/test/integ/descriptor/extrainfo_descriptor.py @@ -2,8 +2,6 @@ Integration tests for stem.descriptor.extrainfo_descriptor. """
-from __future__ import with_statement - import datetime import os import unittest diff --git a/test/integ/descriptor/microdescriptor.py b/test/integ/descriptor/microdescriptor.py index da9cedd..65e47e3 100644 --- a/test/integ/descriptor/microdescriptor.py +++ b/test/integ/descriptor/microdescriptor.py @@ -2,8 +2,6 @@ Integration tests for stem.descriptor.microdescriptor. """
-from __future__ import with_statement - import os import unittest
diff --git a/test/integ/descriptor/networkstatus.py b/test/integ/descriptor/networkstatus.py index 31378fa..92a1973 100644 --- a/test/integ/descriptor/networkstatus.py +++ b/test/integ/descriptor/networkstatus.py @@ -2,8 +2,6 @@ Integration tests for stem.descriptor.networkstatus. """
-from __future__ import with_statement - import datetime import os import unittest diff --git a/test/integ/descriptor/reader.py b/test/integ/descriptor/reader.py index 39170a0..f0fa7d2 100644 --- a/test/integ/descriptor/reader.py +++ b/test/integ/descriptor/reader.py @@ -2,8 +2,6 @@ Integration tests for stem.descriptor.reader. """
-from __future__ import with_statement - import getpass import os import signal @@ -56,7 +54,9 @@ def _get_raw_tar_descriptors(): 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 2.5 support + # TODO: revert to using the 'with' keyword for this when dropping python + # 2.6 support + tar_file = None
try: diff --git a/test/integ/descriptor/server_descriptor.py b/test/integ/descriptor/server_descriptor.py index 696634a..43c9d4d 100644 --- a/test/integ/descriptor/server_descriptor.py +++ b/test/integ/descriptor/server_descriptor.py @@ -2,8 +2,6 @@ Integration tests for stem.descriptor.server_descriptor. """
-from __future__ import with_statement - import datetime import os import unittest diff --git a/test/integ/response/protocolinfo.py b/test/integ/response/protocolinfo.py index fa9e265..b7ef46a 100644 --- a/test/integ/response/protocolinfo.py +++ b/test/integ/response/protocolinfo.py @@ -3,8 +3,6 @@ Integration tests for the stem.response.protocolinfo.ProtocolInfoResponse class and related functions. """
-from __future__ import with_statement - import unittest
import stem.connection diff --git a/test/integ/socket/control_message.py b/test/integ/socket/control_message.py index 557e70d..607d2a4 100644 --- a/test/integ/socket/control_message.py +++ b/test/integ/socket/control_message.py @@ -2,8 +2,6 @@ Integration tests for the stem.response.ControlMessage class. """
-from __future__ import with_statement - import re import unittest
diff --git a/test/integ/socket/control_socket.py b/test/integ/socket/control_socket.py index 2f951b2..a716eea 100644 --- a/test/integ/socket/control_socket.py +++ b/test/integ/socket/control_socket.py @@ -8,8 +8,6 @@ those focus on parsing and correctness of the content these are more concerned with the behavior of the socket itself. """
-from __future__ import with_statement - import unittest
import stem.connection diff --git a/test/integ/util/proc.py b/test/integ/util/proc.py index e6d1534..4fabfe9 100644 --- a/test/integ/util/proc.py +++ b/test/integ/util/proc.py @@ -3,8 +3,6 @@ Integration tests for stem.util.proc functions against the tor process that we're running. """
-from __future__ import with_statement - import os import unittest
diff --git a/test/mocking.py b/test/mocking.py index b491010..340a625 100644 --- a/test/mocking.py +++ b/test/mocking.py @@ -58,7 +58,6 @@ import base64 import hashlib import inspect import itertools -import StringIO
import stem.descriptor.extrainfo_descriptor import stem.descriptor.microdescriptor @@ -1059,60 +1058,3 @@ def sign_descriptor_content(desc_content): desc_content = desc_content[:rst_start] + router_signature_token + router_signature_start + signature_base64 + router_signature_end
return desc_content - - -class BytesBuffer(object): - """ - Similiar to a StringIO but provides bytes content (in python 3.x StringIO can - only be used for unicode). - """ - - def __init__(self, content): - self.wrapped_file = StringIO.StringIO(stem.util.str_tools._to_unicode(content)) - - def close(self): - return self.wrapped_file.close() - - def getvalue(self): - return self.wrapped_file.getvalue() - - def isatty(self): - return self.wrapped_file.isatty() - - def next(self): - return self.wrapped_file.next() - - def read(self, n = -1): - return stem.util.str_tools._to_bytes(self.wrapped_file.read(n)) - - def readline(self): - return stem.util.str_tools._to_bytes(self.wrapped_file.readline()) - - def readlines(self, sizehint = None): - # being careful to do in-place conversion so we don't accidently double our - # memory usage - - if sizehint is not None: - results = self.wrapped_file.readlines(sizehint) - else: - results = self.wrapped_file.readlines() - - for i in xrange(len(results)): - results[i] = stem.util.str_tools._to_bytes(results[i]) - - return results - - def seek(self, pos, mode = None): - if mode is not None: - return self.wrapped_file.seek(pos, mode) - else: - return self.wrapped_file.seek(pos) - - def tell(self): - return self.wrapped_file.tell() - - def __enter__(self): - return self - - def __exit__(self, exit_type, value, traceback): - pass diff --git a/test/runner.py b/test/runner.py index f94e4da..7fa9c41 100644 --- a/test/runner.py +++ b/test/runner.py @@ -39,8 +39,6 @@ about the tor test instance they're running against. +- get_tor_command - provides the command used to start tor """
-from __future__ import with_statement - import logging import os import shutil diff --git a/test/static_checks.py b/test/static_checks.py index 43b6866..b8cc664 100644 --- a/test/static_checks.py +++ b/test/static_checks.py @@ -8,16 +8,8 @@ which are... * two space indentations * tabs are the root of all evil and should be shot on sight * standard newlines (\n), not windows (\r\n) nor classic mac (\r) - -This also checks for 2.5 compatibility issues (yea, they're not whitespace but -it's so much easier to do here...): - -* checks that anything using the 'with' keyword has... - from __future__ import with_statement """
-from __future__ import with_statement - import re import os
@@ -166,7 +158,6 @@ def get_issues(base_path = DEFAULT_TARGET): file_contents = f.read()
lines, file_issues, prev_indent = file_contents.split("\n"), [], 0 - has_with_import, given_with_warning = False, False is_block_comment = False
for index, line in enumerate(lines): @@ -175,13 +166,6 @@ def get_issues(base_path = DEFAULT_TARGET): if '"""' in content: is_block_comment = not is_block_comment
- if content == "from __future__ import with_statement": - has_with_import = True - elif content.startswith("with ") and content.endswith(":") \ - and not has_with_import and not given_with_warning and not is_block_comment: - file_issues.append((index + 1, "missing 'with' import (from __future__ import with_statement)")) - given_with_warning = True - if "\t" in whitespace: file_issues.append((index + 1, "indentation has a tab")) elif "\r" in content: diff --git a/test/unit/descriptor/networkstatus/document_v3.py b/test/unit/descriptor/networkstatus/document_v3.py index c140d23..f4b13af 100644 --- a/test/unit/descriptor/networkstatus/document_v3.py +++ b/test/unit/descriptor/networkstatus/document_v3.py @@ -2,9 +2,8 @@ Unit tests for the NetworkStatusDocumentV3 of stem.descriptor.networkstatus. """
-from __future__ import with_statement - import datetime +import io import unittest
import stem.descriptor @@ -28,7 +27,6 @@ from test.mocking import get_router_status_entry_v3, \ get_router_status_entry_micro_v3, \ get_directory_authority, \ get_network_status_document_v3, \ - BytesBuffer, \ CRYPTO_BLOB, \ DOC_SIG, \ NETWORK_STATUS_DOCUMENT_FOOTER @@ -118,7 +116,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
# first example: parsing via the NetworkStatusDocumentV3 constructor
- consensus_file = BytesBuffer(content) + consensus_file = io.BytesIO(content) consensus = NetworkStatusDocumentV3(consensus_file.read()) consensus_file.close()
@@ -127,7 +125,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
# second example: using stem.descriptor.parse_file
- with BytesBuffer(content) as consensus_file: + with io.BytesIO(content) as consensus_file: for router in stem.descriptor.parse_file(consensus_file, 'network-status-consensus-3 1.0'): self.assertEqual('caerSidi', router.nickname)
@@ -144,12 +142,12 @@ class TestNetworkStatusDocument(unittest.TestCase): entry2 = get_router_status_entry_v3({'s': "Valid"}) content = get_network_status_document_v3(routers = (entry1, entry2), content = True)
- descriptors = list(stem.descriptor.parse_file(BytesBuffer(content), 'network-status-consensus-3 1.0', document_handler = stem.descriptor.DocumentHandler.DOCUMENT)) + descriptors = list(stem.descriptor.parse_file(io.BytesIO(content), 'network-status-consensus-3 1.0', document_handler = stem.descriptor.DocumentHandler.DOCUMENT)) self.assertEqual(1, len(descriptors)) self.assertTrue(isinstance(descriptors[0], NetworkStatusDocumentV3)) self.assertEqual(2, len(descriptors[0].routers))
- descriptors = list(stem.descriptor.parse_file(BytesBuffer(content), 'network-status-consensus-3 1.0', document_handler = stem.descriptor.DocumentHandler.BARE_DOCUMENT)) + descriptors = list(stem.descriptor.parse_file(io.BytesIO(content), 'network-status-consensus-3 1.0', document_handler = stem.descriptor.DocumentHandler.BARE_DOCUMENT)) self.assertEqual(1, len(descriptors)) self.assertTrue(isinstance(descriptors[0], NetworkStatusDocumentV3)) self.assertEqual(0, len(descriptors[0].routers)) @@ -168,7 +166,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
expected_document = get_network_status_document_v3()
- descriptor_file = BytesBuffer(content) + descriptor_file = io.BytesIO(content) entries = list(_parse_file(descriptor_file))
self.assertEquals(entry1, entries[0]) diff --git a/test/unit/descriptor/server_descriptor.py b/test/unit/descriptor/server_descriptor.py index e8fe6c0..02ec64c 100644 --- a/test/unit/descriptor/server_descriptor.py +++ b/test/unit/descriptor/server_descriptor.py @@ -3,6 +3,7 @@ Unit tests for stem.descriptor.server_descriptor. """
import datetime +import io import unittest
import stem.descriptor.server_descriptor @@ -17,7 +18,6 @@ from test.mocking import no_op, \ revert_mocking, \ get_relay_server_descriptor, \ get_bridge_server_descriptor, \ - BytesBuffer, \ CRYPTO_BLOB
@@ -216,7 +216,7 @@ class TestServerDescriptor(unittest.TestCase): desc_text += b"\ntrailing text that should be ignored, ho hum"
# running _parse_file should provide an iterator with a single descriptor - desc_iter = stem.descriptor.server_descriptor._parse_file(BytesBuffer(stem.util.str_tools._to_unicode(desc_text))) + desc_iter = stem.descriptor.server_descriptor._parse_file(io.BytesIO(desc_text)) desc_entries = list(desc_iter) self.assertEquals(1, len(desc_entries)) desc = desc_entries[0] diff --git a/test/unit/tutorial.py b/test/unit/tutorial.py index 4ec6290..405bca7 100644 --- a/test/unit/tutorial.py +++ b/test/unit/tutorial.py @@ -2,8 +2,7 @@ Tests for the examples given in stem's tutorial. """
-from __future__ import with_statement - +import io import StringIO import sys import unittest @@ -98,7 +97,7 @@ class TestTutorial(unittest.TestCase): for desc in parse_file(open("/home/atagar/.tor/cached-consensus")): print "found relay %s (%s)" % (desc.nickname, desc.fingerprint)
- test_file = mocking.BytesBuffer(mocking.get_network_status_document_v3( + test_file = io.BytesIO(mocking.get_network_status_document_v3( routers = [mocking.get_router_status_entry_v3()], content = True, ))
tor-commits@lists.torproject.org