[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Dropping python 2.5 compatibility hacks
commit b3c00c4a6d0565939745e6eba2064b17aaff491a
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
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 mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits