diff options
-rw-r--r-- | Include/object.h | 3 | ||||
-rw-r--r-- | Lib/test/test_class.py | 9 | ||||
-rw-r--r-- | Lib/test/test_descr.py | 59 | ||||
-rw-r--r-- | Lib/test/test_hash.py | 1 | ||||
-rw-r--r-- | Lib/test/test_long.py | 14 | ||||
-rw-r--r-- | Lib/test/test_richcmp.py | 2 | ||||
-rw-r--r-- | Lib/test/test_set.py | 3 | ||||
-rw-r--r-- | Objects/typeobject.c | 85 |
8 files changed, 26 insertions, 150 deletions
diff --git a/Include/object.h b/Include/object.h index bddfb6f..16708f9 100644 --- a/Include/object.h +++ b/Include/object.h @@ -447,9 +447,6 @@ PyAPI_FUNC(int) PyCallable_Check(PyObject *); PyAPI_FUNC(void) PyObject_ClearWeakRefs(PyObject *); -/* A slot function whose address we need to compare */ -extern int _PyObject_SlotCompare(PyObject *, PyObject *); - /* PyObject_Dir(obj) acts like Python builtins.dir(obj), returning a list of strings. PyObject_Dir(NULL) is like builtins.dir(), diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py index cabf715..552c521 100644 --- a/Lib/test/test_class.py +++ b/Lib/test/test_class.py @@ -92,10 +92,6 @@ def __float__(self, *args): return 1.0 @trackCall -def __cmp__(self, *args): - return 0 - -@trackCall def __eq__(self, *args): return True @@ -465,11 +461,6 @@ class ClassTests(unittest.TestCase): hash(C0()) # This should work; the next two should raise TypeError - class C1: - def __cmp__(self, other): return 0 - - self.assertRaises(TypeError, hash, C1()) - class C2: def __eq__(self, other): return 1 diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 3c0bae0..85df9dc 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -1566,7 +1566,7 @@ order (MRO) for bases """ for i in range(10): self.assert_(i in d1) self.assertFalse(10 in d1) - # Test overridden behavior for static classes + # Test overridden behavior class Proxy(object): def __init__(self, x): self.x = x @@ -1578,8 +1578,14 @@ order (MRO) for bases """ return self.x == other def __ne__(self, other): return self.x != other - def __cmp__(self, other): - return cmp(self.x, other.x) + def __ge__(self, other): + return self.x >= other + def __gt__(self, other): + return self.x > other + def __le__(self, other): + return self.x <= other + def __lt__(self, other): + return self.x < other def __str__(self): return "Proxy:%s" % self.x def __repr__(self): @@ -1596,9 +1602,10 @@ order (MRO) for bases """ self.assertNotEqual(p0, p1) self.assert_(not p0 != p0) self.assertEqual(not p0, p1) - self.assertEqual(cmp(p0, p1), -1) - self.assertEqual(cmp(p0, p0), 0) - self.assertEqual(cmp(p0, p_1), 1) + self.assert_(p0 < p1) + self.assert_(p0 <= p1) + self.assert_(p1 > p0) + self.assert_(p1 >= p0) self.assertEqual(str(p0), "Proxy:0") self.assertEqual(repr(p0), "Proxy(0)") p10 = Proxy(range(10)) @@ -1606,46 +1613,6 @@ order (MRO) for bases """ for i in range(10): self.assert_(i in p10) self.assertFalse(10 in p10) - # Test overridden behavior for dynamic classes - class DProxy(object): - def __init__(self, x): - self.x = x - def __bool__(self): - return not not self.x - def __hash__(self): - return hash(self.x) - def __eq__(self, other): - return self.x == other - def __ne__(self, other): - return self.x != other - def __cmp__(self, other): - return cmp(self.x, other.x) - def __str__(self): - return "DProxy:%s" % self.x - def __repr__(self): - return "DProxy(%r)" % self.x - def __contains__(self, value): - return value in self.x - p0 = DProxy(0) - p1 = DProxy(1) - p_1 = DProxy(-1) - self.assertFalse(p0) - self.assert_(not not p1) - self.assertEqual(hash(p0), hash(0)) - self.assertEqual(p0, p0) - self.assertNotEqual(p0, p1) - self.assertNotEqual(not p0, p0) - self.assertEqual(not p0, p1) - self.assertEqual(cmp(p0, p1), -1) - self.assertEqual(cmp(p0, p0), 0) - self.assertEqual(cmp(p0, p_1), 1) - self.assertEqual(str(p0), "DProxy:0") - self.assertEqual(repr(p0), "DProxy(0)") - p10 = DProxy(range(10)) - self.assertFalse(-1 in p10) - for i in range(10): - self.assert_(i in p10) - self.assertFalse(10 in p10) ## # Safety test for __cmp__ ## def unsafecmp(a, b): diff --git a/Lib/test/test_hash.py b/Lib/test/test_hash.py index 56974b8..59e43dc 100644 --- a/Lib/test/test_hash.py +++ b/Lib/test/test_hash.py @@ -78,7 +78,6 @@ class HashInheritanceTestCase(unittest.TestCase): ] error_expected = [NoHash(), OnlyEquality(), - OnlyCmp(), ] def test_default_hash(self): diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py index dc04bad..a1db26a 100644 --- a/Lib/test/test_long.py +++ b/Lib/test/test_long.py @@ -669,10 +669,22 @@ class LongTest(unittest.TestCase): else: raise TypeError("can't deal with %r" % val) - def __cmp__(self, other): + def _cmp__(self, other): if not isinstance(other, Rat): other = Rat(other) return cmp(self.n * other.d, self.d * other.n) + def __eq__(self, other): + return self._cmp__(other) == 0 + def __ne__(self, other): + return self._cmp__(other) != 0 + def __ge__(self, other): + return self._cmp__(other) >= 0 + def __gt__(self, other): + return self._cmp__(other) > 0 + def __le__(self, other): + return self._cmp__(other) <= 0 + def __lt__(self, other): + return self._cmp__(other) < 0 cases = [0, 0.001, 0.99, 1.0, 1.5, 1e20, 1e200] # 2**48 is an important boundary in the internals. 2**53 is an diff --git a/Lib/test/test_richcmp.py b/Lib/test/test_richcmp.py index 435de75..72e636d 100644 --- a/Lib/test/test_richcmp.py +++ b/Lib/test/test_richcmp.py @@ -198,13 +198,11 @@ class MiscTest(unittest.TestCase): def __le__(self, other): raise TestFailed("This shouldn't happen") def __ge__(self, other): raise TestFailed("This shouldn't happen") def __ne__(self, other): raise TestFailed("This shouldn't happen") - def __cmp__(self, other): raise RuntimeError("expected") a = Misb() b = Misb() self.assertEqual(a<b, 0) self.assertEqual(a==b, 0) self.assertEqual(a>b, 0) - self.assertRaises(RuntimeError, cmp, a, b) def test_not(self): # Check that exceptions in __bool__ are properly diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py index 0effd65..614c9c0 100644 --- a/Lib/test/test_set.py +++ b/Lib/test/test_set.py @@ -202,9 +202,6 @@ class TestJointOps(unittest.TestCase): s = self.thetype(t) self.assertEqual(len(s), 3) - def test_compare(self): - self.assertRaises(TypeError, self.s.__cmp__, self.s) - def test_sub_and_super(self): p, q, r = map(self.thetype, ['ab', 'abcde', 'def']) self.assert_(p < q) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 8f1b389..7f9551f 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3536,7 +3536,6 @@ inherit_special(PyTypeObject *type, PyTypeObject *base) static char *hash_name_op[] = { "__eq__", - "__cmp__", "__hash__", NULL }; @@ -4227,32 +4226,6 @@ wrap_delitem(PyObject *self, PyObject *args, void *wrapped) return Py_None; } -static PyObject * -wrap_cmpfunc(PyObject *self, PyObject *args, void *wrapped) -{ - cmpfunc func = (cmpfunc)wrapped; - int res; - PyObject *other; - - if (!check_num_args(args, 1)) - return NULL; - other = PyTuple_GET_ITEM(args, 0); - if (Py_TYPE(other)->tp_compare != func && - !PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self))) { - PyErr_Format( - PyExc_TypeError, - "%s.__cmp__(x,y) requires y to be a '%s', not a '%s'", - Py_TYPE(self)->tp_name, - Py_TYPE(self)->tp_name, - Py_TYPE(other)->tp_name); - return NULL; - } - res = (*func)(self, other); - if (PyErr_Occurred()) - return NULL; - return PyLong_FromLong((long)res); -} - /* Helper to check for object.__setattr__ or __delattr__ applied to a type. This is called the Carlo Verre hack after its discoverer. */ static int @@ -4878,62 +4851,6 @@ SLOT1BIN(slot_nb_true_divide, nb_true_divide, "__truediv__", "__rtruediv__") SLOT1(slot_nb_inplace_floor_divide, "__ifloordiv__", PyObject *, "O") SLOT1(slot_nb_inplace_true_divide, "__itruediv__", PyObject *, "O") -static int -half_compare(PyObject *self, PyObject *other) -{ - PyObject *func, *args, *res; - static PyObject *cmp_str; - Py_ssize_t c; - - func = lookup_method(self, "__cmp__", &cmp_str); - if (func == NULL) { - PyErr_Clear(); - } - else { - args = PyTuple_Pack(1, other); - if (args == NULL) - res = NULL; - else { - res = PyObject_Call(func, args, NULL); - Py_DECREF(args); - } - Py_DECREF(func); - if (res != Py_NotImplemented) { - if (res == NULL) - return -2; - c = PyLong_AsLong(res); - Py_DECREF(res); - if (c == -1 && PyErr_Occurred()) - return -2; - return (c < 0) ? -1 : (c > 0) ? 1 : 0; - } - Py_DECREF(res); - } - return 2; -} - -/* This slot is published for the benefit of try_3way_compare in object.c */ -int -_PyObject_SlotCompare(PyObject *self, PyObject *other) -{ - int c; - - if (Py_TYPE(self)->tp_compare == _PyObject_SlotCompare) { - c = half_compare(self, other); - if (c <= 1) - return c; - } - if (Py_TYPE(other)->tp_compare == _PyObject_SlotCompare) { - c = half_compare(other, self); - if (c < -1) - return -2; - if (c <= 1) - return -c; - } - return (void *)self < (void *)other ? -1 : - (void *)self > (void *)other ? 1 : 0; -} - static PyObject * slot_tp_repr(PyObject *self) { @@ -5532,8 +5449,6 @@ static slotdef slotdefs[] = { "x.__str__() <==> str(x)"), TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc, "x.__repr__() <==> repr(x)"), - TPSLOT("__cmp__", tp_compare, _PyObject_SlotCompare, wrap_cmpfunc, - "x.__cmp__(y) <==> cmp(x,y)"), TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc, "x.__hash__() <==> hash(x)"), FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call, |