mirror of
https://github.com/python/cpython.git
synced 2025-12-15 21:44:50 +00:00
remove some more references to __cmp__ #1717
This commit is contained in:
parent
aaebe1c11d
commit
60192084c4
8 changed files with 26 additions and 150 deletions
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -91,10 +91,6 @@ def __index__(self, *args):
|
|||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -78,7 +78,6 @@ class HashInheritanceTestCase(unittest.TestCase):
|
|||
]
|
||||
error_expected = [NoHash(),
|
||||
OnlyEquality(),
|
||||
OnlyCmp(),
|
||||
]
|
||||
|
||||
def test_default_hash(self):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue