Search code examples
pythonpython-3.xpeppython-3.12

Immortal Objects in Python: how do they work?


Recently I came across

PEP 683 – Immortal Objects, Using a Fixed Refcount

https://peps.python.org/pep-0683/

What I figured out that objects like None, True, False will be shared across interpreter instead of creating copies.

These were already immutable, weren't they?

Can someone please explain in easy terms. Thanks.


Solution

  • That PEP is about CPython, which is the reference implementation of Python. As such, it talks about things on a very different level than what most of us are thinking about.

    CPython keeps track of how many references there are to any given object (the refcount). If you do something like a = some_expression(), the object that is assigned to a gets its refcount increased. Same with something like my_list.append(something). If you clear a list, reassign or delete a variable, or something else like that, CPython decreases the refcount of the objects involved by one. When the refcount reaches 0, it knows it can clean up that object.

    Now, certain values like None, True, and False are never going to get to 0 as long as the program is running, so they are effectively immortal. But up until 3.12, CPython didn't know that it didn't need to bother changing the refcount for these objects, so it still updated it every time they got a new reference or a reference disappeared. So while the Python-facing part of these objects were immutable, on the C-side, None and objects like it actually have a bit of memory attached to it that was mutable. And that has impacts on performance (outlined in the "Motivation" section of the PEP).

    This is all very nitty-gritty, and I don't understand the full implications of all this myself, but unless you're writing a C extension, you probably don't need to worry about it.