[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Using rich comparison functions
commit 5914ae523eb393383a120cd24c12c508e0ffaeac
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Tue Jan 22 09:27:45 2013 -0800
Using rich comparison functions
Python 3.x drops support for __cmp__, requiring that users opt for rich
comparison methods instead...
http://python3porting.com/problems.html#unorderable-types-cmp-and-cmp
======================================================================
ERROR: test_event_listening
----------------------------------------------------------------------
Traceback:
File "/home/atagar/Desktop/stem/test/data/python3/test/unit/control/controller.py", line 285, in test_event_listening
self.assertRaises(InvalidRequest, self.controller.add_event_listener, mocking.no_op(), EventType.BW)
File "/usr/lib/python3.2/unittest/case.py", line 574, in assertRaises
callableObj(*args, **kwargs)
File "/home/atagar/Desktop/stem/test/data/python3/stem/control.py", line 1438, in add_event_listener
if not self.get_version().meets_requirements(event_version):
File "/home/atagar/Desktop/stem/test/data/python3/stem/version.py", line 175, in meets_requirements
return self >= requirements
TypeError: unorderable types: Version() >= Version()
This change uncovered a couple bugs where events failed to strip off the
trailing 'OK'. I'm not entirely sure why the previous comparisons didn't catch
this, but oh well - fixed now.
---
stem/descriptor/networkstatus.py | 66 ++++++++++++++++++++++++--------
stem/descriptor/router_status_entry.py | 60 +++++++++++++++++++++++------
stem/descriptor/server_descriptor.py | 30 +++++++++++---
stem/response/events.py | 4 +-
stem/version.py | 30 +++++++-------
5 files changed, 139 insertions(+), 51 deletions(-)
diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py
index c1bbadf..511f5b0 100644
--- a/stem/descriptor/networkstatus.py
+++ b/stem/descriptor/networkstatus.py
@@ -528,11 +528,20 @@ class NetworkStatusDocumentV3(NetworkStatusDocument):
return self._header.meets_consensus_method(method)
- def __cmp__(self, other):
+ def _compare(self, other, method):
if not isinstance(other, NetworkStatusDocumentV3):
- return 1
+ return False
- return str(self) > str(other)
+ return method(str(self).strip(), str(other).strip())
+
+ def __eq__(self, other):
+ return self._compare(other, lambda s, o: s == o)
+
+ def __lt__(self, other):
+ return self._compare(other, lambda s, o: s < o)
+
+ def __le__(self, other):
+ return self._compare(other, lambda s, o: s <= o)
class _DocumentHeader(object):
@@ -1124,11 +1133,20 @@ class DirectoryAuthority(stem.descriptor.Descriptor):
return self._unrecognized_lines
- def __cmp__(self, other):
+ def _compare(self, other, method):
if not isinstance(other, DirectoryAuthority):
- return 1
+ return False
+
+ return method(str(self).strip(), str(other).strip())
+
+ def __eq__(self, other):
+ return self._compare(other, lambda s, o: s == o)
+
+ def __lt__(self, other):
+ return self._compare(other, lambda s, o: s < o)
- return str(self) > str(other)
+ def __le__(self, other):
+ return self._compare(other, lambda s, o: s <= o)
class KeyCertificate(stem.descriptor.Descriptor):
@@ -1285,11 +1303,20 @@ class KeyCertificate(stem.descriptor.Descriptor):
return self._unrecognized_lines
- def __cmp__(self, other):
+ def _compare(self, other, method):
if not isinstance(other, KeyCertificate):
- return 1
+ return False
- return str(self) > str(other)
+ return method(str(self).strip(), str(other).strip())
+
+ def __eq__(self, other):
+ return self._compare(other, lambda s, o: s == o)
+
+ def __lt__(self, other):
+ return self._compare(other, lambda s, o: s < o)
+
+ def __le__(self, other):
+ return self._compare(other, lambda s, o: s <= o)
class DocumentSignature(object):
@@ -1321,17 +1348,24 @@ class DocumentSignature(object):
self.key_digest = key_digest
self.signature = signature
- def __cmp__(self, other):
+ def _compare(self, other, method):
if not isinstance(other, DocumentSignature):
- return 1
+ return False
for attr in ("identity", "key_digest", "signature"):
- if getattr(self, attr) > getattr(other, attr):
- return 1
- elif getattr(self, attr) < getattr(other, attr):
- return -1
+ if getattr(self, attr) != getattr(other, attr):
+ return method(getattr(self, attr), getattr(other, attr))
+
+ return method(True, True) # we're equal
+
+ def __eq__(self, other):
+ return self._compare(other, lambda s, o: s == o)
+
+ def __lt__(self, other):
+ return self._compare(other, lambda s, o: s < o)
- return 0
+ def __le__(self, other):
+ return self._compare(other, lambda s, o: s <= o)
class BridgeNetworkStatusDocument(NetworkStatusDocument):
diff --git a/stem/descriptor/router_status_entry.py b/stem/descriptor/router_status_entry.py
index a19f17f..9af2f44 100644
--- a/stem/descriptor/router_status_entry.py
+++ b/stem/descriptor/router_status_entry.py
@@ -222,11 +222,20 @@ class RouterStatusEntry(stem.descriptor.Descriptor):
return list(self._unrecognized_lines)
- def __cmp__(self, other):
+ def _compare(self, other, method):
if not isinstance(other, RouterStatusEntry):
- return 1
+ return False
- return str(self) > str(other)
+ return method(str(self).strip(), str(other).strip())
+
+ def __eq__(self, other):
+ return self._compare(other, lambda s, o: s == o)
+
+ def __lt__(self, other):
+ return self._compare(other, lambda s, o: s < o)
+
+ def __le__(self, other):
+ return self._compare(other, lambda s, o: s <= o)
class RouterStatusEntryV2(RouterStatusEntry):
@@ -266,11 +275,20 @@ class RouterStatusEntryV2(RouterStatusEntry):
def _single_fields(self):
return ('r', 's', 'v')
- def __cmp__(self, other):
+ def _compare(self, other, method):
if not isinstance(other, RouterStatusEntryV2):
- return 1
+ return False
+
+ return method(str(self).strip(), str(other).strip())
+
+ def __eq__(self, other):
+ return self._compare(other, lambda s, o: s == o)
+
+ def __lt__(self, other):
+ return self._compare(other, lambda s, o: s < o)
- return str(self) > str(other)
+ def __le__(self, other):
+ return self._compare(other, lambda s, o: s <= o)
class RouterStatusEntryV3(RouterStatusEntry):
@@ -348,11 +366,20 @@ class RouterStatusEntryV3(RouterStatusEntry):
def _single_fields(self):
return ('r', 's', 'v', 'w', 'p')
- def __cmp__(self, other):
+ def _compare(self, other, method):
if not isinstance(other, RouterStatusEntryV3):
- return 1
+ return False
- return str(self) > str(other)
+ return method(str(self).strip(), str(other).strip())
+
+ def __eq__(self, other):
+ return self._compare(other, lambda s, o: s == o)
+
+ def __lt__(self, other):
+ return self._compare(other, lambda s, o: s < o)
+
+ def __le__(self, other):
+ return self._compare(other, lambda s, o: s <= o)
class RouterStatusEntryMicroV3(RouterStatusEntry):
@@ -410,11 +437,20 @@ class RouterStatusEntryMicroV3(RouterStatusEntry):
def _single_fields(self):
return ('r', 's', 'v', 'w', 'm')
- def __cmp__(self, other):
+ def _compare(self, other, method):
if not isinstance(other, RouterStatusEntryMicroV3):
- return 1
+ return False
+
+ return method(str(self).strip(), str(other).strip())
+
+ def __eq__(self, other):
+ return self._compare(other, lambda s, o: s == o)
+
+ def __lt__(self, other):
+ return self._compare(other, lambda s, o: s < o)
- return str(self) > str(other)
+ def __le__(self, other):
+ return self._compare(other, lambda s, o: s <= o)
def _parse_r_line(desc, value, validate, include_digest = True):
diff --git a/stem/descriptor/server_descriptor.py b/stem/descriptor/server_descriptor.py
index a4548bf..38781bd 100644
--- a/stem/descriptor/server_descriptor.py
+++ b/stem/descriptor/server_descriptor.py
@@ -793,11 +793,20 @@ class RelayDescriptor(ServerDescriptor):
ServerDescriptor._parse(self, entries, validate)
- def __cmp__(self, other):
+ def _compare(self, other, method):
if not isinstance(other, RelayDescriptor):
- return 1
+ return False
- return str(self).strip() > str(other).strip()
+ return method(str(self).strip(), str(other).strip())
+
+ def __eq__(self, other):
+ return self._compare(other, lambda s, o: s == o)
+
+ def __lt__(self, other):
+ return self._compare(other, lambda s, o: s < o)
+
+ def __le__(self, other):
+ return self._compare(other, lambda s, o: s <= o)
@staticmethod
def _get_key_bytes(key_string):
@@ -918,8 +927,17 @@ class BridgeDescriptor(ServerDescriptor):
def _last_keyword(self):
return None
- def __cmp__(self, other):
+ def _compare(self, other, method):
if not isinstance(other, BridgeDescriptor):
- return 1
+ return False
+
+ return method(str(self).strip(), str(other).strip())
+
+ def __eq__(self, other):
+ return self._compare(other, lambda s, o: s == o)
+
+ def __lt__(self, other):
+ return self._compare(other, lambda s, o: s < o)
- return str(self).strip() > str(other).strip()
+ def __le__(self, other):
+ return self._compare(other, lambda s, o: s <= o)
diff --git a/stem/response/events.py b/stem/response/events.py
index 563b685..486e448 100644
--- a/stem/response/events.py
+++ b/stem/response/events.py
@@ -564,7 +564,7 @@ class NetworkStatusEvent(Event):
_VERSION_ADDED = stem.version.Requirement.EVENT_NS
def _parse(self):
- content = str(self).lstrip("NS\n")
+ content = str(self).lstrip("NS\n").rstrip("\nOK")
self.desc = list(stem.descriptor.router_status_entry._parse_file(
StringIO.StringIO(content),
@@ -589,7 +589,7 @@ class NewConsensusEvent(Event):
_VERSION_ADDED = stem.version.Requirement.EVENT_NEWCONSENSUS
def _parse(self):
- content = str(self).lstrip("NEWCONSENSUS\n")
+ content = str(self).lstrip("NEWCONSENSUS\n").rstrip("\nOK")
self.desc = list(stem.descriptor.router_status_entry._parse_file(
StringIO.StringIO(content),
diff --git a/stem/version.py b/stem/version.py
index 47b8393..46ed394 100644
--- a/stem/version.py
+++ b/stem/version.py
@@ -18,9 +18,7 @@ easily parsed and compared, for instance...
get_system_tor_version - gets the version of our system's tor installation
Version - Tor versioning information
- |- meets_requirements - checks if this version meets the given requirements
- |- __str__ - string representation
- +- __cmp__ - compares with another Version
+ +- meets_requirements - checks if this version meets the given requirements
VersionRequirements - Series of version requirements
|- greater_than - adds rule that matches if we're greater than a version
@@ -187,22 +185,20 @@ class Version(object):
return self.version_str
- def __cmp__(self, other):
+ def _compare(self, other, method):
"""
Compares version ordering according to the spec.
"""
if not isinstance(other, Version):
- return 1 # this is also used for equality checks
+ return False
for attr in ("major", "minor", "micro", "patch"):
my_version = max(0, self.__dict__[attr])
other_version = max(0, other.__dict__[attr])
- if my_version > other_version:
- return 1
- elif my_version < other_version:
- return -1
+ if my_version != other_version:
+ return method(my_version, other_version)
# According to the version spec...
#
@@ -212,12 +208,16 @@ class Version(object):
my_status = self.status if self.status else ""
other_status = other.status if other.status else ""
- if my_status > other_status:
- return 1
- elif my_status < other_status:
- return -1
- else:
- return 0
+ return method(my_status, other_status)
+
+ def __eq__(self, other):
+ return self._compare(other, lambda s, o: s == o)
+
+ def __lt__(self, other):
+ return self._compare(other, lambda s, o: s < o)
+
+ def __le__(self, other):
+ return self._compare(other, lambda s, o: s <= o)
class VersionRequirements(object):
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits