But in both cases, I think that behind the scene the function PyObject_RichCompareBoolis called correct? Why is there a difference? Shouldn't they have the same behavior?
==never calls PyObject_RichCompareBoolon floating point objects, float has its own rich_comparemethod (called for __eq__), which may or may not call PyObject_RichCompareBooldepending on the arguments passed to it.
static PyObject*
float_richcompare(PyObject *v, PyObject *w, int op)
{
double i, j;
int r = 0;
assert(PyFloat_Check(v));
i = PyFloat_AS_DOUBLE(v);
if (PyFloat_Check(w))
j = PyFloat_AS_DOUBLE(w);
else if (!Py_IS_FINITE(i)) {
if (PyInt_Check(w) || PyLong_Check(w))
j = 0.0;
else
goto Unimplemented;
}
...
, list_contains PyObject_RichCompareBool , True .
, CPython, PyPy list.__contains__ , , , __eq__ :
$~/pypy-2.4.0-linux64/bin
Python 2.7.8 (f5dcc2477b97, Sep 18 2014, 11:33:30)
[PyPy 2.4.0 with GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>> nan = float('nan')
>>>> nan == nan
False
>>>> nan is nan
True
>>>> nan in [nan]
False