Seeking deeper understanding of python equality (==)

Sam Ezeh sam.z.ezeh at gmail.com
Fri May 6 13:31:05 EDT 2022


Perhaps these source references are useful:

Python/ceval.c (_PyEval_EvalFrameDefault)
https://github.com/python/cpython/blob/main/Python/ceval.c#L3754-L3768
Objects/object.c (do_richcompare)
https://github.com/python/cpython/blob/42fee931d055a3ef8ed31abe44603b9b2856e04d/Objects/object.c#L661-L713

Kind regards,
Sam Ezeh


On Fri, 6 May 2022 at 18:12, Jonathan Kaczynski
<jonathan.kaczynski at guildeducation.com> wrote:
>
> Hi,
>
> I was recently trying to explain how python equality works and ran into a
> gap in my knowledge. I haven't found any good pages going beneath a surface
> level explanation of python equality comparison.
>
> I'll post my investigations below. What I think I'm looking for is where in
> the source code (https://github.com/python/cpython) does the equality
> comparison occur. I have an idea but wanted to ask first.
>
>
> Using the dis module, we see the comparison operator is a single bytecode,
> which is expected.
>
> ❯ docker run -it --rm ubuntu:jammy
> root at 919d94c98191:/# apt-get update
> root at 919d94c98191:/# apt-get --yes install python3
> root at 919d94c98191:/# cat >play.py <<EOF
> import dis
> import uuid
>
> def test():
>     x = uuid.uuid4()
>     y = str(x)
>     x == y
>     return
>
> dis.dis(test)
> EOF
> root at f33b02fef026:/# python3 play.py
> ... snip ...
>   7          16 LOAD_FAST                0 (x)
>              18 LOAD_FAST                1 (y)
>              20 COMPARE_OP               2 (==)
>              22 POP_TOP
> ... snip ...
>
>
> Stepping through the code with gdb, we see it jump from the compare
> operator to the dunder-eq method on the UUID object. What I want to be able
> to do is explain the in-between steps. Also, if you change `x == y` to `y
> == x`, you still see the same behavior, which I assume has to do with
> dunder-eq being defined on the UUID class and thus given priority.
>
> ❯ docker run -it --rm ubuntu:jammy
> root at 919d94c98191:/# apt-get update
> root at 919d94c98191:/# apt-get --yes install dpkg-source-gitarchive
> root at 919d94c98191:/# sed -i 's/^# deb-src/deb-src/' /etc/apt/sources.list
> root at 919d94c98191:/# apt-get update
> root at 919d94c98191:/# apt-get --yes install gdb python3.10-dbg
> root at 919d94c98191:/# apt-get source python3.10-dbg
> root at 919d94c98191:/# cat >play.py <<EOF
> import uuid
> x = uuid.uuid4()
> y = str(x)
> breakpoint()
> x == y
> EOF
> root at 919d94c98191:/# gdb python3.10-dbg
> (gdb) dir python3.10-3.10.4/Python
> (gdb) run play.py
> Starting program: /usr/bin/python3.10-dbg play.py
>
> warning: Error disabling address space randomization: Operation not
> permitted
> [Thread debugging using libthread_db enabled]
> Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
> > //play.py(5)<module>()
> -> x == y
> (Pdb) s
> --Call--
> > /usr/lib/python3.10/uuid.py(239)__eq__()
> -> def __eq__(self, other):
>
>
> Thank you,
> Jonathan
> --
> https://mail.python.org/mailman/listinfo/python-list


More information about the Python-list mailing list