Author vstinner
Recipients vstinner
Date 2021-04-06.18:38:58
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1617734338.35.0.565380301548.issue43753@roundup.psfhosted.org>
In-reply-to
Content
I propose to add at least Py_Is(x, y) function to the Python C API which would be simply implemented as:

    static inline int Py_Is(PyObject *x, PyObject *y) { return (x == y); }

Right now, there is no benefit for CPython. The idea is to prepare the CPython code base for future optimization, like tagged pointers. It may help PyPy. It can also help to prepare C extensions to migrate to HPy, since HPy requires to use HPy_Is(ctx, x, y): "x == y" (where x and y types is HPy) fails with a compiler error with HPy.

--

CPython uses reference counting and singletons like None and False. The "x is y" operator in Python is implemented with the IS_OP opcode implemented in Python/ceval.c as:

        case TARGET(IS_OP): {
            PyObject *right = POP();
            PyObject *left = TOP();
            int res = (left == right)^oparg;
            PyObject *b = res ? Py_True : Py_False;
            Py_INCREF(b);
            SET_TOP(b);
            Py_DECREF(left);
            Py_DECREF(right);
            PREDICT(POP_JUMP_IF_FALSE);
            PREDICT(POP_JUMP_IF_TRUE);
            DISPATCH();
        }

In short, "x is y" in Python simply compares directly PyObject* pointer values in C: "x == y" where x and y are PyObject* pointers.

PyPy doesn't use reference counting and so implements "x is y" differently: id(x) == id(y) if I understood correctly. In PyPy, id(obj) is more complex than simply getting the object memory address. For example, id(1) is always 17 in PyPy (on Linux/x86-64 at least).

At the C API level, using "x == y" to check if y object "is" x object doesn't work well with PyPy object models. Moreover, "x == Py_None" doesn't work if None is stored as a tagged pointer in CPython.

--

Maybe we can also add functions to check if an object is a singleton:

* Py_IsNone(x): x == Py_None
* Py_IsTrue(x): x == Py_True
* Py_IsFalse(x): x == Py_False

See also bpo-39511 "[subinterpreters] Per-interpreter singletons (None, True, False, etc.)" which may need to replace Py_None singleton with Py_GetNone(). IMO it makes more sense to call Py_IS_NONE(x) function to express that code is run, rather than writing "x == Py_None" as if Py_None is and will always be a variable directly accesssible.

Py_IS_TRUE() name sounds like PyObject_IsTrue(). Can it be an issue? Can someone come with a better name?
History
Date User Action Args
2021-04-06 18:38:58vstinnersetrecipients: + vstinner
2021-04-06 18:38:58vstinnersetmessageid: <1617734338.35.0.565380301548.issue43753@roundup.psfhosted.org>
2021-04-06 18:38:58vstinnerlinkissue43753 messages
2021-04-06 18:38:58vstinnercreate