Full rich comparison operators 1.2
authorSergey Matveev <stargrave@stargrave.org>
Tue, 3 Oct 2017 11:34:58 +0000 (14:34 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Tue, 3 Oct 2017 11:45:58 +0000 (14:45 +0300)
It is required for Py27, where __ne__ != not(__eq__).

VERSION
pyderasn.py
tests/test_pyderasn.py

diff --git a/VERSION b/VERSION
index 9459d4ba2a0d3cc475f89ed03a13a1517c04798e..5625e59da8873d8077c1fb0feb605078b34b640e 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.1
+1.2
index 5c311e09c11d2c39eed450a0d2f768bd195f1bea..0c2c2ee44d1fff5f4b664427124f8f0d41caaa81 100755 (executable)
@@ -735,6 +735,24 @@ class Obj(object):
     def __str__(self):  # pragma: no cover
         return self.__bytes__() if PY2 else self.__unicode__()
 
+    def __eq__(self, their):  # pragma: no cover
+        raise NotImplementedError()
+
+    def __ne__(self, their):
+        return not(self == their)
+
+    def __lt__(self, their):  # pragma: no cover
+        raise NotImplementedError()
+
+    def __gt__(self, their):  # pragma: no cover
+        return not(self < their)
+
+    def __le__(self, their):  # pragma: no cover
+        return (self == their) or (self < their)
+
+    def __ge__(self, their):  # pragma: no cover
+        return (self == their) or (self > their)
+
     def _encode(self):  # pragma: no cover
         raise NotImplementedError()
 
@@ -1327,10 +1345,7 @@ class Integer(Obj):
         )
 
     def __lt__(self, their):
-        return self._value < their
-
-    def __gt__(self, their):
-        return self._value > their
+        return self._value < their._value
 
     @property
     def named(self):
@@ -1946,6 +1961,9 @@ class OctetString(Obj):
             self._expl == their._expl
         )
 
+    def __lt__(self, their):
+        return self._value < their._value
+
     def __call__(
             self,
             value=None,
@@ -2313,10 +2331,7 @@ class ObjectIdentifier(Obj):
         )
 
     def __lt__(self, their):
-        return self._value < their
-
-    def __gt__(self, their):
-        return self._value > their
+        return self._value < their._value
 
     def __call__(
             self,
index 0be393ed20841fc480345332e1864a6788ac9720..58ecbdb52d3a132cdb0edae0d6085155eaac0cfc 100644 (file)
@@ -372,10 +372,12 @@ class TestBoolean(CommonMixin, TestCase):
             obj1 = klass(value1)
             obj2 = klass(value2)
             self.assertEqual(obj1 == obj2, value1 == value2)
+            self.assertEqual(obj1 != obj2, value1 != value2)
             self.assertEqual(obj1 == bool(obj2), value1 == value2)
             obj1 = klass(value1, impl=tag1)
             obj2 = klass(value1, impl=tag2)
             self.assertEqual(obj1 == obj2, tag1 == tag2)
+            self.assertEqual(obj1 != obj2, tag1 != tag2)
 
     @given(data_strategy())
     def test_call(self, d):
@@ -677,10 +679,12 @@ class TestInteger(CommonMixin, TestCase):
             obj1 = klass(value1)
             obj2 = klass(value2)
             self.assertEqual(obj1 == obj2, value1 == value2)
+            self.assertEqual(obj1 != obj2, value1 != value2)
             self.assertEqual(obj1 == int(obj2), value1 == value2)
             obj1 = klass(value1, impl=tag1)
             obj2 = klass(value1, impl=tag2)
             self.assertEqual(obj1 == obj2, tag1 == tag2)
+            self.assertEqual(obj1 != obj2, tag1 != tag2)
 
     @given(lists(integers()))
     def test_sorted_works(self, values):
@@ -1129,10 +1133,12 @@ class TestBitString(CommonMixin, TestCase):
             obj1 = klass(value1)
             obj2 = klass(value2)
             self.assertEqual(obj1 == obj2, value1 == value2)
+            self.assertEqual(obj1 != obj2, value1 != value2)
             self.assertEqual(obj1 == bytes(obj2), value1[1] == value2[1])
             obj1 = klass(value1, impl=tag1)
             obj2 = klass(value1, impl=tag2)
             self.assertEqual(obj1 == obj2, tag1 == tag2)
+            self.assertEqual(obj1 != obj2, tag1 != tag2)
 
     @given(data_strategy())
     def test_call(self, d):
@@ -1434,10 +1440,19 @@ class TestOctetString(CommonMixin, TestCase):
             obj1 = klass(value1)
             obj2 = klass(value2)
             self.assertEqual(obj1 == obj2, value1 == value2)
+            self.assertEqual(obj1 != obj2, value1 != value2)
             self.assertEqual(obj1 == bytes(obj2), value1 == value2)
             obj1 = klass(value1, impl=tag1)
             obj2 = klass(value1, impl=tag2)
             self.assertEqual(obj1 == obj2, tag1 == tag2)
+            self.assertEqual(obj1 != obj2, tag1 != tag2)
+
+    @given(lists(binary()))
+    def test_sorted_works(self, values):
+        self.assertSequenceEqual(
+            [bytes(v) for v in sorted(OctetString(v) for v in values)],
+            sorted(values),
+        )
 
     @given(data_strategy())
     def test_bounds_satisfied(self, d):
@@ -1698,6 +1713,7 @@ class TestNull(CommonMixin, TestCase):
             obj1 = klass(impl=tag1)
             obj2 = klass(impl=tag2)
             self.assertEqual(obj1 == obj2, tag1 == tag2)
+            self.assertEqual(obj1 != obj2, tag1 != tag2)
             self.assertNotEqual(obj1, tag2)
 
     @given(data_strategy())
@@ -1910,11 +1926,13 @@ class TestObjectIdentifier(CommonMixin, TestCase):
             obj1 = klass(value1)
             obj2 = klass(value2)
             self.assertEqual(obj1 == obj2, value1 == value2)
+            self.assertEqual(obj1 != obj2, value1 != value2)
             self.assertEqual(obj1 == tuple(obj2), value1 == value2)
             self.assertEqual(str(obj1) == str(obj2), value1 == value2)
             obj1 = klass(value1, impl=tag1)
             obj2 = klass(value1, impl=tag2)
             self.assertEqual(obj1 == obj2, tag1 == tag2)
+            self.assertEqual(obj1 != obj2, tag1 != tag2)
 
     @given(lists(oid_strategy()))
     def test_sorted_works(self, values):
@@ -2272,10 +2290,12 @@ class TestEnumerated(CommonMixin, TestCase):
             obj1 = klass(value1)
             obj2 = klass(value2)
             self.assertEqual(obj1 == obj2, value1 == value2)
+            self.assertEqual(obj1 != obj2, value1 != value2)
             self.assertEqual(obj1 == int(obj2), value1 == value2)
             obj1 = klass(value1, impl=tag1)
             obj2 = klass(value1, impl=tag2)
             self.assertEqual(obj1 == obj2, tag1 == tag2)
+            self.assertEqual(obj1 != obj2, tag1 != tag2)
 
     @given(data_strategy())
     def test_call(self, d):
@@ -2486,11 +2506,13 @@ class StringMixin(object):
         obj1 = self.base_klass(value1)
         obj2 = self.base_klass(value2)
         self.assertEqual(obj1 == obj2, value1 == value2)
+        self.assertEqual(obj1 != obj2, value1 != value2)
         self.assertEqual(obj1 == bytes(obj2), value1 == value2)
         self.assertEqual(obj1 == text_type(obj2), value1 == value2)
         obj1 = self.base_klass(value1, impl=tag1)
         obj2 = self.base_klass(value1, impl=tag2)
         self.assertEqual(obj1 == obj2, tag1 == tag2)
+        self.assertEqual(obj1 != obj2, tag1 != tag2)
 
     @given(data_strategy())
     def test_bounds_satisfied(self, d):
@@ -2846,11 +2868,13 @@ class TimeMixin(object):
         obj1 = self.base_klass(value1)
         obj2 = self.base_klass(value2)
         self.assertEqual(obj1 == obj2, value1 == value2)
+        self.assertEqual(obj1 != obj2, value1 != value2)
         self.assertEqual(obj1 == obj2.todatetime(), value1 == value2)
         self.assertEqual(obj1 == bytes(obj2), value1 == value2)
         obj1 = self.base_klass(value1, impl=tag1)
         obj2 = self.base_klass(value1, impl=tag2)
         self.assertEqual(obj1 == obj2, tag1 == tag2)
+        self.assertEqual(obj1 != obj2, tag1 != tag2)
 
     @given(data_strategy())
     def test_call(self, d):
@@ -3173,6 +3197,7 @@ class TestAny(CommonMixin, TestCase):
             obj1 = klass(value1)
             obj2 = klass(value2)
             self.assertEqual(obj1 == obj2, value1 == value2)
+            self.assertEqual(obj1 != obj2, value1 != value2)
             self.assertEqual(obj1 == bytes(obj2), value1 == value2)
 
     @given(data_strategy())
@@ -3412,6 +3437,7 @@ class TestChoice(CommonMixin, TestCase):
             obj1 = klass(("whatever", Boolean(value1)))
             obj2 = klass(("whatever", Boolean(value2)))
             self.assertEqual(obj1 == obj2, value1 == value2)
+            self.assertEqual(obj1 != obj2, value1 != value2)
             self.assertEqual(obj1 == obj2._value, value1 == value2)
             self.assertFalse(obj1 == obj2._value[1])
 
@@ -4270,11 +4296,13 @@ class SeqOfMixing(object):
         obj1 = SeqOf([Boolean(value1)])
         obj2 = SeqOf([Boolean(value2)])
         self.assertEqual(obj1 == obj2, value1 == value2)
+        self.assertEqual(obj1 != obj2, value1 != value2)
         self.assertEqual(obj1 == list(obj2), value1 == value2)
         self.assertEqual(obj1 == tuple(obj2), value1 == value2)
         obj1 = SeqOf([Boolean(value1)], impl=tag1)
         obj2 = SeqOf([Boolean(value1)], impl=tag2)
         self.assertEqual(obj1 == obj2, tag1 == tag2)
+        self.assertEqual(obj1 != obj2, tag1 != tag2)
 
     @given(lists(booleans()))
     def test_iter(self, values):