[tor-commits] [stem/master] Drop OrderedDict copy

atagar at torproject.org atagar at torproject.org
Sun Jan 5 21:39:28 UTC 2020


commit a1eaf853775316e20649e49115a4e9839dfa4393
Author: Damian Johnson <atagar at torproject.org>
Date:   Fri Jan 3 13:46:48 2020 -0800

    Drop OrderedDict copy
    
    Python added OrderedDict as a builtin in Python 2.7. We included a copy for
    Python 2.6 compatibity and as such is no longer required.
---
 stem/control.py                                   |  10 +-
 stem/descriptor/__init__.py                       |  12 +-
 stem/descriptor/bandwidth_file.py                 |  11 +-
 stem/directory.py                                 |  11 +-
 stem/manual.py                                    |  33 +++---
 stem/util/conf.py                                 |  15 +--
 stem/util/ordereddict.py                          | 133 ----------------------
 test/unit/descriptor/bandwidth_file.py            |  13 +--
 test/unit/descriptor/hidden_service_v3.py         |   9 +-
 test/unit/descriptor/networkstatus/document_v3.py |  11 +-
 test/unit/descriptor/router_status_entry.py       |   9 +-
 test/unit/descriptor/server_descriptor.py         |   9 +-
 test/unit/directory/fallback.py                   |  11 +-
 test/unit/manual.py                               |  11 +-
 14 files changed, 49 insertions(+), 249 deletions(-)

diff --git a/stem/control.py b/stem/control.py
index 56567467..25a65f43 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -257,12 +257,6 @@ import threading
 import time
 
 try:
-  # Added in 2.7
-  from collections import OrderedDict
-except ImportError:
-  from stem.util.ordereddict import OrderedDict
-
-try:
   # Added in 3.x
   import queue
 except ImportError:
@@ -2623,7 +2617,7 @@ class Controller(BaseController):
       log.debug('GETCONF HiddenServiceOptions (failed: %s)' % exc)
       raise
 
-    service_dir_map = OrderedDict()
+    service_dir_map = collections.OrderedDict()
     directory = None
 
     for status_code, divider, content in response.content():
@@ -2779,7 +2773,7 @@ class Controller(BaseController):
     if path in conf and (port, target_address, target_port) in conf[path]['HiddenServicePort']:
       return None
 
-    conf.setdefault(path, OrderedDict()).setdefault('HiddenServicePort', []).append((port, target_address, target_port))
+    conf.setdefault(path, collections.OrderedDict()).setdefault('HiddenServicePort', []).append((port, target_address, target_port))
 
     if auth_type and client_names:
       hsac = "%s %s" % (auth_type, ','.join(client_names))
diff --git a/stem/descriptor/__init__.py b/stem/descriptor/__init__.py
index c97db183..bab339ac 100644
--- a/stem/descriptor/__init__.py
+++ b/stem/descriptor/__init__.py
@@ -106,12 +106,6 @@ import stem.util.enum
 import stem.util.str_tools
 import stem.util.system
 
-try:
-  # added in python 2.7
-  from collections import OrderedDict
-except ImportError:
-  from stem.util.ordereddict import OrderedDict
-
 __all__ = [
   'bandwidth_file',
   'certificate',
@@ -589,7 +583,7 @@ def _descriptor_content(attr = None, exclude = (), header_template = (), footer_
   """
 
   header_content, footer_content = [], []
-  attr = {} if attr is None else OrderedDict(attr)  # shallow copy since we're destructive
+  attr = {} if attr is None else collections.OrderedDict(attr)  # shallow copy since we're destructive
 
   for content, template in ((header_content, header_template),
                             (footer_content, footer_template)):
@@ -707,7 +701,7 @@ def _parse_protocol_line(keyword, attribute):
     # parses 'protocol' entries like: Cons=1-2 Desc=1-2 DirCache=1 HSDir=1
 
     value = _value(keyword, entries)
-    protocols = OrderedDict()
+    protocols = collections.OrderedDict()
 
     for k, v in _mappings_for(keyword, value):
       versions = []
@@ -1468,7 +1462,7 @@ def _descriptor_components(raw_contents, validate, extra_keywords = (), non_asci
   if isinstance(raw_contents, bytes):
     raw_contents = stem.util.str_tools._to_unicode(raw_contents)
 
-  entries = OrderedDict()
+  entries = collections.OrderedDict()
   extra_entries = []  # entries with a keyword in extra_keywords
   remaining_lines = raw_contents.split('\n')
 
diff --git a/stem/descriptor/bandwidth_file.py b/stem/descriptor/bandwidth_file.py
index 658f02b8..43c43aff 100644
--- a/stem/descriptor/bandwidth_file.py
+++ b/stem/descriptor/bandwidth_file.py
@@ -14,6 +14,7 @@ Parsing for Bandwidth Authority metrics as described in Tor's
 .. versionadded:: 1.8.0
 """
 
+import collections
 import datetime
 import io
 import time
@@ -25,12 +26,6 @@ from stem.descriptor import (
   Descriptor,
 )
 
-try:
-  # added in python 2.7
-  from collections import OrderedDict
-except ImportError:
-  from stem.util.ordereddict import OrderedDict
-
 # Four character dividers are allowed for backward compatability, but five is
 # preferred.
 
@@ -175,7 +170,7 @@ def _parse_file(descriptor_file, validate = False, **kwargs):
 
 
 def _parse_header(descriptor, entries):
-  header = OrderedDict()
+  header = collections.OrderedDict()
   content = io.BytesIO(descriptor.get_bytes())
 
   content.readline()  # skip the first line, which should be the timestamp
@@ -332,7 +327,7 @@ class BandwidthFile(Descriptor):
     if sign:
       raise NotImplementedError('Signing of %s not implemented' % cls.__name__)
 
-    header = OrderedDict(attr) if attr is not None else OrderedDict()
+    header = collections.OrderedDict(attr) if attr is not None else collections.OrderedDict()
     timestamp = header.pop('timestamp', str(int(time.time())))
     content = header.pop('content', [])
     version = header.get('version', HEADER_DEFAULT.get('version'))
diff --git a/stem/directory.py b/stem/directory.py
index b93b49a2..0ca089c3 100644
--- a/stem/directory.py
+++ b/stem/directory.py
@@ -38,6 +38,7 @@ as follows...
 .. versionadded:: 1.7.0
 """
 
+import collections
 import os
 import re
 import sys
@@ -49,12 +50,6 @@ import stem.util.conf
 from stem.util import connection, str_tools, tor_tools
 
 try:
-  # added in python 2.7
-  from collections import OrderedDict
-except ImportError:
-  from stem.util.ordereddict import OrderedDict
-
-try:
   # account for urllib's change between python 2.x and 3.x
   import urllib.request as urllib
 except ImportError:
@@ -369,13 +364,13 @@ class Fallback(Directory):
   def __init__(self, address = None, or_port = None, dir_port = None, fingerprint = None, nickname = None, has_extrainfo = False, orport_v6 = None, header = None):
     super(Fallback, self).__init__(address, or_port, dir_port, fingerprint, nickname, orport_v6)
     self.has_extrainfo = has_extrainfo
-    self.header = OrderedDict(header) if header else OrderedDict()
+    self.header = collections.OrderedDict(header) if header else collections.OrderedDict()
 
   @staticmethod
   def from_cache(path = FALLBACK_CACHE_PATH):
     conf = stem.util.conf.Config()
     conf.load(path)
-    headers = OrderedDict([(k.split('.', 1)[1], conf.get(k)) for k in conf.keys() if k.startswith('header.')])
+    headers = collections.OrderedDict([(k.split('.', 1)[1], conf.get(k)) for k in conf.keys() if k.startswith('header.')])
 
     results = {}
 
diff --git a/stem/manual.py b/stem/manual.py
index 25d435d4..b94d4e0b 100644
--- a/stem/manual.py
+++ b/stem/manual.py
@@ -48,6 +48,7 @@ us what our torrc options do...
 .. versionadded:: 1.5.0
 """
 
+import collections
 import os
 import shutil
 import sys
@@ -61,12 +62,6 @@ import stem.util.enum
 import stem.util.log
 import stem.util.system
 
-try:
-  # added in python 2.7
-  from collections import OrderedDict
-except ImportError:
-  from stem.util.ordereddict import OrderedDict
-
 if stem.prereq._is_lru_cache_available():
   from functools import lru_cache
 else:
@@ -96,7 +91,7 @@ SCHEMA = (
   'CREATE TABLE torrc(key TEXT PRIMARY KEY, name TEXT, category TEXT, usage TEXT, summary TEXT, description TEXT, position INTEGER)',
 )
 
-CATEGORY_SECTIONS = OrderedDict((
+CATEGORY_SECTIONS = collections.OrderedDict((
   ('GENERAL OPTIONS', Category.GENERAL),
   ('CLIENT OPTIONS', Category.CLIENT),
   ('SERVER OPTIONS', Category.RELAY),
@@ -374,10 +369,10 @@ class Manual(object):
     self.name = name
     self.synopsis = synopsis
     self.description = description
-    self.commandline_options = OrderedDict(commandline_options)
-    self.signals = OrderedDict(signals)
-    self.files = OrderedDict(files)
-    self.config_options = OrderedDict(config_options)
+    self.commandline_options = collections.OrderedDict(commandline_options)
+    self.signals = collections.OrderedDict(signals)
+    self.files = collections.OrderedDict(files)
+    self.config_options = collections.OrderedDict(config_options)
     self.man_commit = None
     self.stem_commit = None
     self.schema = None
@@ -442,7 +437,7 @@ class Manual(object):
       signals = dict(conn.execute('SELECT name, description FROM signals').fetchall())
       files = dict(conn.execute('SELECT name, description FROM files').fetchall())
 
-      config_options = OrderedDict()
+      config_options = collections.OrderedDict()
 
       for entry in conn.execute('SELECT name, category, usage, summary, description FROM torrc ORDER BY position').fetchall():
         option, category, usage, summary, option_description = entry
@@ -460,7 +455,7 @@ class Manual(object):
     conf = stem.util.conf.Config()
     conf.load(path, commenting = False)
 
-    config_options = OrderedDict()
+    config_options = collections.OrderedDict()
 
     for key in conf.keys():
       if key.startswith('config_options.'):
@@ -479,9 +474,9 @@ class Manual(object):
       conf.get('name', ''),
       conf.get('synopsis', ''),
       conf.get('description', ''),
-      conf.get('commandline_options', OrderedDict()),
-      conf.get('signals', OrderedDict()),
-      conf.get('files', OrderedDict()),
+      conf.get('commandline_options', collections.OrderedDict()),
+      conf.get('signals', collections.OrderedDict()),
+      conf.get('files', collections.OrderedDict()),
       config_options,
     )
 
@@ -514,7 +509,7 @@ class Manual(object):
     except OSError as exc:
       raise IOError("Unable to run '%s': %s" % (man_cmd, exc))
 
-    categories, config_options = _get_categories(man_output), OrderedDict()
+    categories, config_options = _get_categories(man_output), collections.OrderedDict()
 
     for category_header, category_enum in CATEGORY_SECTIONS.items():
       _add_config_options(config_options, category_enum, categories.get(category_header, []))
@@ -677,7 +672,7 @@ def _get_categories(content):
   if content and content[-1].startswith('Tor'):
     content = content[:-1]
 
-  categories = OrderedDict()
+  categories = collections.OrderedDict()
   category, lines = None, []
 
   for line in content:
@@ -727,7 +722,7 @@ def _get_indented_descriptions(lines):
   ignoring those.
   """
 
-  options, last_arg = OrderedDict(), None
+  options, last_arg = collections.OrderedDict(), None
 
   for line in lines:
     if line == '    Note':
diff --git a/stem/util/conf.py b/stem/util/conf.py
index b4580ed9..7dffe95a 100644
--- a/stem/util/conf.py
+++ b/stem/util/conf.py
@@ -157,6 +157,7 @@ Here's an expanation of what happened...
     +- get_value - provides the value for a given key as a string
 """
 
+import collections
 import inspect
 import os
 import threading
@@ -165,12 +166,6 @@ import stem.prereq
 
 from stem.util import log
 
-try:
-  # added in python 2.7
-  from collections import OrderedDict
-except ImportError:
-  from stem.util.ordereddict import OrderedDict
-
 CONFS = {}  # mapping of identifier to singleton instances of configs
 
 
@@ -453,9 +448,9 @@ class Config(object):
   """
 
   def __init__(self):
-    self._path = None        # location we last loaded from or saved to
-    self._contents = OrderedDict()  # configuration key/value pairs
-    self._listeners = []     # functors to be notified of config changes
+    self._path = None  # location we last loaded from or saved to
+    self._contents = collections.OrderedDict()  # configuration key/value pairs
+    self._listeners = []  # functors to be notified of config changes
 
     # used for accessing _contents
     self._contents_lock = threading.RLock()
@@ -735,7 +730,7 @@ class Config(object):
     elif isinstance(default, tuple):
       val = tuple(val)
     elif isinstance(default, dict):
-      val_map = OrderedDict()
+      val_map = collections.OrderedDict()
       for entry in val:
         if '=>' in entry:
           entry_key, entry_val = entry.split('=>', 1)
diff --git a/stem/util/ordereddict.py b/stem/util/ordereddict.py
deleted file mode 100644
index ec228f31..00000000
--- a/stem/util/ordereddict.py
+++ /dev/null
@@ -1,133 +0,0 @@
-# Drop in replacement for python 2.7's OrderedDict, from...
-# https://pypi.org/project/ordereddict/
-#
-# Stem users should *not* rely upon this module. It will be removed when we
-# drop support for python 2.6 and below.
-
-# Copyright (c) 2009 Raymond Hettinger
-#
-# Permission is hereby granted, free of charge, to any person
-# obtaining a copy of this software and associated documentation files
-# (the "Software"), to deal in the Software without restriction,
-# including without limitation the rights to use, copy, modify, merge,
-# publish, distribute, sublicense, and/or sell copies of the Software,
-# and to permit persons to whom the Software is furnished to do so,
-# subject to the following conditions:
-#
-#     The above copyright notice and this permission notice shall be
-#     included in all copies or substantial portions of the Software.
-#
-#     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-#     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-#     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-#     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-#     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-#     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-#     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-#     OTHER DEALINGS IN THE SOFTWARE.
-
-from UserDict import DictMixin
-
-
-class OrderedDict(dict, DictMixin):
-  def __init__(self, *args, **kwds):
-    if len(args) > 1:
-      raise TypeError('expected at most 1 arguments, got %d' % len(args))
-    try:
-      self.__end
-    except AttributeError:
-      self.clear()
-    self.update(*args, **kwds)
-
-  def clear(self):
-    self.__end = end = []
-    end += [None, end, end]         # sentinel node for doubly linked list
-    self.__map = {}                 # key --> [key, prev, next]
-    dict.clear(self)
-
-  def __setitem__(self, key, value):
-    if key not in self:
-      end = self.__end
-      curr = end[1]
-      curr[2] = end[1] = self.__map[key] = [key, curr, end]
-    dict.__setitem__(self, key, value)
-
-  def __delitem__(self, key):
-    dict.__delitem__(self, key)
-    key, prev, next = self.__map.pop(key)
-    prev[2] = next
-    next[1] = prev
-
-  def __iter__(self):
-    end = self.__end
-    curr = end[2]
-    while curr is not end:
-      yield curr[0]
-      curr = curr[2]
-
-  def __reversed__(self):
-    end = self.__end
-    curr = end[1]
-    while curr is not end:
-      yield curr[0]
-      curr = curr[1]
-
-  def popitem(self, last=True):
-    if not self:
-      raise KeyError('dictionary is empty')
-    if last:
-      key = reversed(self).next()
-    else:
-      key = iter(self).next()
-    value = self.pop(key)
-    return key, value
-
-  def __reduce__(self):
-    items = [[k, self[k]] for k in self]
-    tmp = self.__map, self.__end
-    del self.__map, self.__end
-    inst_dict = vars(self).copy()
-    self.__map, self.__end = tmp
-    if inst_dict:
-      return (self.__class__, (items,), inst_dict)
-    return self.__class__, (items,)
-
-  def keys(self):
-    return list(self)
-
-  setdefault = DictMixin.setdefault
-  update = DictMixin.update
-  pop = DictMixin.pop
-  values = DictMixin.values
-  items = DictMixin.items
-  iterkeys = DictMixin.iterkeys
-  itervalues = DictMixin.itervalues
-  iteritems = DictMixin.iteritems
-
-  def __repr__(self):
-    if not self:
-      return '%s()' % (self.__class__.__name__,)
-    return '%s(%r)' % (self.__class__.__name__, self.items())
-
-  def copy(self):
-    return self.__class__(self)
-
-  @classmethod
-  def fromkeys(cls, iterable, value=None):
-    d = cls()
-    for key in iterable:
-      d[key] = value
-    return d
-
-  def __eq__(self, other):
-    if isinstance(other, OrderedDict):
-      if len(self) != len(other):
-        return False
-      for p, q in zip(self.items(), other.items()):
-        if p != q:
-          return False
-      return True
-    return dict.__eq__(self, other)
-
-  def __ne__(self, other):
-    return not self == other
diff --git a/test/unit/descriptor/bandwidth_file.py b/test/unit/descriptor/bandwidth_file.py
index 3040c38b..bb1eeffa 100644
--- a/test/unit/descriptor/bandwidth_file.py
+++ b/test/unit/descriptor/bandwidth_file.py
@@ -2,6 +2,7 @@
 Unit tests for stem.descriptor.bandwidth_file.
 """
 
+import collections
 import datetime
 import unittest
 
@@ -11,12 +12,6 @@ from stem.descriptor.bandwidth_file import BandwidthFile
 from test.unit.descriptor import get_resource
 
 try:
-  # added in python 2.7
-  from collections import OrderedDict
-except ImportError:
-  from stem.util.ordereddict import OrderedDict
-
-try:
   # added in python 3.3
   from unittest.mock import Mock, patch
 except ImportError:
@@ -272,7 +267,7 @@ class TestBandwidthFile(unittest.TestCase):
     Exercise the example in our content method's pydoc.
     """
 
-    content = BandwidthFile.content(OrderedDict([
+    content = BandwidthFile.content(collections.OrderedDict([
       ('timestamp', '12345'),
       ('version', '1.2.0'),
       ('content', []),
@@ -286,7 +281,7 @@ class TestBandwidthFile(unittest.TestCase):
     Include an unrecognized header field.
     """
 
-    desc = BandwidthFile.create(OrderedDict([('version', '1.1.0'), ('new_header', 'neat stuff')]))
+    desc = BandwidthFile.create(collections.OrderedDict([('version', '1.1.0'), ('new_header', 'neat stuff')]))
     self.assertEqual(EXPECTED_NEW_HEADER_CONTENT, str(desc))
     self.assertEqual('1.1.0', desc.version)
     self.assertEqual({'version': '1.1.0', 'new_header': 'neat stuff'}, desc.header)
@@ -309,7 +304,7 @@ class TestBandwidthFile(unittest.TestCase):
 
     self.assertRaisesWith(ValueError, "The 'version' header must be in the second position", BandwidthFile.from_str, WRONG_VERSION_POSITION, validate = True)
 
-    content = BandwidthFile.content(OrderedDict([
+    content = BandwidthFile.content(collections.OrderedDict([
       ('timestamp', '1410723598'),
       ('file_created', '2019-01-14T05:35:06'),
       ('version', '1.1.0'),
diff --git a/test/unit/descriptor/hidden_service_v3.py b/test/unit/descriptor/hidden_service_v3.py
index 33507314..0c172fcb 100644
--- a/test/unit/descriptor/hidden_service_v3.py
+++ b/test/unit/descriptor/hidden_service_v3.py
@@ -3,6 +3,7 @@ Unit tests for stem.descriptor.hidden_service for version 3.
 """
 
 import base64
+import collections
 import functools
 import unittest
 
@@ -28,12 +29,6 @@ from test.unit.descriptor import (
 )
 
 try:
-  # added in python 2.7
-  from collections import OrderedDict
-except ImportError:
-  from stem.util.ordereddict import OrderedDict
-
-try:
   # added in python 3.3
   from unittest.mock import patch, Mock
 except ImportError:
@@ -328,7 +323,7 @@ class TestHiddenServiceDescriptorV3(unittest.TestCase):
 
     # include optional parameters
 
-    desc = InnerLayer.create(OrderedDict((
+    desc = InnerLayer.create(collections.OrderedDict((
       ('intro-auth-required', 'ed25519'),
       ('single-onion-service', ''),
     )))
diff --git a/test/unit/descriptor/networkstatus/document_v3.py b/test/unit/descriptor/networkstatus/document_v3.py
index ce7cfdb7..93f98d77 100644
--- a/test/unit/descriptor/networkstatus/document_v3.py
+++ b/test/unit/descriptor/networkstatus/document_v3.py
@@ -2,6 +2,7 @@
 Unit tests for the NetworkStatusDocumentV3 of stem.descriptor.networkstatus.
 """
 
+import collections
 import datetime
 import io
 import unittest
@@ -31,12 +32,6 @@ from stem.descriptor.router_status_entry import (
 
 from test.unit.descriptor import get_resource
 
-try:
-  # added in python 2.7
-  from collections import OrderedDict
-except ImportError:
-  from stem.util.ordereddict import OrderedDict
-
 BANDWIDTH_WEIGHT_ENTRIES = (
   'Wbd', 'Wbe', 'Wbg', 'Wbm',
   'Wdb',
@@ -869,7 +864,7 @@ DnN5aFtYKiTc19qIC7Nmo+afPdDEf0MlJvEOP5EWl3w=
     Parses the parameters attributes.
     """
 
-    document = NetworkStatusDocumentV3.create(OrderedDict([
+    document = NetworkStatusDocumentV3.create(collections.OrderedDict([
       ('vote-status', 'vote'),
       ('recommended-client-protocols', 'HSDir=1 HSIntro=3'),
       ('recommended-relay-protocols', 'Cons=1 Desc=1'),
@@ -1231,7 +1226,7 @@ DnN5aFtYKiTc19qIC7Nmo+afPdDEf0MlJvEOP5EWl3w=
     COMMITMENT_1 = '1 sha3-256 4CAEC248004A0DC6CE86EBD5F608C9B05500C70C AAAAAFd4/kAaklgYr4ijHZjXXy/B354jQfL31BFhhE46nuOHSPITyw== AAAAAFd4/kCpZeis3yJyr//rz8hXCeeAhHa4k3lAcAiMJd1vEMTPuw=='
     COMMITMENT_2 = '1 sha3-256 598536A9DD4E6C0F18B4AD4B88C7875A0A29BA31 AAAAAFd4/kC7S920awC5/HF5RfX4fKZtYqjm6qMh9G91AcjZm13DQQ=='
 
-    authority = DirectoryAuthority.create(OrderedDict([
+    authority = DirectoryAuthority.create(collections.OrderedDict([
       ('shared-rand-participate', ''),
       ('shared-rand-commit', '%s\nshared-rand-commit %s' % (COMMITMENT_1, COMMITMENT_2)),
       ('shared-rand-previous-value', '8 hAQLxyt0U3gu7QR2owixRCbIltcyPrz3B0YBfUshOkE='),
diff --git a/test/unit/descriptor/router_status_entry.py b/test/unit/descriptor/router_status_entry.py
index c428d6b2..7ee942e0 100644
--- a/test/unit/descriptor/router_status_entry.py
+++ b/test/unit/descriptor/router_status_entry.py
@@ -2,6 +2,7 @@
 Unit tests for stem.descriptor.router_status_entry.
 """
 
+import collections
 import datetime
 import functools
 import unittest
@@ -27,12 +28,6 @@ from stem.descriptor.router_status_entry import (
   _base64_to_hex,
 )
 
-try:
-  # Added in 2.7
-  from collections import OrderedDict
-except ImportError:
-  from stem.util.ordereddict import OrderedDict
-
 ENTRY_WITHOUT_ED25519 = """\
 r seele AAoQ1DAR6kkoo19hBAX5K0QztNw m0ynPuwzSextzsiXYJYA0Hce+Cs 2015-08-23 00:26:35 73.15.150.172 9001 0
 s Running Stable Valid
@@ -258,7 +253,7 @@ class TestRouterStatusEntry(unittest.TestCase):
     Parse a router status entry with an IPv6 address.
     """
 
-    expected_protocols = OrderedDict((
+    expected_protocols = collections.OrderedDict((
       ('Cons', [1]),
       ('Desc', [1]),
       ('DirCache', [1]),
diff --git a/test/unit/descriptor/server_descriptor.py b/test/unit/descriptor/server_descriptor.py
index d87d51e9..3878c8af 100644
--- a/test/unit/descriptor/server_descriptor.py
+++ b/test/unit/descriptor/server_descriptor.py
@@ -2,6 +2,7 @@
 Unit tests for stem.descriptor.server_descriptor.
 """
 
+import collections
 import datetime
 import functools
 import hashlib
@@ -32,12 +33,6 @@ from test.unit.descriptor import (
 )
 
 try:
-  # Added in 2.7
-  from collections import OrderedDict
-except ImportError:
-  from stem.util.ordereddict import OrderedDict
-
-try:
   # added in python 3.3
   from unittest.mock import Mock, patch
 except ImportError:
@@ -288,7 +283,7 @@ Qlx9HNCqCY877ztFRC624ja2ql6A2hBcuoYMbkHjcQ4=
     exc_msg = 'Server descriptor lacks a fingerprint. This is an optional field, but required to make a router status entry.'
     self.assertRaisesWith(ValueError, exc_msg, desc_without_fingerprint.make_router_status_entry)
 
-    desc = RelayDescriptor.create(OrderedDict((
+    desc = RelayDescriptor.create(collections.OrderedDict((
       ('router', 'caerSidi 71.35.133.197 9001 0 0'),
       ('published', '2012-02-29 04:03:19'),
       ('fingerprint', '4F0C 867D F0EF 6816 0568 C826 838F 482C EA7C FE44'),
diff --git a/test/unit/directory/fallback.py b/test/unit/directory/fallback.py
index 06b4510d..00965187 100644
--- a/test/unit/directory/fallback.py
+++ b/test/unit/directory/fallback.py
@@ -2,6 +2,7 @@
 Unit tests for stem.directory.Fallback.
 """
 
+import collections
 import io
 import re
 import tempfile
@@ -12,12 +13,6 @@ import stem.directory
 import stem.util.conf
 
 try:
-  # added in python 2.7
-  from collections import OrderedDict
-except ImportError:
-  from stem.util.ordereddict import OrderedDict
-
-try:
   # added in python 3.3
   from unittest.mock import patch, Mock
 except ImportError:
@@ -58,7 +53,7 @@ URL: https:onionoo.torproject.orguptime?first_seen_days=30-&flag=V2Dir&type=rela
 /* ===== */
 """
 
-HEADER = OrderedDict((
+HEADER = collections.OrderedDict((
   ('type', 'fallback'),
   ('version', '2.0.0'),
   ('timestamp', '20170526090242'),
@@ -75,7 +70,7 @@ class TestFallback(unittest.TestCase):
       'nickname': 'rueckgrat',
       'has_extrainfo': True,
       'orport_v6': ('2a01:4f8:162:51e2::2', 9001),
-      'header': OrderedDict((
+      'header': collections.OrderedDict((
         ('type', 'fallback'),
         ('version', '2.0.0'),
         ('timestamp', '20170526090242'),
diff --git a/test/unit/manual.py b/test/unit/manual.py
index 72f847e5..b7a2de6f 100644
--- a/test/unit/manual.py
+++ b/test/unit/manual.py
@@ -2,6 +2,7 @@
 Unit testing for the stem.manual module.
 """
 
+import collections
 import io
 import os
 import sqlite3
@@ -25,12 +26,6 @@ try:
 except ImportError:
   from mock import Mock, patch
 
-try:
-  # added in python 2.7
-  from collections import OrderedDict
-except ImportError:
-  from stem.util.ordereddict import OrderedDict
-
 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')
@@ -59,7 +54,7 @@ EXPECTED_FILES = {
   '$HOME/.torrc': 'Fallback location for torrc, if @CONFDIR@/torrc is not found.',
 }
 
-EXPECTED_CONFIG_OPTIONS = OrderedDict()
+EXPECTED_CONFIG_OPTIONS = collections.OrderedDict()
 
 EXPECTED_CONFIG_OPTIONS['BandwidthRate'] = stem.manual.ConfigOption(
   name = 'BandwidthRate',
@@ -315,4 +310,4 @@ class TestManual(unittest.TestCase):
     self.assertEqual({}, manual.commandline_options)
     self.assertEqual({}, manual.signals)
     self.assertEqual({}, manual.files)
-    self.assertEqual(OrderedDict(), manual.config_options)
+    self.assertEqual(collections.OrderedDict(), manual.config_options)





More information about the tor-commits mailing list