As part of this blog series on Python's syntactic sugar, I said in the post on unary arithmetic operators that it might be the most boring post in this series. I think I was wrong. 😄
The operators is
and is not
are very short. The documentation for the operators says the following:
x is y
is true if and only if x and y are the same object. An Object’s identity is determined using theid()
function.x is not y
yields the inverse truth value.
That's it: call id()
on the objects in question and see if you got the same/different values for each of the objects.
The bytecode
Disassembling the two operators leads to the following:
>>> def spam():
... x is y
... x is not y
...
>>> import dis
>>> dis.dis(spam)
2 0 LOAD_GLOBAL 0 (x)
2 LOAD_GLOBAL 1 (y)
4 COMPARE_OP 8 (is)
6 POP_TOP
3 8 LOAD_GLOBAL 0 (x)
10 LOAD_GLOBAL 1 (y)
12 COMPARE_OP 9 (is not)
14 POP_TOP
16 LOAD_CONST 0 (None)
18 RETURN_VALUE
Disassembly of is
and is not
If you follow into COMPARE_OP
you will see it calls cmp_outcome()
. The pertinent lines of that function are:
static PyObject *
cmp_outcome(PyThreadState *tstate, int op, PyObject *v, PyObject *w)
{
int res = 0;
switch (op) {
case PyCmp_IS:
res = (v == w);
break;
case PyCmp_IS_NOT:
res = (v != w);
break;
Snippet from cmp_outcome()
What that is showing is that is
and is not
are doing nothing more than comparing the pointers of the objects in question (which are the location in memory for the objects if you are unfamiliar with what a pointer is; PyPy returns a unique number instead).
The code
That translates is
and is not
to:
def is_(a: Any, b: Any) -> bool:
"""Check if the arguments are the same object."""
return id(a) == id(b)
def is_not(a: Any, b: Any) -> bool:
"""Check if the arguments are different objects."""
return id(a) != id(b)
Implementations of is
and is not
This is one of those instances where the tests took up more code than the implementation. 😄
As usual, the source code from this blog post can be found in my desugar project.
from Planet Python
via read more
No comments:
Post a Comment