I was learning cpython internals(especially how is
operator is implemented) and came across the following opcode implementation for IS_OP
in ceval.c
case TARGET(IS_OP): {
PyObject *right = POP();
PyObject *left = TOP();
int res = (left == right)^oparg;
PyObject *b = res ? Py_True : Py_False;
...
}
I know the first two statements pop
the operands from the stack.
PyObject *right = POP();
PyObject *left = TOP();
But my question is related to the following statement:
int res = (left == right)^oparg;
In my understanding is
operator in python compares object identity, In other terms it will check whether both the objects are pointing to the same object. So my question is, only the following code is sufficient to check the object identity?, Why the actual implementation again apply an exlcusive OR(^
) with oparg
?
int res = (left == right)
The IS_OP
op code is used for both is
and is not
. The ^oparg
flips the result of the comparison when oparg
is 1
(for is not
) and leaves it alone when it's 0
(for is
), so the same bytecode can handle both cases branchlessly just by tweaking the oparg
(in dis
output, is
is IS_OP 0
, is not
is IS_OP 1
).