mirror of https://github.com/python/cpython
Issue #1717: remove the cmp builtin function, the C-API functions
PyObject_Cmp, PyObject_Compare, and various support functions.
This commit is contained in:
parent
211c625829
commit
f02e0aaafd
|
@ -89,27 +89,6 @@ Object Protocol
|
||||||
*opid*.
|
*opid*.
|
||||||
|
|
||||||
|
|
||||||
.. cfunction:: int PyObject_Cmp(PyObject *o1, PyObject *o2, int *result)
|
|
||||||
|
|
||||||
.. index:: builtin: cmp
|
|
||||||
|
|
||||||
Compare the values of *o1* and *o2* using a routine provided by *o1*, if one
|
|
||||||
exists, otherwise with a routine provided by *o2*. The result of the comparison
|
|
||||||
is returned in *result*. Returns ``-1`` on failure. This is the equivalent of
|
|
||||||
the Python statement ``result = cmp(o1, o2)``.
|
|
||||||
|
|
||||||
|
|
||||||
.. cfunction:: int PyObject_Compare(PyObject *o1, PyObject *o2)
|
|
||||||
|
|
||||||
.. index:: builtin: cmp
|
|
||||||
|
|
||||||
Compare the values of *o1* and *o2* using a routine provided by *o1*, if one
|
|
||||||
exists, otherwise with a routine provided by *o2*. Returns the result of the
|
|
||||||
comparison on success. On error, the value returned is undefined; use
|
|
||||||
:cfunc:`PyErr_Occurred` to detect an error. This is equivalent to the Python
|
|
||||||
expression ``cmp(o1, o2)``.
|
|
||||||
|
|
||||||
|
|
||||||
.. cfunction:: PyObject* PyObject_Repr(PyObject *o)
|
.. cfunction:: PyObject* PyObject_Repr(PyObject *o)
|
||||||
|
|
||||||
.. index:: builtin: repr
|
.. index:: builtin: repr
|
||||||
|
|
|
@ -228,29 +228,6 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
|
||||||
*/
|
*/
|
||||||
#define PyObject_DelAttr(O,A) PyObject_SetAttr((O),(A),NULL)
|
#define PyObject_DelAttr(O,A) PyObject_SetAttr((O),(A),NULL)
|
||||||
|
|
||||||
PyAPI_FUNC(int) PyObject_Cmp(PyObject *o1, PyObject *o2, int *result);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Compare the values of o1 and o2 using a routine provided by
|
|
||||||
o1, if one exists, otherwise with a routine provided by o2.
|
|
||||||
The result of the comparison is returned in result. Returns
|
|
||||||
-1 on failure. This is the equivalent of the Python
|
|
||||||
statement: result=cmp(o1,o2).
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Implemented elsewhere:
|
|
||||||
|
|
||||||
int PyObject_Compare(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
Compare the values of o1 and o2 using a routine provided by
|
|
||||||
o1, if one exists, otherwise with a routine provided by o2.
|
|
||||||
Returns the result of the comparison on success. On error,
|
|
||||||
the value returned is undefined. This is equivalent to the
|
|
||||||
Python expression: cmp(o1,o2).
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Implemented elsewhere:
|
/* Implemented elsewhere:
|
||||||
|
|
||||||
PyObject *PyObject_Repr(PyObject *o);
|
PyObject *PyObject_Repr(PyObject *o);
|
||||||
|
|
|
@ -220,9 +220,7 @@ class BuiltinTest(unittest.TestCase):
|
||||||
self.assertRaises((OverflowError, ValueError), chr, 2**32)
|
self.assertRaises((OverflowError, ValueError), chr, 2**32)
|
||||||
|
|
||||||
def test_cmp(self):
|
def test_cmp(self):
|
||||||
# uncomment the following line once cmp has been removed
|
self.assert_(not hasattr(builtins, "cmp"))
|
||||||
#self.assert_(not hasattr(builtins, "cmp"))
|
|
||||||
pass
|
|
||||||
|
|
||||||
def test_compile(self):
|
def test_compile(self):
|
||||||
compile('print(1)\n', '', 'exec')
|
compile('print(1)\n', '', 'exec')
|
||||||
|
|
|
@ -12,6 +12,10 @@ What's New in Python 3.1 alpha 0
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #1717: Remove builtin cmp() function, C-API functions
|
||||||
|
PyObject_Cmp and PyObject_Compare, and the support function
|
||||||
|
Py_CmpToRich.
|
||||||
|
|
||||||
- Issue #4707: round(x, n) now returns an integer if x is an integer.
|
- Issue #4707: round(x, n) now returns an integer if x is an integer.
|
||||||
Previously it returned a float.
|
Previously it returned a float.
|
||||||
|
|
||||||
|
|
|
@ -27,22 +27,6 @@ null_error(void)
|
||||||
|
|
||||||
/* Operations on any object */
|
/* Operations on any object */
|
||||||
|
|
||||||
int
|
|
||||||
PyObject_Cmp(PyObject *o1, PyObject *o2, int *result)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (o1 == NULL || o2 == NULL) {
|
|
||||||
null_error();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
r = PyObject_Compare(o1, o2);
|
|
||||||
if (PyErr_Occurred())
|
|
||||||
return -1;
|
|
||||||
*result = r;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyObject_Type(PyObject *o)
|
PyObject_Type(PyObject *o)
|
||||||
{
|
{
|
||||||
|
|
100
Objects/object.c
100
Objects/object.c
|
@ -549,68 +549,6 @@ PyObject_Bytes(PyObject *v)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Forward */
|
|
||||||
static PyObject *do_richcompare(PyObject *v, PyObject *w, int op);
|
|
||||||
|
|
||||||
/* Perform a three-way comparison, raising TypeError if three-way comparison
|
|
||||||
is not supported. */
|
|
||||||
static int
|
|
||||||
do_compare(PyObject *v, PyObject *w)
|
|
||||||
{
|
|
||||||
cmpfunc f;
|
|
||||||
int ok;
|
|
||||||
|
|
||||||
if (v->ob_type == w->ob_type &&
|
|
||||||
(f = v->ob_type->tp_compare) != NULL) {
|
|
||||||
return (*f)(v, w);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now try three-way compare before giving up. This is intentionally
|
|
||||||
elaborate; if you have a it will raise TypeError if it detects two
|
|
||||||
objects that aren't ordered with respect to each other. */
|
|
||||||
ok = PyObject_RichCompareBool(v, w, Py_LT);
|
|
||||||
if (ok < 0)
|
|
||||||
return -1; /* Error */
|
|
||||||
if (ok)
|
|
||||||
return -1; /* Less than */
|
|
||||||
ok = PyObject_RichCompareBool(v, w, Py_GT);
|
|
||||||
if (ok < 0)
|
|
||||||
return -1; /* Error */
|
|
||||||
if (ok)
|
|
||||||
return 1; /* Greater than */
|
|
||||||
ok = PyObject_RichCompareBool(v, w, Py_EQ);
|
|
||||||
if (ok < 0)
|
|
||||||
return -1; /* Error */
|
|
||||||
if (ok)
|
|
||||||
return 0; /* Equal */
|
|
||||||
|
|
||||||
/* Give up */
|
|
||||||
PyErr_Format(PyExc_TypeError,
|
|
||||||
"unorderable types: '%.100s' != '%.100s'",
|
|
||||||
v->ob_type->tp_name,
|
|
||||||
w->ob_type->tp_name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Perform a three-way comparison. This wraps do_compare() with a check for
|
|
||||||
NULL arguments and a recursion check. */
|
|
||||||
int
|
|
||||||
PyObject_Compare(PyObject *v, PyObject *w)
|
|
||||||
{
|
|
||||||
int res;
|
|
||||||
|
|
||||||
if (v == NULL || w == NULL) {
|
|
||||||
if (!PyErr_Occurred())
|
|
||||||
PyErr_BadInternalCall();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (Py_EnterRecursiveCall(" in cmp"))
|
|
||||||
return -1;
|
|
||||||
res = do_compare(v, w);
|
|
||||||
Py_LeaveRecursiveCall();
|
|
||||||
return res < 0 ? -1 : res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Map rich comparison operators to their swapped version, e.g. LT <--> GT */
|
/* Map rich comparison operators to their swapped version, e.g. LT <--> GT */
|
||||||
int _Py_SwappedOp[] = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE};
|
int _Py_SwappedOp[] = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE};
|
||||||
|
|
||||||
|
@ -715,44 +653,6 @@ PyObject_RichCompareBool(PyObject *v, PyObject *w, int op)
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Turn the result of a three-way comparison into the result expected by a
|
|
||||||
rich comparison. */
|
|
||||||
PyObject *
|
|
||||||
Py_CmpToRich(int op, int cmp)
|
|
||||||
{
|
|
||||||
PyObject *res;
|
|
||||||
int ok;
|
|
||||||
|
|
||||||
if (PyErr_Occurred())
|
|
||||||
return NULL;
|
|
||||||
switch (op) {
|
|
||||||
case Py_LT:
|
|
||||||
ok = cmp < 0;
|
|
||||||
break;
|
|
||||||
case Py_LE:
|
|
||||||
ok = cmp <= 0;
|
|
||||||
break;
|
|
||||||
case Py_EQ:
|
|
||||||
ok = cmp == 0;
|
|
||||||
break;
|
|
||||||
case Py_NE:
|
|
||||||
ok = cmp != 0;
|
|
||||||
break;
|
|
||||||
case Py_GT:
|
|
||||||
ok = cmp > 0;
|
|
||||||
break;
|
|
||||||
case Py_GE:
|
|
||||||
ok = cmp >= 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
PyErr_BadArgument();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
res = ok ? Py_True : Py_False;
|
|
||||||
Py_INCREF(res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set of hash utility functions to help maintaining the invariant that
|
/* Set of hash utility functions to help maintaining the invariant that
|
||||||
if a==b then hash(a)==hash(b)
|
if a==b then hash(a)==hash(b)
|
||||||
|
|
||||||
|
|
|
@ -2897,7 +2897,7 @@ same_slots_added(PyTypeObject *a, PyTypeObject *b)
|
||||||
slots_a = ((PyHeapTypeObject *)a)->ht_slots;
|
slots_a = ((PyHeapTypeObject *)a)->ht_slots;
|
||||||
slots_b = ((PyHeapTypeObject *)b)->ht_slots;
|
slots_b = ((PyHeapTypeObject *)b)->ht_slots;
|
||||||
if (slots_a && slots_b) {
|
if (slots_a && slots_b) {
|
||||||
if (PyObject_Compare(slots_a, slots_b) != 0)
|
if (PyObject_RichCompareBool(slots_a, slots_b, Py_EQ) != 1)
|
||||||
return 0;
|
return 0;
|
||||||
size += sizeof(PyObject *) * PyTuple_GET_SIZE(slots_a);
|
size += sizeof(PyObject *) * PyTuple_GET_SIZE(slots_a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -493,25 +493,6 @@ PyDoc_STR(
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
builtin_cmp(PyObject *self, PyObject *args)
|
|
||||||
{
|
|
||||||
PyObject *a, *b;
|
|
||||||
int c;
|
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "cmp", 2, 2, &a, &b))
|
|
||||||
return NULL;
|
|
||||||
if (PyObject_Cmp(a, b, &c) < 0)
|
|
||||||
return NULL;
|
|
||||||
return PyLong_FromLong((long)c);
|
|
||||||
}
|
|
||||||
|
|
||||||
PyDoc_STRVAR(cmp_doc,
|
|
||||||
"cmp(x, y) -> integer\n\
|
|
||||||
\n\
|
|
||||||
Return negative if x<y, zero if x==y, positive if x>y.");
|
|
||||||
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
source_as_string(PyObject *cmd, char *funcname, char *what)
|
source_as_string(PyObject *cmd, char *funcname, char *what)
|
||||||
{
|
{
|
||||||
|
@ -2230,7 +2211,6 @@ static PyMethodDef builtin_methods[] = {
|
||||||
{"ascii", builtin_ascii, METH_O, ascii_doc},
|
{"ascii", builtin_ascii, METH_O, ascii_doc},
|
||||||
{"bin", builtin_bin, METH_O, bin_doc},
|
{"bin", builtin_bin, METH_O, bin_doc},
|
||||||
{"chr", builtin_chr, METH_VARARGS, chr_doc},
|
{"chr", builtin_chr, METH_VARARGS, chr_doc},
|
||||||
{"cmp", builtin_cmp, METH_VARARGS, cmp_doc},
|
|
||||||
{"compile", (PyCFunction)builtin_compile, METH_VARARGS | METH_KEYWORDS, compile_doc},
|
{"compile", (PyCFunction)builtin_compile, METH_VARARGS | METH_KEYWORDS, compile_doc},
|
||||||
{"delattr", builtin_delattr, METH_VARARGS, delattr_doc},
|
{"delattr", builtin_delattr, METH_VARARGS, delattr_doc},
|
||||||
{"dir", builtin_dir, METH_VARARGS, dir_doc},
|
{"dir", builtin_dir, METH_VARARGS, dir_doc},
|
||||||
|
|
Loading…
Reference in New Issue