[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Drop is_python_3 checks
commit 1f2cc309a0785d2d5885cf16fb739707ead195c2
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Fri Jan 3 15:10:07 2020 -0800
Drop is_python_3 checks
These checks now always evaluate to 'true'. Dropping these checks and their
alternate code paths.
---
stem/client/cell.py | 4 ++--
stem/client/datatype.py | 4 ++--
stem/control.py | 10 ++++-----
stem/descriptor/__init__.py | 9 +++-----
stem/descriptor/reader.py | 2 +-
stem/descriptor/router_status_entry.py | 4 +---
stem/exit_policy.py | 8 +++----
stem/interpreter/__init__.py | 4 ++--
stem/manual.py | 3 +--
stem/prereq.py | 29 ------------------------
stem/response/__init__.py | 13 +++++------
stem/response/events.py | 20 +++++++----------
stem/response/getinfo.py | 3 +--
stem/response/protocolinfo.py | 4 +---
stem/socket.py | 5 ++---
stem/util/__init__.py | 38 ++-----------------------------
stem/util/conf.py | 4 +---
stem/util/connection.py | 4 ++--
stem/util/enum.py | 2 +-
stem/util/log.py | 3 +--
stem/util/str_tools.py | 39 +++++++++++---------------------
stem/util/system.py | 2 +-
test/integ/process.py | 10 +++------
test/task.py | 2 +-
test/unit/descriptor/collector.py | 23 +++++++------------
test/unit/descriptor/remote.py | 41 +++++++++++++---------------------
test/unit/directory/authority.py | 6 ++---
test/unit/directory/fallback.py | 12 +++++-----
test/unit/manual.py | 7 +++---
test/unit/tutorial_examples.py | 16 +++++--------
test/unit/util/connection.py | 7 +++---
31 files changed, 105 insertions(+), 233 deletions(-)
diff --git a/stem/client/cell.py b/stem/client/cell.py
index 57a71749..83888556 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -354,10 +354,10 @@ class RelayCell(CircuitCell):
digest_packed = digest.digest()[:RELAY_DIGEST_SIZE.size]
digest = RELAY_DIGEST_SIZE.unpack(digest_packed)
- elif stem.util._is_str(digest):
+ elif isinstance(digest, (bytes, str)):
digest_packed = digest[:RELAY_DIGEST_SIZE.size]
digest = RELAY_DIGEST_SIZE.unpack(digest_packed)
- elif stem.util._is_int(digest):
+ elif isinstance(digest, int):
pass
else:
raise ValueError('RELAY cell digest must be a hash, string, or int but was a %s' % type(digest).__name__)
diff --git a/stem/client/datatype.py b/stem/client/datatype.py
index 367074b2..0b39d1b5 100644
--- a/stem/client/datatype.py
+++ b/stem/client/datatype.py
@@ -183,7 +183,7 @@ class _IntegerEnum(stem.util.enum.Enum):
Provides the (enum, int_value) tuple for a given value.
"""
- if stem.util._is_int(val):
+ if isinstance(val, int):
return self._int_to_enum.get(val, self.UNKNOWN), val
elif val in self:
return val, self._enum_to_int.get(val, val)
@@ -402,7 +402,7 @@ class Size(Field):
try:
packed = struct.pack(self.format, content)
except struct.error:
- if not stem.util._is_int(content):
+ if not isinstance(content, int):
raise ValueError('Size.pack encodes an integer, but was a %s' % type(content).__name__)
elif content < 0:
raise ValueError('Packed values must be positive (attempted to pack %i as a %s)' % (content, self.name))
diff --git a/stem/control.py b/stem/control.py
index 25a65f43..c046755c 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -1160,7 +1160,7 @@ class Controller(BaseController):
start_time = time.time()
reply = {}
- if stem.util._is_str(params):
+ if isinstance(params, (bytes, str)):
is_multiple = False
params = set([params])
else:
@@ -1205,7 +1205,7 @@ class Controller(BaseController):
# usually we want unicode values under python 3.x
- if stem.prereq.is_python_3() and not get_bytes:
+ if not get_bytes:
response.entries = dict((k, stem.util.str_tools._to_unicode(v)) for (k, v) in response.entries.items())
reply.update(response.entries)
@@ -2308,7 +2308,7 @@ class Controller(BaseController):
start_time = time.time()
reply = {}
- if stem.util._is_str(params):
+ if isinstance(params, (bytes, str)):
params = [params]
# remove strings which contain only whitespace
@@ -3476,7 +3476,7 @@ class Controller(BaseController):
* :class:`stem.InvalidArguments` if features passed were invalid
"""
- if stem.util._is_str(features):
+ if isinstance(features, (bytes, str)):
features = [features]
response = self.msg('USEFEATURE %s' % ' '.join(features))
@@ -3631,7 +3631,7 @@ class Controller(BaseController):
args = [circuit_id]
- if stem.util._is_str(path):
+ if isinstance(path, (bytes, str)):
path = [path]
if path:
diff --git a/stem/descriptor/__init__.py b/stem/descriptor/__init__.py
index bab339ac..ec299289 100644
--- a/stem/descriptor/__init__.py
+++ b/stem/descriptor/__init__.py
@@ -357,7 +357,7 @@ def parse_file(descriptor_file, descriptor_type = None, validate = False, docume
handler = None
- if stem.util._is_str(descriptor_file):
+ if isinstance(descriptor_file, (bytes, str)):
if stem.util.system.is_tarfile(descriptor_file):
handler = _parse_file_for_tar_path
else:
@@ -1157,10 +1157,7 @@ class Descriptor(object):
return super(Descriptor, self).__getattribute__(name)
def __str__(self):
- if stem.prereq.is_python_3():
- return stem.util.str_tools._to_unicode(self._raw_contents)
- else:
- return self._raw_contents
+ return stem.util.str_tools._to_unicode(self._raw_contents)
def _compare(self, other, method):
if type(self) != type(other):
@@ -1234,7 +1231,7 @@ def _read_until_keywords(keywords, descriptor_file, inclusive = False, ignore_fi
content = None if skip else []
ending_keyword = None
- if stem.util._is_str(keywords):
+ if isinstance(keywords, (bytes, str)):
keywords = (keywords,)
if ignore_first:
diff --git a/stem/descriptor/reader.py b/stem/descriptor/reader.py
index b4cc4279..ebd41c73 100644
--- a/stem/descriptor/reader.py
+++ b/stem/descriptor/reader.py
@@ -270,7 +270,7 @@ class DescriptorReader(object):
"""
def __init__(self, target, validate = False, follow_links = False, buffer_size = 100, persistence_path = None, document_handler = stem.descriptor.DocumentHandler.ENTRIES, **kwargs):
- self._targets = [target] if stem.util._is_str(target) else target
+ self._targets = [target] if isinstance(target, (bytes, str)) else target
# expand any relative paths we got
diff --git a/stem/descriptor/router_status_entry.py b/stem/descriptor/router_status_entry.py
index cf1c52f5..d248774a 100644
--- a/stem/descriptor/router_status_entry.py
+++ b/stem/descriptor/router_status_entry.py
@@ -374,9 +374,7 @@ def _base64_to_hex(identity, check_if_fingerprint = True):
raise ValueError("Unable to decode identity string '%s'" % identity)
fingerprint = binascii.hexlify(identity_decoded).upper()
-
- if stem.prereq.is_python_3():
- fingerprint = stem.util.str_tools._to_unicode(fingerprint)
+ fingerprint = stem.util.str_tools._to_unicode(fingerprint)
if check_if_fingerprint:
if not stem.util.tor_tools.is_valid_fingerprint(fingerprint):
diff --git a/stem/exit_policy.py b/stem/exit_policy.py
index f9d7e6e0..0d1e7e42 100644
--- a/stem/exit_policy.py
+++ b/stem/exit_policy.py
@@ -124,7 +124,7 @@ def get_config_policy(rules, ip_address = None):
elif ip_address and stem.util.connection.is_valid_ipv6_address(ip_address, allow_brackets = True) and not (ip_address[0] == '[' and ip_address[-1] == ']'):
ip_address = '[%s]' % ip_address # ExitPolicy validation expects IPv6 addresses to be bracketed
- if stem.util._is_str(rules):
+ if isinstance(rules, (bytes, str)):
rules = rules.split(',')
result = []
@@ -238,7 +238,7 @@ class ExitPolicy(object):
# sanity check the types
for rule in rules:
- if not stem.util._is_str(rule) and not isinstance(rule, ExitPolicyRule):
+ if not isinstance(rule, (bytes, str)) and not isinstance(rule, ExitPolicyRule):
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
@@ -249,7 +249,7 @@ class ExitPolicy(object):
is_all_str = True
for rule in rules:
- if not stem.util._is_str(rule):
+ if not isinstance(rule, (bytes, str)):
is_all_str = False
if rules and is_all_str:
@@ -466,7 +466,7 @@ class ExitPolicy(object):
if isinstance(rule, bytes):
rule = stem.util.str_tools._to_unicode(rule)
- if stem.util._is_str(rule):
+ if isinstance(rule, (bytes, str)):
if not rule.strip():
continue
diff --git a/stem/interpreter/__init__.py b/stem/interpreter/__init__.py
index 30af3f62..fc0c2cf3 100644
--- a/stem/interpreter/__init__.py
+++ b/stem/interpreter/__init__.py
@@ -171,14 +171,14 @@ def main():
while True:
try:
prompt = '... ' if interpreter.is_multiline_context else PROMPT
- user_input = input(prompt) if stem.prereq.is_python_3() else raw_input(prompt)
+ user_input = input(prompt)
interpreter.run_command(user_input, print_response = True)
except stem.SocketClosed:
if showed_close_confirmation:
print(format('Unable to run tor commands. The control connection has been closed.', *ERROR_OUTPUT))
else:
prompt = format("Tor's control port has closed. Do you want to continue this interpreter? (y/n) ", *HEADER_BOLD_OUTPUT)
- user_input = input(prompt) if stem.prereq.is_python_3() else raw_input(prompt)
+ user_input = input(prompt)
print('') # blank line
if user_input.lower() in ('y', 'yes'):
diff --git a/stem/manual.py b/stem/manual.py
index 2176067c..d9ad5aa7 100644
--- a/stem/manual.py
+++ b/stem/manual.py
@@ -678,8 +678,7 @@ def _get_categories(content):
# \u2014 - extra long dash
# \xb7 - centered dot
- char_for = chr if stem.prereq.is_python_3() else unichr
- line = line.replace(char_for(0x2019), "'").replace(char_for(0x2014), '-').replace(char_for(0xb7), '*')
+ line = line.replace(chr(0x2019), "'").replace(chr(0x2014), '-').replace(chr(0xb7), '*')
if line and not line.startswith(' '):
if category:
diff --git a/stem/prereq.py b/stem/prereq.py
index d748c2ab..bd006bd0 100644
--- a/stem/prereq.py
+++ b/stem/prereq.py
@@ -12,7 +12,6 @@ stem will still read descriptors - just without signature checks.
::
check_requirements - checks for minimum requirements for running stem
- is_python_3 - checks if python 3.0 or later is available
is_sqlite_available - checks if the sqlite3 module is available
is_crypto_available - checks if the cryptography module is available
is_zstd_available - checks if the zstd module is available
@@ -50,34 +49,6 @@ def check_requirements():
raise ImportError('stem requires python version 3.6 or greater')
-def is_python_27():
- """
- Checks if we're running python 2.7 or above (including the 3.x series).
-
- .. deprecated:: 1.5.0
- Stem 2.x will remove this method along with Python 2.x support.
-
- :returns: **True** if we meet this requirement and **False** otherwise
- """
-
- major_version, minor_version = sys.version_info[0:2]
-
- return major_version > 2 or (major_version == 2 and minor_version >= 7)
-
-
-def is_python_3():
- """
- Checks if we're in the 3.0 - 3.x range.
-
- .. deprecated:: 1.8.0
- Stem 2.x will remove this method along with Python 2.x support.
-
- :returns: **True** if we meet this requirement and **False** otherwise
- """
-
- return sys.version_info[0] == 3
-
-
def is_pypy():
"""
Checks if we're running PyPy.
diff --git a/stem/response/__init__.py b/stem/response/__init__.py
index 1a5b2b45..2fbb9c48 100644
--- a/stem/response/__init__.py
+++ b/stem/response/__init__.py
@@ -229,7 +229,7 @@ class ControlMessage(object):
:returns: **list** of (str, str, str) tuples for the components of this message
"""
- if stem.prereq.is_python_3() and not get_bytes:
+ if not get_bytes:
return [(code, div, stem.util.str_tools._to_unicode(content)) for (code, div, content) in self._parsed_content]
else:
return list(self._parsed_content)
@@ -246,7 +246,7 @@ class ControlMessage(object):
:returns: **str** of the socket data used to generate this message
"""
- if stem.prereq.is_python_3() and not get_bytes:
+ if not get_bytes:
return stem.util.str_tools._to_unicode(self._raw_content)
else:
return self._raw_content
@@ -286,8 +286,7 @@ class ControlMessage(object):
"""
for _, _, content in self._parsed_content:
- if stem.prereq.is_python_3():
- content = stem.util.str_tools._to_unicode(content)
+ content = stem.util.str_tools._to_unicode(content)
yield ControlLine(content)
@@ -304,9 +303,7 @@ class ControlMessage(object):
"""
content = self._parsed_content[index][2]
-
- if stem.prereq.is_python_3():
- content = stem.util.str_tools._to_unicode(content)
+ content = stem.util.str_tools._to_unicode(content)
return ControlLine(content)
@@ -534,7 +531,7 @@ def _parse_entry(line, quoted, escaped, get_bytes):
next_entry = codecs.escape_decode(next_entry)[0]
- if stem.prereq.is_python_3() and not get_bytes:
+ if not get_bytes:
next_entry = stem.util.str_tools._to_unicode(next_entry) # normalize back to str
if get_bytes:
diff --git a/stem/response/events.py b/stem/response/events.py
index e634a5d6..9b6d8393 100644
--- a/stem/response/events.py
+++ b/stem/response/events.py
@@ -23,10 +23,6 @@ QUOTED_KW_ARG = re.compile('^(.*) ([A-Za-z0-9_]+)="(.*)"$')
CELL_TYPE = re.compile('^[a-z0-9_]+$')
PARSE_NEWCONSENSUS_EVENTS = True
-# TODO: We can remove the following when we drop python2.6 support.
-
-INT_TYPE = int if stem.prereq.is_python_3() else long
-
class Event(stem.response.ControlMessage):
"""
@@ -163,7 +159,7 @@ class Event(stem.response.ControlMessage):
attr_values = getattr(self, attr)
if attr_values:
- if stem.util._is_str(attr_values):
+ if isinstance(attr_values, (bytes, str)):
attr_values = [attr_values]
for value in attr_values:
@@ -284,8 +280,8 @@ class BandwidthEvent(Event):
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)
- self.read = INT_TYPE(self.read)
- self.written = INT_TYPE(self.written)
+ self.read = int(self.read)
+ self.written = int(self.written)
class BuildTimeoutSetEvent(Event):
@@ -1095,8 +1091,8 @@ class StreamBwEvent(Event):
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)
- self.read = INT_TYPE(self.read)
- self.written = INT_TYPE(self.written)
+ self.read = int(self.read)
+ self.written = int(self.written)
self.time = self._iso_timestamp(self.time)
@@ -1174,8 +1170,8 @@ class ConnectionBandwidthEvent(Event):
elif not tor_tools.is_valid_connection_id(self.id):
raise stem.ProtocolError("Connection IDs must be one to sixteen alphanumeric characters, got '%s': %s" % (self.id, self))
- self.read = INT_TYPE(self.read)
- self.written = INT_TYPE(self.written)
+ self.read = int(self.read)
+ self.written = int(self.written)
self._log_if_unrecognized('conn_type', stem.ConnectionType)
@@ -1247,7 +1243,7 @@ class CircuitBandwidthEvent(Event):
value = getattr(self, attr)
if value:
- setattr(self, attr, INT_TYPE(value))
+ setattr(self, attr, int(value))
class CellStatsEvent(Event):
diff --git a/stem/response/getinfo.py b/stem/response/getinfo.py
index 0b9766ba..27442ffd 100644
--- a/stem/response/getinfo.py
+++ b/stem/response/getinfo.py
@@ -53,8 +53,7 @@ class GetInfoResponse(stem.response.ControlMessage):
except ValueError:
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)
+ key = stem.util.str_tools._to_unicode(key)
# if the value is a multiline value then it *must* be of the form
# '<key>=\n<value>'
diff --git a/stem/response/protocolinfo.py b/stem/response/protocolinfo.py
index 1763e59f..46f6ab4f 100644
--- a/stem/response/protocolinfo.py
+++ b/stem/response/protocolinfo.py
@@ -108,9 +108,7 @@ class ProtocolInfoResponse(stem.response.ControlMessage):
if line.is_next_mapping('COOKIEFILE', True, True):
self.cookie_path = line.pop_mapping(True, True, get_bytes = True)[1].decode(sys.getfilesystemencoding())
-
- if stem.prereq.is_python_3():
- self.cookie_path = stem.util.str_tools._to_unicode(self.cookie_path) # normalize back to str
+ self.cookie_path = stem.util.str_tools._to_unicode(self.cookie_path) # normalize back to str
elif line_type == 'VERSION':
# Line format:
# VersionLine = "250-VERSION" SP "Tor=" TorVersion OptArguments CRLF
diff --git a/stem/socket.py b/stem/socket.py
index 26e8f22e..275a55d4 100644
--- a/stem/socket.py
+++ b/stem/socket.py
@@ -710,9 +710,8 @@ def recv_message(control_file, arrived_at = None):
status_code, divider, content = line[:3], line[3:4], line[4:-2] # strip CRLF off content
- if stem.prereq.is_python_3():
- status_code = stem.util.str_tools._to_unicode(status_code)
- divider = stem.util.str_tools._to_unicode(divider)
+ status_code = stem.util.str_tools._to_unicode(status_code)
+ divider = stem.util.str_tools._to_unicode(divider)
# Most controller responses are single lines, in which case we don't need
# so much overhead.
diff --git a/stem/util/__init__.py b/stem/util/__init__.py
index 226f5fbf..c6b9ce34 100644
--- a/stem/util/__init__.py
+++ b/stem/util/__init__.py
@@ -56,7 +56,7 @@ def _hash_value(val):
#
# This hack will go away when we drop Python 2.x support.
- if _is_str(val):
+ if isinstance(val, (bytes, str)):
my_hash = hash('str')
else:
# Hashing common builtins (ints, bools, etc) provide consistant values but many others vary their value on interpreter invokation.
@@ -75,40 +75,6 @@ def _hash_value(val):
return my_hash
-def _is_str(val):
- """
- Check if a value is a string. This will be removed when we no longer provide
- backward compatibility for the Python 2.x series.
-
- :param object val: value to be checked
-
- :returns: **True** if the value is some form of string (unicode or bytes),
- and **False** otherwise
- """
-
- if stem.prereq.is_python_3():
- return isinstance(val, (bytes, str))
- else:
- return isinstance(val, (bytes, unicode))
-
-
-def _is_int(val):
- """
- Check if a value is an integer. This will be removed when we no longer
- provide backward compatibility for the Python 2.x series.
-
- :param object val: value to be checked
-
- :returns: **True** if the value is some form of integer (int or long),
- and **False** otherwise
- """
-
- if stem.prereq.is_python_3():
- return isinstance(val, int)
- else:
- return isinstance(val, (int, long))
-
-
def datetime_to_unix(timestamp):
"""
Converts a utc datetime object to a unix timestamp.
@@ -128,7 +94,7 @@ def _pubkey_bytes(key):
Normalizes X25509 and ED25519 keys into their public key bytes.
"""
- if _is_str(key):
+ if isinstance(key, (bytes, str)):
return key
if not stem.prereq.is_crypto_available():
diff --git a/stem/util/conf.py b/stem/util/conf.py
index 7dffe95a..1dbcc243 100644
--- a/stem/util/conf.py
+++ b/stem/util/conf.py
@@ -635,14 +635,12 @@ class Config(object):
"""
with self._contents_lock:
- unicode_type = str if stem.prereq.is_python_3() else unicode
-
if value is None:
if overwrite and key in self._contents:
del self._contents[key]
else:
pass # no value so this is a no-op
- elif isinstance(value, (bytes, unicode_type)):
+ elif isinstance(value, (bytes, str)):
if not overwrite and key in self._contents:
self._contents[key].append(value)
else:
diff --git a/stem/util/connection.py b/stem/util/connection.py
index bd1fb5a2..7c8e864b 100644
--- a/stem/util/connection.py
+++ b/stem/util/connection.py
@@ -458,7 +458,7 @@ def is_valid_ipv4_address(address):
if isinstance(address, bytes):
address = str_tools._to_unicode(address)
- elif not stem.util._is_str(address):
+ elif not isinstance(address, (bytes, str)):
return False
# checks if theres four period separated values
@@ -488,7 +488,7 @@ def is_valid_ipv6_address(address, allow_brackets = False):
if isinstance(address, bytes):
address = str_tools._to_unicode(address)
- elif not stem.util._is_str(address):
+ elif not isinstance(address, (bytes, str)):
return False
if allow_brackets:
diff --git a/stem/util/enum.py b/stem/util/enum.py
index 76a52a55..abaf2490 100644
--- a/stem/util/enum.py
+++ b/stem/util/enum.py
@@ -76,7 +76,7 @@ class Enum(object):
keys, values = [], []
for entry in args:
- if stem.util._is_str(entry):
+ if isinstance(entry, (bytes, str)):
key, val = entry, _to_camel_case(entry)
elif isinstance(entry, tuple) and len(entry) == 2:
key, val = entry
diff --git a/stem/util/log.py b/stem/util/log.py
index e8d61c1d..ccf6b4ae 100644
--- a/stem/util/log.py
+++ b/stem/util/log.py
@@ -153,8 +153,7 @@ def escape(message):
:returns: str that is escaped
"""
- if stem.prereq.is_python_3():
- message = stem.util.str_tools._to_unicode(message)
+ message = stem.util.str_tools._to_unicode(message)
for pattern, replacement in (('\n', '\\n'), ('\r', '\\r'), ('\t', '\\t')):
message = message.replace(pattern, replacement)
diff --git a/stem/util/str_tools.py b/stem/util/str_tools.py
index 58effbee..6b852f3d 100644
--- a/stem/util/str_tools.py
+++ b/stem/util/str_tools.py
@@ -61,30 +61,17 @@ TIME_UNITS = (
_timestamp_re = re.compile(r'(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})')
-if stem.prereq.is_python_3():
- def _to_bytes_impl(msg):
- if isinstance(msg, str):
- 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')
- 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]
- else:
- return msg
+def _to_bytes_impl(msg):
+ if isinstance(msg, str):
+ 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')
- else:
- return msg
+def _to_unicode_impl(msg):
+ if msg is not None and not isinstance(msg, str):
+ return msg.decode('utf-8', 'replace')
+ else:
+ return msg
def _to_bytes(msg):
@@ -137,7 +124,7 @@ def _to_int(msg):
:returns: **int** representation of the string
"""
- if stem.prereq.is_python_3() and isinstance(msg, bytes):
+ if isinstance(msg, bytes):
# iterating over bytes in python3 provides ints rather than characters
return sum([pow(256, (len(msg) - i - 1)) * c for (i, c) in enumerate(msg)])
else:
@@ -508,7 +495,7 @@ def _parse_timestamp(entry):
:raises: **ValueError** if the timestamp is malformed
"""
- if not stem.util._is_str(entry):
+ if not isinstance(entry, (bytes, str)):
raise ValueError('parse_timestamp() input must be a str, got a %s' % type(entry))
try:
@@ -534,7 +521,7 @@ def _parse_iso_timestamp(entry):
:raises: **ValueError** if the timestamp is malformed
"""
- if not stem.util._is_str(entry):
+ if not isinstance(entry, (bytes, str)):
raise ValueError('parse_iso_timestamp() input must be a str, got a %s' % type(entry))
# based after suggestions from...
diff --git a/stem/util/system.py b/stem/util/system.py
index 0d2262f5..e514c3a4 100644
--- a/stem/util/system.py
+++ b/stem/util/system.py
@@ -454,7 +454,7 @@ def is_running(command):
if command_listing:
command_listing = [c.strip() for c in command_listing]
- if stem.util._is_str(command):
+ if isinstance(command, (bytes, str)):
command = [command]
for cmd in command:
diff --git a/test/integ/process.py b/test/integ/process.py
index 26346ece..88230805 100644
--- a/test/integ/process.py
+++ b/test/integ/process.py
@@ -106,7 +106,7 @@ def run_tor(tor_cmd, *args, **kwargs):
elif not exit_status and expect_failure:
raise AssertionError("Didn't expect tor to be able to start when we run: %s\n%s" % (' '.join(args), stdout))
- return stem.util.str_tools._to_unicode(stdout) if stem.prereq.is_python_3() else stdout
+ return stem.util.str_tools._to_unicode(stdout)
class TestProcess(unittest.TestCase):
@@ -177,12 +177,8 @@ class TestProcess(unittest.TestCase):
# I'm not gonna even pretend to understand the following. Ported directly
# from tor's test_cmdline_args.py.
- if stem.prereq.is_python_3():
- output_hex = binascii.a2b_hex(stem.util.str_tools._to_bytes(output).strip()[3:])
- salt, how, hashed = output_hex[:8], output_hex[8], output_hex[9:]
- else:
- output_hex = binascii.a2b_hex(output.strip()[3:])
- salt, how, hashed = output_hex[:8], ord(output_hex[8]), output_hex[9:]
+ output_hex = binascii.a2b_hex(stem.util.str_tools._to_bytes(output).strip()[3:])
+ salt, how, hashed = output_hex[:8], output_hex[8], output_hex[9:]
count = (16 + (how & 15)) << ((how >> 4) + 6)
stuff = salt + b'my_password'
diff --git a/test/task.py b/test/task.py
index 1fbcf9a4..31c7d628 100644
--- a/test/task.py
+++ b/test/task.py
@@ -273,7 +273,7 @@ class Task(object):
self.is_successful = True
output_msg = 'running' if self._is_background_task else 'done'
- if self.result and self.print_result and stem.util._is_str(self.result):
+ if self.result and self.print_result and isinstance(self.result, (bytes, str)):
output_msg = self.result
elif self.print_runtime:
output_msg += ' (%0.1fs)' % (time.time() - start_time)
diff --git a/test/unit/descriptor/collector.py b/test/unit/descriptor/collector.py
index 3d6b2da0..acdcc0d4 100644
--- a/test/unit/descriptor/collector.py
+++ b/test/unit/descriptor/collector.py
@@ -19,9 +19,6 @@ try:
except ImportError:
from mock import Mock, patch
-URL_OPEN = 'urllib.request.urlopen' if stem.prereq.is_python_3() else 'urllib2.urlopen'
-
-
with open(get_resource('collector/index.json'), 'rb') as index_file:
EXAMPLE_INDEX_JSON = index_file.read()
@@ -60,7 +57,7 @@ class TestCollector(unittest.TestCase):
# tests for the CollecTor class
- @patch(URL_OPEN)
+ @patch('urllib.request.urlopen')
def test_index_plaintext(self, urlopen_mock):
urlopen_mock.return_value = io.BytesIO(EXAMPLE_INDEX_JSON)
@@ -68,7 +65,7 @@ class TestCollector(unittest.TestCase):
self.assertEqual(EXAMPLE_INDEX, collector.index(Compression.PLAINTEXT))
urlopen_mock.assert_called_with('https://collector.torproject.org/index/index.json', timeout = None)
- @patch(URL_OPEN)
+ @patch('urllib.request.urlopen')
def test_index_gzip(self, urlopen_mock):
if not Compression.GZIP.available:
self.skipTest('(gzip compression unavailable)')
@@ -80,7 +77,7 @@ class TestCollector(unittest.TestCase):
self.assertEqual(EXAMPLE_INDEX, collector.index(Compression.GZIP))
urlopen_mock.assert_called_with('https://collector.torproject.org/index/index.json.gz', timeout = None)
- @patch(URL_OPEN)
+ @patch('urllib.request.urlopen')
def test_index_bz2(self, urlopen_mock):
if not Compression.BZ2.available:
self.skipTest('(bz2 compression unavailable)')
@@ -92,7 +89,7 @@ class TestCollector(unittest.TestCase):
self.assertEqual(EXAMPLE_INDEX, collector.index(Compression.BZ2))
urlopen_mock.assert_called_with('https://collector.torproject.org/index/index.json.bz2', timeout = None)
- @patch(URL_OPEN)
+ @patch('urllib.request.urlopen')
def test_index_lzma(self, urlopen_mock):
if not Compression.LZMA.available:
self.skipTest('(lzma compression unavailable)')
@@ -104,7 +101,7 @@ class TestCollector(unittest.TestCase):
self.assertEqual(EXAMPLE_INDEX, collector.index(Compression.LZMA))
urlopen_mock.assert_called_with('https://collector.torproject.org/index/index.json.xz', timeout = None)
- @patch(URL_OPEN)
+ @patch('urllib.request.urlopen')
def test_index_retries(self, urlopen_mock):
urlopen_mock.side_effect = IOError('boom')
@@ -118,21 +115,17 @@ class TestCollector(unittest.TestCase):
self.assertRaisesRegexp(IOError, 'boom', collector.index)
self.assertEqual(5, urlopen_mock.call_count)
- @patch(URL_OPEN, Mock(return_value = io.BytesIO(b'not json')))
+ @patch('urllib.request.urlopen', Mock(return_value = io.BytesIO(b'not json')))
def test_index_malformed_json(self):
collector = CollecTor()
-
- if stem.prereq.is_python_3():
- self.assertRaisesRegexp(ValueError, 'Expecting value: line 1 column 1', collector.index, Compression.PLAINTEXT)
- else:
- self.assertRaisesRegexp(ValueError, 'No JSON object could be decoded', collector.index, Compression.PLAINTEXT)
+ self.assertRaisesRegexp(ValueError, 'Expecting value: line 1 column 1', collector.index, Compression.PLAINTEXT)
def test_index_malformed_compression(self):
for compression in (Compression.GZIP, Compression.BZ2, Compression.LZMA):
if not compression.available:
continue
- with patch(URL_OPEN, Mock(return_value = io.BytesIO(b'not compressed'))):
+ with patch('urllib.request.urlopen', Mock(return_value = io.BytesIO(b'not compressed'))):
collector = CollecTor()
self.assertRaisesRegexp(IOError, 'Failed to decompress as %s' % compression, collector.index, compression)
diff --git a/test/unit/descriptor/remote.py b/test/unit/descriptor/remote.py
index 7703c62c..f8421757 100644
--- a/test/unit/descriptor/remote.py
+++ b/test/unit/descriptor/remote.py
@@ -27,12 +27,6 @@ try:
except ImportError:
from mock import patch, Mock, MagicMock
-# The urlopen() method is in a different location depending on if we're using
-# python 2.x or 3.x. The 2to3 converter accounts for this in imports, but not
-# mock annotations.
-
-URL_OPEN = 'urllib.request.urlopen' if stem.prereq.is_python_3() else 'urllib2.urlopen'
-
TEST_RESOURCE = '/tor/server/fp/9695DFC35FFEB861329B9F1AB04C46397020CE31'
# Output from requesting moria1's descriptor from itself...
@@ -104,16 +98,13 @@ def _dirport_mock(data, encoding = 'identity'):
dirport_mock = Mock()
dirport_mock().read.return_value = data
- if stem.prereq.is_python_3():
- headers = HTTPMessage()
+ headers = HTTPMessage()
- for line in HEADER.splitlines():
- key, value = line.split(': ', 1)
- headers.add_header(key, encoding if key == 'Content-Encoding' else value)
+ for line in HEADER.splitlines():
+ key, value = line.split(': ', 1)
+ headers.add_header(key, encoding if key == 'Content-Encoding' else value)
- dirport_mock().headers = headers
- else:
- dirport_mock().headers = HTTPMessage(io.BytesIO(HEADER % encoding))
+ dirport_mock().headers = headers
return dirport_mock
@@ -165,7 +156,7 @@ class TestDescriptorDownloader(unittest.TestCase):
self.assertRaisesRegexp(stem.ProtocolError, "^Response should begin with HTTP success, but was 'HTTP/1.0 500 Kaboom'", request.run)
- @patch(URL_OPEN, _dirport_mock(TEST_DESCRIPTOR))
+ @patch('urllib.request.urlopen', _dirport_mock(TEST_DESCRIPTOR))
def test_using_dirport(self):
"""
Download a descriptor through the DirPort.
@@ -203,7 +194,7 @@ class TestDescriptorDownloader(unittest.TestCase):
query = stem.descriptor.remote.Query(TEST_RESOURCE, compression = Compression.LZMA, start = False)
self.assertEqual([stem.descriptor.Compression.PLAINTEXT], query.compression)
- @patch(URL_OPEN, _dirport_mock(read_resource('compressed_identity'), encoding = 'identity'))
+ @patch('urllib.request.urlopen', _dirport_mock(read_resource('compressed_identity'), encoding = 'identity'))
def test_compression_plaintext(self):
"""
Download a plaintext descriptor.
@@ -218,7 +209,7 @@ class TestDescriptorDownloader(unittest.TestCase):
self.assertEqual(1, len(descriptors))
self.assertEqual('moria1', descriptors[0].nickname)
- @patch(URL_OPEN, _dirport_mock(read_resource('compressed_gzip'), encoding = 'gzip'))
+ @patch('urllib.request.urlopen', _dirport_mock(read_resource('compressed_gzip'), encoding = 'gzip'))
def test_compression_gzip(self):
"""
Download a gip compressed descriptor.
@@ -233,7 +224,7 @@ class TestDescriptorDownloader(unittest.TestCase):
self.assertEqual(1, len(descriptors))
self.assertEqual('moria1', descriptors[0].nickname)
- @patch(URL_OPEN, _dirport_mock(read_resource('compressed_zstd'), encoding = 'x-zstd'))
+ @patch('urllib.request.urlopen', _dirport_mock(read_resource('compressed_zstd'), encoding = 'x-zstd'))
def test_compression_zstd(self):
"""
Download a zstd compressed descriptor.
@@ -251,7 +242,7 @@ class TestDescriptorDownloader(unittest.TestCase):
self.assertEqual(1, len(descriptors))
self.assertEqual('moria1', descriptors[0].nickname)
- @patch(URL_OPEN, _dirport_mock(read_resource('compressed_lzma'), encoding = 'x-tor-lzma'))
+ @patch('urllib.request.urlopen', _dirport_mock(read_resource('compressed_lzma'), encoding = 'x-tor-lzma'))
def test_compression_lzma(self):
"""
Download a lzma compressed descriptor.
@@ -269,7 +260,7 @@ class TestDescriptorDownloader(unittest.TestCase):
self.assertEqual(1, len(descriptors))
self.assertEqual('moria1', descriptors[0].nickname)
- @patch(URL_OPEN)
+ @patch('urllib.request.urlopen')
def test_each_getter(self, dirport_mock):
"""
Surface level exercising of each getter method for downloading descriptors.
@@ -286,7 +277,7 @@ class TestDescriptorDownloader(unittest.TestCase):
downloader.get_bandwidth_file()
downloader.get_detached_signatures()
- @patch(URL_OPEN, _dirport_mock(TEST_DESCRIPTOR))
+ @patch('urllib.request.urlopen', _dirport_mock(TEST_DESCRIPTOR))
def test_reply_headers(self):
query = stem.descriptor.remote.get_server_descriptors('9695DFC35FFEB861329B9F1AB04C46397020CE31', start = False)
self.assertEqual(None, query.reply_headers) # initially we don't have a reply
@@ -309,7 +300,7 @@ class TestDescriptorDownloader(unittest.TestCase):
self.assertEqual(1, len(descriptors))
self.assertEqual('moria1', descriptors[0].nickname)
- @patch(URL_OPEN, _dirport_mock(TEST_DESCRIPTOR))
+ @patch('urllib.request.urlopen', _dirport_mock(TEST_DESCRIPTOR))
def test_query_download(self):
"""
Check Query functionality when we successfully download a descriptor.
@@ -334,7 +325,7 @@ class TestDescriptorDownloader(unittest.TestCase):
self.assertEqual('9695DFC35FFEB861329B9F1AB04C46397020CE31', desc.fingerprint)
self.assertEqual(TEST_DESCRIPTOR, desc.get_bytes())
- @patch(URL_OPEN, _dirport_mock(b'some malformed stuff'))
+ @patch('urllib.request.urlopen', _dirport_mock(b'some malformed stuff'))
def test_query_with_malformed_content(self):
"""
Query with malformed descriptor content.
@@ -361,7 +352,7 @@ class TestDescriptorDownloader(unittest.TestCase):
self.assertRaises(ValueError, query.run)
- @patch(URL_OPEN)
+ @patch('urllib.request.urlopen')
def test_query_with_timeout(self, dirport_mock):
def urlopen_call(*args, **kwargs):
time.sleep(0.06)
@@ -396,7 +387,7 @@ class TestDescriptorDownloader(unittest.TestCase):
expected_error = 'Endpoints must be an stem.ORPort, stem.DirPort, or two value tuple. ' + error_suffix
self.assertRaisesWith(ValueError, expected_error, stem.descriptor.remote.Query, TEST_RESOURCE, 'server-descriptor 1.0', endpoints = endpoints)
- @patch(URL_OPEN, _dirport_mock(TEST_DESCRIPTOR))
+ @patch('urllib.request.urlopen', _dirport_mock(TEST_DESCRIPTOR))
def test_can_iterate_multiple_times(self):
query = stem.descriptor.remote.Query(
TEST_RESOURCE,
diff --git a/test/unit/directory/authority.py b/test/unit/directory/authority.py
index 1c2a86b4..c2ebd322 100644
--- a/test/unit/directory/authority.py
+++ b/test/unit/directory/authority.py
@@ -15,8 +15,6 @@ try:
except ImportError:
from mock import patch, Mock
-URL_OPEN = 'urllib.request.urlopen' if stem.prereq.is_python_3() else 'urllib2.urlopen'
-
AUTHORITY_GITWEB_CONTENT = b"""\
"moria1 orport=9101 "
"v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
@@ -53,7 +51,7 @@ class TestAuthority(unittest.TestCase):
self.assertTrue(len(authorities) > 4)
self.assertEqual('128.31.0.39', authorities['moria1'].address)
- @patch(URL_OPEN, Mock(return_value = io.BytesIO(AUTHORITY_GITWEB_CONTENT)))
+ @patch('urllib.request.urlopen', Mock(return_value = io.BytesIO(AUTHORITY_GITWEB_CONTENT)))
def test_from_remote(self):
expected = {
'moria1': stem.directory.Authority(
@@ -77,6 +75,6 @@ class TestAuthority(unittest.TestCase):
self.assertEqual(expected, stem.directory.Authority.from_remote())
- @patch(URL_OPEN, Mock(return_value = io.BytesIO(b'')))
+ @patch('urllib.request.urlopen', Mock(return_value = io.BytesIO(b'')))
def test_from_remote_empty(self):
self.assertRaisesRegexp(stem.DownloadFailed, 'no content', stem.directory.Authority.from_remote)
diff --git a/test/unit/directory/fallback.py b/test/unit/directory/fallback.py
index 00965187..f999943f 100644
--- a/test/unit/directory/fallback.py
+++ b/test/unit/directory/fallback.py
@@ -18,8 +18,6 @@ try:
except ImportError:
from mock import patch, Mock
-URL_OPEN = 'urllib.request.urlopen' if stem.prereq.is_python_3() else 'urllib2.urlopen'
-
FALLBACK_GITWEB_CONTENT = b"""\
/* type=fallback */
/* version=2.0.0 */
@@ -90,7 +88,7 @@ class TestFallback(unittest.TestCase):
self.assertTrue(len(fallbacks) > 10)
self.assertEqual('185.13.39.197', fallbacks['001524DD403D729F08F7E5D77813EF12756CFA8D'].address)
- @patch(URL_OPEN, Mock(return_value = io.BytesIO(FALLBACK_GITWEB_CONTENT)))
+ @patch('urllib.request.urlopen', Mock(return_value = io.BytesIO(FALLBACK_GITWEB_CONTENT)))
def test_from_remote(self):
expected = {
'0756B7CD4DFC8182BE23143FAC0642F515182CEB': stem.directory.Fallback(
@@ -117,15 +115,15 @@ class TestFallback(unittest.TestCase):
self.assertEqual(expected, stem.directory.Fallback.from_remote())
- @patch(URL_OPEN, Mock(return_value = io.BytesIO(b'')))
+ @patch('urllib.request.urlopen', Mock(return_value = io.BytesIO(b'')))
def test_from_remote_empty(self):
self.assertRaisesRegexp(stem.DownloadFailed, 'no content', stem.directory.Fallback.from_remote)
- @patch(URL_OPEN, Mock(return_value = io.BytesIO(b'\n'.join(FALLBACK_GITWEB_CONTENT.splitlines()[1:]))))
+ @patch('urllib.request.urlopen', Mock(return_value = io.BytesIO(b'\n'.join(FALLBACK_GITWEB_CONTENT.splitlines()[1:]))))
def test_from_remote_no_header(self):
self.assertRaisesRegexp(IOError, 'does not have a type field indicating it is fallback directory metadata', stem.directory.Fallback.from_remote)
- @patch(URL_OPEN, Mock(return_value = io.BytesIO(FALLBACK_GITWEB_CONTENT.replace(b'version=2.0.0', b'version'))))
+ @patch('urllib.request.urlopen', Mock(return_value = io.BytesIO(FALLBACK_GITWEB_CONTENT.replace(b'version=2.0.0', b'version'))))
def test_from_remote_malformed_header(self):
self.assertRaisesRegexp(IOError, 'Malformed fallback directory header line: /\\* version \\*/', stem.directory.Fallback.from_remote)
@@ -140,7 +138,7 @@ class TestFallback(unittest.TestCase):
}
for entry, expected in test_values.items():
- with patch(URL_OPEN, Mock(return_value = io.BytesIO(entry))):
+ with patch('urllib.request.urlopen', Mock(return_value = io.BytesIO(entry))):
self.assertRaisesRegexp(IOError, re.escape(expected), stem.directory.Fallback.from_remote)
def test_persistence(self):
diff --git a/test/unit/manual.py b/test/unit/manual.py
index c108af19..b10ce2a0 100644
--- a/test/unit/manual.py
+++ b/test/unit/manual.py
@@ -26,7 +26,6 @@ try:
except ImportError:
from mock import Mock, patch
-URL_OPEN = 'urllib.request.urlopen' if stem.prereq.is_python_3() else 'urllib2.urlopen'
EXAMPLE_MAN_PATH = os.path.join(os.path.dirname(__file__), 'tor_man_example')
UNKNOWN_OPTIONS_MAN_PATH = os.path.join(os.path.dirname(__file__), 'tor_man_with_unknown')
@@ -252,7 +251,7 @@ class TestManual(unittest.TestCase):
@patch('shutil.rmtree', Mock())
@patch('stem.manual.open', Mock(return_value = io.BytesIO()), create = True)
@patch('stem.util.system.is_available', Mock(return_value = True))
- @patch(URL_OPEN, Mock(side_effect = urllib.URLError('<urlopen error [Errno -2] Name or service not known>')))
+ @patch('urllib.request.urlopen', Mock(side_effect = urllib.URLError('<urlopen error [Errno -2] Name or service not known>')))
def test_download_man_page_when_download_fails(self):
exc_msg = "Unable to download tor's manual from https://www.atagar.com/foo/bar to /no/such/path/tor.1.txt: <urlopen error <urlopen error [Errno -2] Name or service not known>>"
self.assertRaisesWith(IOError, exc_msg, stem.manual.download_man_page, '/tmp/no_such_file', url = 'https://www.atagar.com/foo/bar')
@@ -262,7 +261,7 @@ class TestManual(unittest.TestCase):
@patch('stem.manual.open', Mock(return_value = io.BytesIO()), create = True)
@patch('stem.util.system.call', Mock(side_effect = stem.util.system.CallError('call failed', 'a2x -f manpage /no/such/path/tor.1.txt', 1, None, None, 'call failed')))
@patch('stem.util.system.is_available', Mock(return_value = True))
- @patch(URL_OPEN, Mock(return_value = io.BytesIO(b'test content')))
+ @patch('urllib.request.urlopen', Mock(return_value = io.BytesIO(b'test content')))
def test_download_man_page_when_a2x_fails(self):
exc_msg = "Unable to run 'a2x -f manpage /no/such/path/tor.1.txt': call failed"
self.assertRaisesWith(IOError, exc_msg, stem.manual.download_man_page, '/tmp/no_such_file', url = 'https://www.atagar.com/foo/bar')
@@ -273,7 +272,7 @@ class TestManual(unittest.TestCase):
@patch('stem.util.system.call')
@patch('stem.util.system.is_available', Mock(return_value = True))
@patch('os.path.exists', Mock(return_value = True))
- @patch(URL_OPEN, Mock(return_value = io.BytesIO(b'test content')))
+ @patch('urllib.request.urlopen', Mock(return_value = io.BytesIO(b'test content')))
def test_download_man_page_when_successful(self, call_mock, open_mock):
open_mock.side_effect = lambda path, *args: {
'/no/such/path/tor.1.txt': io.BytesIO(),
diff --git a/test/unit/tutorial_examples.py b/test/unit/tutorial_examples.py
index de00a2b8..67a688b8 100644
--- a/test/unit/tutorial_examples.py
+++ b/test/unit/tutorial_examples.py
@@ -129,12 +129,6 @@ def _get_router_status(address = None, port = None, nickname = None, fingerprint
class TestTutorialExamples(unittest.TestCase):
- def assert_equal_unordered(self, expected, actual):
- if stem.prereq.is_python_3():
- self.assertCountEqual(expected.splitlines(), actual.splitlines())
- else:
- self.assertItemsEqual(expected.splitlines(), actual.splitlines())
-
@patch('sys.stdout', new_callable = StringIO)
@patch('stem.control.Controller.from_port', spec = Controller)
def test_list_circuits(self, from_port_mock, stdout_mock):
@@ -164,7 +158,7 @@ class TestTutorialExamples(unittest.TestCase):
}[fingerprint]
exec_documentation_example('list_circuits.py')
- self.assert_equal_unordered(LIST_CIRCUITS_OUTPUT, stdout_mock.getvalue())
+ self.assertCountEqual(LIST_CIRCUITS_OUTPUT.splitlines(), stdout_mock.getvalue().splitlines())
@patch('sys.stdout', new_callable = StringIO)
@patch('stem.control.Controller.from_port', spec = Controller)
@@ -215,7 +209,7 @@ class TestTutorialExamples(unittest.TestCase):
controller.get_info.return_value = 'unknown'
tutorial_example(event)
- self.assert_equal_unordered(EXIT_USED_OUTPUT, stdout_mock.getvalue())
+ self.assertCountEqual(EXIT_USED_OUTPUT.splitlines(), stdout_mock.getvalue().splitlines())
@patch('sys.stdout', new_callable = StringIO)
@patch('stem.descriptor.remote.DescriptorDownloader')
@@ -229,7 +223,7 @@ class TestTutorialExamples(unittest.TestCase):
exec_documentation_example('outdated_relays.py')
- self.assert_equal_unordered(OUTDATED_RELAYS_OUTPUT, stdout_mock.getvalue())
+ self.assertCountEqual(OUTDATED_RELAYS_OUTPUT.splitlines(), stdout_mock.getvalue().splitlines())
@patch('sys.stdout', new_callable = StringIO)
@patch('stem.descriptor.remote.Query')
@@ -270,7 +264,7 @@ class TestTutorialExamples(unittest.TestCase):
exec_documentation_example('compare_flags.py')
- self.assert_equal_unordered(COMPARE_FLAGS_OUTPUT, stdout_mock.getvalue())
+ self.assertCountEqual(COMPARE_FLAGS_OUTPUT.splitlines(), stdout_mock.getvalue().splitlines())
@patch('sys.stdout', new_callable = StringIO)
@patch('stem.directory.Authority.from_cache')
@@ -303,7 +297,7 @@ class TestTutorialExamples(unittest.TestCase):
query_mock.side_effect = [query1, query2, query3]
exec_documentation_example('votes_by_bandwidth_authorities.py')
- self.assert_equal_unordered(VOTES_BY_BANDWIDTH_AUTHORITIES_OUTPUT, stdout_mock.getvalue())
+ self.assertCountEqual(VOTES_BY_BANDWIDTH_AUTHORITIES_OUTPUT.splitlines(), stdout_mock.getvalue().splitlines())
@patch('sys.stdout', new_callable = StringIO)
@patch('stem.descriptor.parse_file')
diff --git a/test/unit/util/connection.py b/test/unit/util/connection.py
index 8721ff6d..73cb3c38 100644
--- a/test/unit/util/connection.py
+++ b/test/unit/util/connection.py
@@ -23,7 +23,6 @@ try:
except ImportError:
from mock import Mock, patch
-URL_OPEN = 'urllib.request.urlopen' if stem.prereq.is_python_3() else 'urllib2.urlopen'
URL = 'https://example.unit.test.url'
NETSTAT_OUTPUT = """\
@@ -177,14 +176,14 @@ _tor tor 15843 20* internet stream tcp 0x0 192.168.1.100:36174 -->
class TestConnection(unittest.TestCase):
- @patch(URL_OPEN)
+ @patch('urllib.request.urlopen')
def test_download(self, urlopen_mock):
urlopen_mock.return_value = io.BytesIO(b'hello')
self.assertEqual(b'hello', stem.util.connection.download(URL))
urlopen_mock.assert_called_with(URL, timeout = None)
- @patch(URL_OPEN)
+ @patch('urllib.request.urlopen')
def test_download_failure(self, urlopen_mock):
urlopen_mock.side_effect = urllib.URLError('boom')
@@ -198,7 +197,7 @@ class TestConnection(unittest.TestCase):
self.assertEqual(urllib.URLError, type(exc.error))
self.assertTrue('return urllib.urlopen(url, timeout = timeout).read()' in exc.stacktrace_str)
- @patch(URL_OPEN)
+ @patch('urllib.request.urlopen')
def test_download_retries(self, urlopen_mock):
urlopen_mock.side_effect = urllib.URLError('boom')
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits