Immortal Objects in Python: how do they work?

484 Views Asked by At

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.

3

There are 3 best solutions below

1
On BEST ANSWER

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.

0
On

I think I got my answer, posting here if someone finds this useful.

On searching thoroughly I came across an article explaining in details about this:

They have explained it beautifully including the cpython implementation.

Among the various improvements, an intriguing one is 'immortalization', rolled out in Python 3.12. Within the implementation of CPython, certain objects such as None, True, and False act as global singletons, shared across the interpreter instead of creating fresh copies each time. From the programmer’s perspective, these objects are immutable, a notion that was not entirely accurate until Python 3.12. Every new reference to these global singletons prompted the interpreter to increment their reference count, similar to regular Python objects. This resulted in few performance issues, including cache invalidation and potential race conditions (in GIL free world).

https://codeconfessions.substack.com/p/understanding-immortal-objects-in


Also there is another article which I found from Meta Inc.

Instagram has introduced Immortal Objects – PEP-683 – to Python. Now, objects can bypass reference count checks and live throughout the entire execution of the runtime, unlocking exciting avenues for true parallelism.

This problem of state mutation of shared objects is at the heart of how the Python runtime works. Given that it relies on reference counting and cycle detection, the runtime requires modifying the core memory structure of the object, which is one of the reasons the language requires a global interpreter lock (GIL).

To get around this issue, we introduced Immortal Objects – PEP-683. This creates an immortal object (an object for which the core object state will never change) by marking a special value in the object’s reference count field. It allows the runtime to know when it can and can’t mutate both the reference count fields and GC header.

enter image description here

A comparison of standard objects versus immortal objects. With standard objects, a user can guarantee that it will not mutate its type and/or its data. Immortality adds an extra guarantee that the runtime will not modify the reference count or the GC Header if present, enabling full object immutability.

Full article here: https://engineering.fb.com/2023/08/15/developer-tools/immortal-objects-for-python-instagram-meta/#:~:text=This%20creates%20an%20immortal%20object,count%20fields%20and%20GC%20header.

0
On

This is not about mutabillity.

This PEP is about immortality.

In python each object has a refrence count which is counting how many refrences do this object has.

When this value gets to 0, python's garbage collection would destroy this object.

Immortal objects don't change their refrence count, making it imutable, and they can't be garbage collected, maening they live until interpreter shutdown.