Exemple #1
0
/* Try a 3-way comparison, returning an int.  Return:
   -2 for an exception;
   -1 if v <  w;
    0 if v == w;
    1 if v  > w;
    2 if this particular 3-way comparison is not implemented or undefined.
*/
static int
try_3way_compare(PyObject *v, PyObject *w)
{
	int c;
	cmpfunc f;

	/* Comparisons involving instances are given to instance_compare,
	   which has the same return conventions as this function. */

	f = v->ob_type->tp_compare;
	if (PyInstance_Check(v))
		return (*f)(v, w);
	if (PyInstance_Check(w))
		return (*w->ob_type->tp_compare)(v, w);

	/* If both have the same (non-NULL) tp_compare, use it. */
	if (f != NULL && f == w->ob_type->tp_compare) {
		c = (*f)(v, w);
		if (c < 0 && PyErr_Occurred())
			return -1;
		return c < 0 ? -1 : c > 0 ? 1 : 0;
	}

	/* If either tp_compare is _PyObject_SlotCompare, that's safe. */
	if (f == _PyObject_SlotCompare ||
	    w->ob_type->tp_compare == _PyObject_SlotCompare)
		return _PyObject_SlotCompare(v, w);

	/* Try coercion; if it fails, give up */
	c = PyNumber_CoerceEx(&v, &w);
	if (c < 0)
		return -2;
	if (c > 0)
		return 2;

	/* Try v's comparison, if defined */
	if ((f = v->ob_type->tp_compare) != NULL) {
		c = (*f)(v, w);
		Py_DECREF(v);
		Py_DECREF(w);
		if (c < 0 && PyErr_Occurred())
			return -2;
		return c < 0 ? -1 : c > 0 ? 1 : 0;
	}

	/* Try w's comparison, if defined */
	if ((f = w->ob_type->tp_compare) != NULL) {
		c = (*f)(w, v); /* swapped! */
		Py_DECREF(v);
		Py_DECREF(w);
		if (c < 0 && PyErr_Occurred())
			return -2;
		return c < 0 ? 1 : c > 0 ? -1 : 0; /* negated! */
	}

	/* No comparison defined */
	Py_DECREF(v);
	Py_DECREF(w);
	return 2;
}
Exemple #2
0
/* Try a 3-way comparison, returning an int.  Return:
   -2 for an exception;
   -1 if v <  w;
    0 if v == w;
    1 if v  > w;
    2 if this particular 3-way comparison is not implemented or undefined.
*/
static int
try_3way_compare(PyObject *v, PyObject *w)
{
	int c;
	cmpfunc f;

	/* Comparisons involving instances are given to instance_compare,
	   which has the same return conventions as this function. */

	f = v->ob_type->tp_compare;
	if (PyInstance_Check(v))
		return (*f)(v, w);
	if (PyInstance_Check(w))
		return (*w->ob_type->tp_compare)(v, w);

	/* If both have the same (non-NULL) tp_compare, use it. */
	if (f != NULL && f == w->ob_type->tp_compare) {
		c = (*f)(v, w);
		return adjust_tp_compare(c);
	}

	/* If either tp_compare is _PyObject_SlotCompare, that's safe. */
	if (f == _PyObject_SlotCompare ||
	    w->ob_type->tp_compare == _PyObject_SlotCompare)
		return _PyObject_SlotCompare(v, w);

	/* If we're here, v and w,
	    a) are not instances;
	    b) have different types or a type without tp_compare; and
	    c) don't have a user-defined tp_compare.
	   tp_compare implementations in C assume that both arguments
	   have their type, so we give up if the coercion fails or if
	   it yields types which are still incompatible (which can
	   happen with a user-defined nb_coerce).
	*/
	c = PyNumber_CoerceEx(&v, &w);
	if (c < 0)
		return -2;
	if (c > 0)
		return 2;
	f = v->ob_type->tp_compare;
	if (f != NULL && f == w->ob_type->tp_compare) {
		c = (*f)(v, w);
		Py_DECREF(v);
		Py_DECREF(w);
		return adjust_tp_compare(c);
	}

	/* No comparison defined */
	Py_DECREF(v);
	Py_DECREF(w);
	return 2;
}