[tor-commits] [arm/master] Using stem's enum util
atagar at torproject.org
atagar at torproject.org
Wed Jan 2 01:45:27 UTC 2013
commit ec41f9b795f03efbd29fec3cb6ea831faa40532b
Author: Damian Johnson <atagar at torproject.org>
Date: Wed Dec 19 08:23:03 2012 -0800
Using stem's enum util
Replacing our Enum class with stem's. This is the start of a general migration
to stem's utility classes, which unlike ours actually have tests (yay!).
---
src/cli/configPanel.py | 10 ++-
src/cli/connections/connEntry.py | 6 +-
src/cli/connections/connPanel.py | 18 +++---
src/cli/connections/countPopup.py | 4 +-
src/cli/connections/entries.py | 2 +-
src/cli/controller.py | 4 +-
src/cli/graphing/graphPanel.py | 6 +-
src/cli/logPanel.py | 22 ++++----
src/cli/menu/actions.py | 6 +-
src/cli/torrcPanel.py | 4 +-
src/test.py | 4 +-
src/util/__init__.py | 2 +-
src/util/conf.py | 2 +-
src/util/connections.py | 4 +-
src/util/enum.py | 116 -------------------------------------
src/util/log.py | 11 ++--
src/util/procTools.py | 4 +-
src/util/torConfig.py | 6 +-
src/util/torTools.py | 4 +-
src/util/uiTools.py | 4 +-
20 files changed, 73 insertions(+), 166 deletions(-)
diff --git a/src/cli/configPanel.py b/src/cli/configPanel.py
index a73f2a8..50b66b3 100644
--- a/src/cli/configPanel.py
+++ b/src/cli/configPanel.py
@@ -9,7 +9,9 @@ import threading
import cli.controller
import popups
-from util import conf, enum, panel, sysTools, torConfig, torTools, uiTools
+from util import conf, panel, sysTools, torConfig, torTools, uiTools
+
+from stem.util import enum
DEFAULT_CONFIG = {"features.config.selectionDetails.height": 6,
"features.config.prepopulateEditValues": True,
@@ -182,7 +184,7 @@ class ConfigPanel(panel.Panel):
"features.config.state.colWidth.option": 5,
"features.config.state.colWidth.value": 5})
- sortFields = Field.values()
+ sortFields = list(Field)
customOrdering = config.getIntCSV("features.config.order", None, 3, 0, len(sortFields))
if customOrdering:
@@ -300,9 +302,9 @@ class ConfigPanel(panel.Panel):
# set ordering for config options
titleLabel = "Config Option Ordering:"
- options = [FIELD_ATTR[field][0] for field in Field.values()]
+ options = [FIELD_ATTR[field][0] for field in Field]
oldSelection = [FIELD_ATTR[field][0] for field in self.sortOrdering]
- optionColors = dict([FIELD_ATTR[field] for field in Field.values()])
+ optionColors = dict([FIELD_ATTR[field] for field in Field])
results = popups.showSortDialog(titleLabel, options, oldSelection, optionColors)
if results:
diff --git a/src/cli/connections/connEntry.py b/src/cli/connections/connEntry.py
index 7650149..2f57b51 100644
--- a/src/cli/connections/connEntry.py
+++ b/src/cli/connections/connEntry.py
@@ -6,9 +6,11 @@ Connection panel entries related to actual connections to or from the system
import time
import curses
-from util import connections, enum, torTools, uiTools
+from util import connections, torTools, uiTools
from cli.connections import entries
+from stem.util import enum
+
# Connection Categories:
# Inbound Relay connection, coming to us.
# Outbound Relay connection, leaving us.
@@ -178,7 +180,7 @@ class ConnectionEntry(entries.ConnectionPanelEntry):
if myNickname == "UNKNOWN": return "z" * 20 # orders at the end
else: return myNickname.lower()
elif attr == entries.SortAttr.CATEGORY:
- return Category.indexOf(connLine.getType())
+ return Category.index_of(connLine.getType())
elif attr == entries.SortAttr.UPTIME:
return connLine.startTime
elif attr == entries.SortAttr.COUNTRY:
diff --git a/src/cli/connections/connPanel.py b/src/cli/connections/connPanel.py
index 632669c..50ba2e8 100644
--- a/src/cli/connections/connPanel.py
+++ b/src/cli/connections/connPanel.py
@@ -10,7 +10,9 @@ import threading
import cli.popups
from cli.connections import countPopup, descriptorPopup, entries, connEntry, circEntry
-from util import connections, enum, panel, torTools, uiTools
+from util import connections, panel, torTools, uiTools
+
+from stem.util import enum
DEFAULT_CONFIG = {"features.connection.resolveApps": True,
"features.connection.listingType": 0,
@@ -41,7 +43,7 @@ class ConnectionPanel(panel.Panel, threading.Thread):
if config:
config.update(self._config, {
- "features.connection.listingType": (0, len(Listing.values()) - 1),
+ "features.connection.listingType": (0, len(list(Listing)) - 1),
"features.connection.refreshRate": 1})
# defaults our listing selection to fingerprints if ip address
@@ -49,13 +51,13 @@ class ConnectionPanel(panel.Panel, threading.Thread):
if not self._config["features.connection.showIps"] and self._config["features.connection.listingType"] == 0:
self._config["features.connection.listingType"] = 2
- sortFields = entries.SortAttr.values()
+ sortFields = list(entries.SortAttr)
customOrdering = config.getIntCSV("features.connection.order", None, 3, 0, len(sortFields))
if customOrdering:
self._sortOrdering = [sortFields[i] for i in customOrdering]
- self._listingType = Listing.values()[self._config["features.connection.listingType"]]
+ self._listingType = list(Listing)[self._config["features.connection.listingType"]]
self._scroller = uiTools.Scroller(True)
self._title = "Connections:" # title line of the panel
self._entries = [] # last fetched display entries
@@ -205,7 +207,7 @@ class ConnectionPanel(panel.Panel, threading.Thread):
# set ordering for connection options
titleLabel = "Connection Ordering:"
- options = entries.SortAttr.values()
+ options = list(entries.SortAttr)
oldSelection = self._sortOrdering
optionColors = dict([(attr, entries.SORT_COLORS[attr]) for attr in options])
results = cli.popups.showSortDialog(titleLabel, options, oldSelection, optionColors)
@@ -228,7 +230,7 @@ class ConnectionPanel(panel.Panel, threading.Thread):
elif key == ord('u') or key == ord('U'):
# provides a menu to pick the connection resolver
title = "Resolver Util:"
- options = ["auto"] + connections.Resolver.values()
+ options = ["auto"] + list(connections.Resolver)
connResolver = connections.getResolver("tor")
currentOverwrite = connResolver.overwriteResolver
@@ -244,7 +246,7 @@ class ConnectionPanel(panel.Panel, threading.Thread):
elif key == ord('l') or key == ord('L'):
# provides a menu to pick the primary information we list connections by
title = "List By:"
- options = entries.ListingType.values()
+ options = list(entries.ListingType)
# dropping the HOSTNAME listing type until we support displaying that content
options.remove(cli.connections.entries.ListingType.HOSTNAME)
@@ -489,7 +491,7 @@ class ConnectionPanel(panel.Panel, threading.Thread):
# type cache for all of the connections (in case its changed since last
# fetched).
- categoryTypes = connEntry.Category.values()
+ categoryTypes = list(connEntry.Category)
typeCounts = dict((type, 0) for type in categoryTypes)
for entry in newEntries:
if isinstance(entry, connEntry.ConnectionEntry):
diff --git a/src/cli/connections/countPopup.py b/src/cli/connections/countPopup.py
index 7904519..7ec6e60 100644
--- a/src/cli/connections/countPopup.py
+++ b/src/cli/connections/countPopup.py
@@ -8,7 +8,9 @@ import operator
import cli.controller
import cli.popups
-from util import connections, enum, log, uiTools
+from util import connections, log, uiTools
+
+from stem.util import enum
CountType = enum.Enum("CLIENT_LOCALE", "EXIT_PORT")
EXIT_USAGE_WIDTH = 15
diff --git a/src/cli/connections/entries.py b/src/cli/connections/entries.py
index f832b6a..d5085aa 100644
--- a/src/cli/connections/entries.py
+++ b/src/cli/connections/entries.py
@@ -4,7 +4,7 @@ entry itself (ie, Tor connection, client circuit, etc) and the lines it
consists of in the listing.
"""
-from util import enum
+from stem.util import enum
# attributes we can list entries by
ListingType = enum.Enum(("IP_ADDRESS", "IP Address"), "HOSTNAME", "FINGERPRINT", "NICKNAME")
diff --git a/src/cli/controller.py b/src/cli/controller.py
index 478bc02..af3fdac 100644
--- a/src/cli/controller.py
+++ b/src/cli/controller.py
@@ -22,7 +22,9 @@ import cli.connections.connPanel
from stem.control import Controller
-from util import connections, conf, enum, hostnames, log, panel, sysTools, torConfig, torTools
+from util import connections, conf, hostnames, log, panel, sysTools, torConfig, torTools
+
+from stem.util import enum
ARM_CONTROLLER = None
diff --git a/src/cli/graphing/graphPanel.py b/src/cli/graphing/graphPanel.py
index d03d1bd..16efe8f 100644
--- a/src/cli/graphing/graphPanel.py
+++ b/src/cli/graphing/graphPanel.py
@@ -24,7 +24,9 @@ import cli.controller
import stem.control
-from util import enum, panel, torTools, uiTools
+from util import panel, torTools, uiTools
+
+from stem.util import enum
# time intervals at which graphs can be updated
UPDATE_INTERVALS = [("each second", 1), ("5 seconds", 5), ("30 seconds", 30),
@@ -232,7 +234,7 @@ class GraphPanel(panel.Panel):
def __init__(self, stdscr):
panel.Panel.__init__(self, stdscr, "graph", 0)
self.updateInterval = CONFIG["features.graph.interval"]
- self.bounds = Bounds.values()[CONFIG["features.graph.bound"]]
+ self.bounds = list(Bounds)[CONFIG["features.graph.bound"]]
self.graphHeight = CONFIG["features.graph.height"]
self.currentDisplay = None # label of the stats currently being displayed
self.stats = {} # available stats (mappings of label -> instance)
diff --git a/src/cli/logPanel.py b/src/cli/logPanel.py
index b866c62..d03973d 100644
--- a/src/cli/logPanel.py
+++ b/src/cli/logPanel.py
@@ -120,9 +120,9 @@ def expandEvents(eventAbbr):
for flag in eventAbbr:
if flag == "A":
- armRunlevels = ["ARM_" + runlevel for runlevel in log.Runlevel.values()]
- stemRunlevels = ["STEM_" + runlevel for runlevel in log.Runlevel.values()]
- expandedEvents = set(TOR_EVENT_TYPES.values() + armRunlevels + stemRunlevels + ["UNKNOWN"])
+ armRunlevels = ["ARM_" + runlevel for runlevel in log.Runlevel]
+ stemRunlevels = ["STEM_" + runlevel for runlevel in log.Runlevel]
+ expandedEvents = set(list(TOR_EVENT_TYPES) + armRunlevels + stemRunlevels + ["UNKNOWN"])
break
elif flag == "X":
expandedEvents = set()
@@ -136,11 +136,11 @@ def expandEvents(eventAbbr):
elif flag in "E5": runlevelIndex = 4
if flag in "DINWE":
- runlevelSet = [runlevel for runlevel in log.Runlevel.values()[runlevelIndex:]]
+ runlevelSet = [runlevel for runlevel in list(log.Runlevel)[runlevelIndex:]]
expandedEvents = expandedEvents.union(set(runlevelSet))
elif flag in "12345":
for prefix in ("ARM_", "STEM_"):
- runlevelSet = [prefix + runlevel for runlevel in log.Runlevel.values()[runlevelIndex:]]
+ runlevelSet = [prefix + runlevel for runlevel in list(log.Runlevel)[runlevelIndex:]]
expandedEvents = expandedEvents.union(set(runlevelSet))
elif flag == "U":
expandedEvents.add("UNKNOWN")
@@ -219,7 +219,7 @@ def getLogFileEntries(runlevels, readLimit = None, addLimit = None, config = Non
# if the runlevels argument is a superset of the log file then we can
# limit the read contents to the addLimit
- runlevels = log.Runlevel.values()
+ runlevels = list(log.Runlevel)
loggingTypes = loggingTypes.upper()
if addLimit and (not readLimit or readLimit > addLimit):
if "-" in loggingTypes:
@@ -550,7 +550,7 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler):
# adds arm listener and prepopulates log with past tor/arm events
log.LOG_LOCK.acquire()
try:
- log.addListeners(log.Runlevel.values(), self._registerArmEvent)
+ log.addListeners(list(log.Runlevel), self._registerArmEvent)
self.reprepopulateEvents()
finally:
log.LOG_LOCK.release()
@@ -597,16 +597,16 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler):
# fetches past tor events from log file, if available
torEventBacklog = []
if self._config["features.log.prepopulate"]:
- setRunlevels = list(set.intersection(set(self.loggedEvents), set(log.Runlevel.values())))
+ setRunlevels = list(set.intersection(set(self.loggedEvents), set(list(log.Runlevel))))
readLimit = self._config["features.log.prepopulateReadLimit"]
addLimit = self._config["cache.logPanel.size"]
torEventBacklog = getLogFileEntries(setRunlevels, readLimit, addLimit, self._config)
# gets the set of arm events we're logging
setRunlevels = []
- armRunlevels = log.Runlevel.values()
+ armRunlevels = list(log.Runlevel)
for i in range(len(armRunlevels)):
- if "ARM_" + log.Runlevel.values()[i] in self.loggedEvents:
+ if "ARM_" + list(log.Runlevel)[i] in self.loggedEvents:
setRunlevels.append(armRunlevels[i])
armEventBacklog = []
@@ -1213,7 +1213,7 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler):
runlevelRanges = [] # tuple of type, startLevel, endLevel for ranges to be consensed
# reverses runlevels and types so they're appended in the right order
- reversedRunlevels = log.Runlevel.values()
+ reversedRunlevels = list(log.Runlevel)
reversedRunlevels.reverse()
for prefix in ("STEM_", "ARM_", ""):
# blank ending runlevel forces the break condition to be reached at the end
diff --git a/src/cli/menu/actions.py b/src/cli/menu/actions.py
index 30dff69..b1371c4 100644
--- a/src/cli/menu/actions.py
+++ b/src/cli/menu/actions.py
@@ -157,7 +157,7 @@ def makeGraphMenu(graphPanel):
boundsMenu = cli.menu.item.Submenu("Bounds")
boundsGroup = cli.menu.item.SelectionGroup(graphPanel.setBoundsType, graphPanel.getBoundsType())
- for boundsType in cli.graphing.graphPanel.Bounds.values():
+ for boundsType in cli.graphing.graphPanel.Bounds:
boundsMenu.add(cli.menu.item.SelectionMenuItem(boundsType, boundsGroup, boundsType))
graphMenu.add(boundsMenu)
@@ -219,7 +219,7 @@ def makeConnectionsMenu(connPanel):
# listing options
listingGroup = cli.menu.item.SelectionGroup(connPanel.setListingType, connPanel.getListingType())
- listingOptions = cli.connections.entries.ListingType.values()
+ listingOptions = list(cli.connections.entries.ListingType)
listingOptions.remove(cli.connections.entries.ListingType.HOSTNAME)
for option in listingOptions:
@@ -235,7 +235,7 @@ def makeConnectionsMenu(connPanel):
resolverMenu.add(cli.menu.item.SelectionMenuItem("auto", resolverGroup, None))
- for option in connections.Resolver.values():
+ for option in connections.Resolver:
resolverMenu.add(cli.menu.item.SelectionMenuItem(option, resolverGroup, option))
connectionsMenu.add(resolverMenu)
diff --git a/src/cli/torrcPanel.py b/src/cli/torrcPanel.py
index c1bb3f9..983768f 100644
--- a/src/cli/torrcPanel.py
+++ b/src/cli/torrcPanel.py
@@ -8,7 +8,9 @@ import threading
import popups
-from util import conf, enum, panel, torConfig, torTools, uiTools
+from util import conf, panel, torConfig, torTools, uiTools
+
+from stem.util import enum
DEFAULT_CONFIG = {"features.config.file.showScrollbars": True,
"features.config.file.maxLinesPerEntry": 8}
diff --git a/src/test.py b/src/test.py
index 7129120..10eddb0 100644
--- a/src/test.py
+++ b/src/test.py
@@ -68,7 +68,7 @@ while True:
# provide the selection options
printDivider()
print("Select a resolver:")
- availableResolvers = connections.Resolver.values()
+ availableResolvers = list(connections.Resolver)
for i in range(len(availableResolvers)):
print(" %i. %s" % (i, availableResolvers[i]))
print(" q. Go back to the main menu")
@@ -80,7 +80,7 @@ while True:
if userSelection.isdigit() and int(userSelection) in range(0, 7):
try:
- resolver = connections.Resolver.values()[int(userSelection)]
+ resolver = list(connections.Resolver)[int(userSelection)]
startTime = time.time()
print(connections.getResolverCommand(resolver, "tor", conn.getMyPid()))
diff --git a/src/util/__init__.py b/src/util/__init__.py
index 5afde12..e4e22c1 100644
--- a/src/util/__init__.py
+++ b/src/util/__init__.py
@@ -4,5 +4,5 @@ application's status, making cross platform system calls, parsing tor data,
and safely working with curses (hiding some of the gory details).
"""
-__all__ = ["conf", "connections", "enum", "hostnames", "log", "panel", "procTools", "procName", "sysTools", "textInput", "torConfig", "torTools", "uiTools"]
+__all__ = ["conf", "connections", "hostnames", "log", "panel", "procTools", "procName", "sysTools", "textInput", "torConfig", "torTools", "uiTools"]
diff --git a/src/util/conf.py b/src/util/conf.py
index bfbf468..a8ca6de 100644
--- a/src/util/conf.py
+++ b/src/util/conf.py
@@ -111,7 +111,7 @@ class Config():
if key.startswith("log."):
if val.upper() == "NONE": val = None
- elif val.upper() in log.Runlevel.values(): val = val.upper()
+ elif val.upper() in list(log.Runlevel): val = val.upper()
else:
msg = "Config entry '%s' is expected to be a runlevel" % key
if default != None: msg += ", defaulting to '%s'" % default
diff --git a/src/util/connections.py b/src/util/connections.py
index 250b113..de128c2 100644
--- a/src/util/connections.py
+++ b/src/util/connections.py
@@ -21,7 +21,9 @@ import os
import time
import threading
-from util import enum, log, procTools, sysTools
+from util import log, procTools, sysTools
+
+from stem.util import enum
# enums for connection resolution utilities
Resolver = enum.Enum(("PROC", "proc"),
diff --git a/src/util/enum.py b/src/util/enum.py
deleted file mode 100644
index bdba6b4..0000000
--- a/src/util/enum.py
+++ /dev/null
@@ -1,116 +0,0 @@
-"""
-Basic enumeration, providing ordered types for collections. These can be
-constructed as simple type listings, ie:
->>> insects = Enum("ANT", "WASP", "LADYBUG", "FIREFLY")
->>> insects.ANT
-'Ant'
->>> insects.values()
-['Ant', 'Wasp', 'Ladybug', 'Firefly']
-
-with overwritten string counterparts:
->>> pets = Enum(("DOG", "Skippy"), "CAT", ("FISH", "Nemo"))
->>> pets.DOG
-'Skippy'
->>> pets.CAT
-'Cat'
-
-or with entirely custom string components as an unordered enum with:
->>> pets = LEnum(DOG="Skippy", CAT="Kitty", FISH="Nemo")
->>> pets.CAT
-'Kitty'
-"""
-
-def toCamelCase(label):
- """
- Converts the given string to camel case, ie:
- >>> toCamelCase("I_LIKE_PEPPERJACK!")
- 'I Like Pepperjack!'
-
- Arguments:
- label - input string to be converted
- """
-
- words = []
- for entry in label.split("_"):
- if len(entry) == 0: words.append("")
- elif len(entry) == 1: words.append(entry.upper())
- else: words.append(entry[0].upper() + entry[1:].lower())
-
- return " ".join(words)
-
-class Enum:
- """
- Basic enumeration.
- """
-
- def __init__(self, *args):
- self.orderedValues = []
-
- for entry in args:
- if isinstance(entry, str):
- key, val = entry, toCamelCase(entry)
- elif isinstance(entry, tuple) and len(entry) == 2:
- key, val = entry
- else: raise ValueError("Unrecognized input: %s" % args)
-
- self.__dict__[key] = val
- self.orderedValues.append(val)
-
- def values(self):
- """
- Provides an ordered listing of the enumerations in this set.
- """
-
- return list(self.orderedValues)
-
- def indexOf(self, value):
- """
- Provides the index of the given value in the collection. This raises a
- ValueError if no such element exists.
-
- Arguments:
- value - entry to be looked up
- """
-
- return self.orderedValues.index(value)
-
- def next(self, value):
- """
- Provides the next enumeration after the given value, raising a ValueError
- if no such enum exists.
-
- Arguments:
- value - enumeration for which to get the next entry
- """
-
- if not value in self.orderedValues:
- raise ValueError("No such enumeration exists: %s (options: %s)" % (value, ", ".join(self.orderedValues)))
-
- nextIndex = (self.orderedValues.index(value) + 1) % len(self.orderedValues)
- return self.orderedValues[nextIndex]
-
- def previous(self, value):
- """
- Provides the previous enumeration before the given value, raising a
- ValueError if no such enum exists.
-
- Arguments:
- value - enumeration for which to get the previous entry
- """
-
- if not value in self.orderedValues:
- raise ValueError("No such enumeration exists: %s (options: %s)" % (value, ", ".join(self.orderedValues)))
-
- prevIndex = (self.orderedValues.index(value) - 1) % len(self.orderedValues)
- return self.orderedValues[prevIndex]
-
-class LEnum(Enum):
- """
- Enumeration that accepts custom string mappings.
- """
-
- def __init__(self, **args):
- Enum.__init__(self)
- self.__dict__.update(args)
- self.orderedValues = sorted(args.values())
-
diff --git a/src/util/log.py b/src/util/log.py
index e4bd231..56a6636 100644
--- a/src/util/log.py
+++ b/src/util/log.py
@@ -11,23 +11,22 @@ import time
from sys import maxint
from threading import RLock
-from util import enum
+from stem.util import enum
# Logging runlevels. These are *very* commonly used so including shorter
# aliases (so they can be referenced as log.DEBUG, log.WARN, etc).
-Runlevel = enum.Enum(("DEBUG", "DEBUG"), ("INFO", "INFO"), ("NOTICE", "NOTICE"),
- ("WARN", "WARN"), ("ERR", "ERR"))
-DEBUG, INFO, NOTICE, WARN, ERR = Runlevel.values()
+Runlevel = enum.UppercaseEnum("DEBUG", "INFO", "NOTICE", "WARN", "ERR")
+DEBUG, INFO, NOTICE, WARN, ERR = list(Runlevel)
# provides thread safety for logging operations
LOG_LOCK = RLock()
# chronologically ordered records of events for each runlevel, stored as tuples
# consisting of: (time, message)
-_backlog = dict([(level, []) for level in Runlevel.values()])
+_backlog = dict([(level, []) for level in Runlevel])
# mapping of runlevels to the listeners interested in receiving events from it
-_listeners = dict([(level, []) for level in Runlevel.values()])
+_listeners = dict([(level, []) for level in Runlevel])
CONFIG = {"cache.armLog.size": 1000,
"cache.armLog.trimSize": 200}
diff --git a/src/util/procTools.py b/src/util/procTools.py
index 39b5407..835814e 100644
--- a/src/util/procTools.py
+++ b/src/util/procTools.py
@@ -20,7 +20,9 @@ import time
import socket
import base64
-from util import enum, log
+from util import log
+
+from stem.util import enum
# cached system values
SYS_START_TIME, SYS_PHYSICAL_MEMORY = None, None
diff --git a/src/util/torConfig.py b/src/util/torConfig.py
index 0f6452d..5566e9d 100644
--- a/src/util/torConfig.py
+++ b/src/util/torConfig.py
@@ -9,7 +9,9 @@ import threading
import stem.version
-from util import enum, log, sysTools, torTools, uiTools
+from util import log, sysTools, torTools, uiTools
+
+from stem.util import enum
CONFIG = {"features.torrc.validate": True,
"config.important": [],
@@ -147,7 +149,7 @@ def loadOptionDescriptions(loadPath = None, checkVersion = True):
while inputFileContents:
# gets category enum, failing if it doesn't exist
category = inputFileContents.pop(0).rstrip()
- if not category in Category.values():
+ if not category in Category:
baseMsg = "invalid category in input file: '%s'"
raise IOError(baseMsg % category)
diff --git a/src/util/torTools.py b/src/util/torTools.py
index a5add1a..7aea8fa 100644
--- a/src/util/torTools.py
+++ b/src/util/torTools.py
@@ -16,7 +16,9 @@ import stem
import stem.control
import stem.descriptor
-from util import connections, enum, log, procTools, sysTools, uiTools
+from util import connections, log, procTools, sysTools, uiTools
+
+from stem.util import enum
# enums for tor's controller state:
# INIT - attached to a new controller
diff --git a/src/util/uiTools.py b/src/util/uiTools.py
index bc1fefe..c1f1a86 100644
--- a/src/util/uiTools.py
+++ b/src/util/uiTools.py
@@ -10,7 +10,9 @@ import sys
import curses
from curses.ascii import isprint
-from util import enum, log
+from util import log
+
+from stem.util import enum
# colors curses can handle
COLOR_LIST = {"red": curses.COLOR_RED, "green": curses.COLOR_GREEN,
More information about the tor-commits
mailing list