python: Fix object comparisons in Python 3.
authorRussell Bryant <russell@ovn.org>
Thu, 17 Dec 2015 17:55:43 +0000 (12:55 -0500)
committerRussell Bryant <russell@ovn.org>
Tue, 2 Feb 2016 21:42:32 +0000 (16:42 -0500)
Python 3 no longer supports __cmp__.  Instead, we have to implement the
"rich comparison" operators.  We implement __eq__ and __lt__ and use
functools.total_ordering to implement the rest.

In one case, no __cmp__ method was provided and instead relied on the
default behavior provided in Python 2.  We have to implement the
comparisons explicitly for Python 3.

Signed-off-by: Russell Bryant <russell@ovn.org>
Acked-by: Ben Pfaff <blp@ovn.org>
python/ovs/db/data.py
python/ovs/db/idl.py

index 7a2fbbc..42e78fb 100644 (file)
@@ -12,6 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import functools
 import re
 import uuid
 
@@ -64,6 +65,7 @@ def returnUnchanged(x):
     return x
 
 
+@functools.total_ordering
 class Atom(object):
     def __init__(self, type_, value=None):
         self.type = type_
@@ -72,6 +74,16 @@ class Atom(object):
         else:
             self.value = type_.default_atom()
 
+    def __eq__(self, other):
+        if not isinstance(other, Atom) or self.type != other.type:
+            return NotImplemented
+        return True if self.value == other.value else False
+
+    def __lt__(self, other):
+        if not isinstance(other, Atom) or self.type != other.type:
+            return NotImplemented
+        return True if self.value < other.value else False
+
     def __cmp__(self, other):
         if not isinstance(other, Atom) or self.type != other.type:
             return NotImplemented
@@ -256,11 +268,22 @@ class Atom(object):
         return Atom(t, x)
 
 
+@functools.total_ordering
 class Datum(object):
     def __init__(self, type_, values={}):
         self.type = type_
         self.values = values
 
+    def __eq__(self, other):
+        if not isinstance(other, Datum):
+            return NotImplemented
+        return True if self.values == other.values else False
+
+    def __lt__(self, other):
+        if not isinstance(other, Datum):
+            return NotImplemented
+        return True if self.values < other.values else False
+
     def __cmp__(self, other):
         if not isinstance(other, Datum):
             return NotImplemented
index 7eaeda7..e69d35e 100644 (file)
@@ -12,6 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import functools
 import uuid
 
 import six
@@ -504,6 +505,7 @@ def _row_to_uuid(value):
         return value
 
 
+@functools.total_ordering
 class Row(object):
     """A row within an IDL.
 
@@ -572,6 +574,19 @@ class Row(object):
         # in the dictionary are all None.
         self.__dict__["_prereqs"] = {}
 
+    def __lt__(self, other):
+        if not isinstance(other, Row):
+            return NotImplemented
+        return bool(self.__dict__['uuid'] < other.__dict__['uuid'])
+
+    def __eq__(self, other):
+        if not isinstance(other, Row):
+            return NotImplemented
+        return bool(self.__dict__['uuid'] == other.__dict__['uuid'])
+
+    def __hash__(self):
+        return int(self.__dict__['uuid'])
+
     def __getattr__(self, column_name):
         assert self._changes is not None