-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Idea: Make Py_TYPE(obj)
outlive obj
#38
Comments
Py_TYPE(obj)
outlive obj
Py_TYPE(obj)
outlive obj
I would suggest an other approach:
As for 1., my intuition is that most use cases for |
That's also possible. In fact, it doesn't conflict with my proposal. The trouble is with the implied next step:
My intuition agrees with yours, but another common use would be for looking up slots. |
The existing
No all Py_TYPE() usage are unsafe. In the majority of cases, it's very unlikely to get a crash related to Py_TYPE() borrowed reference. Specially design object can trigger crashes, yes. But with regular code, it's unlikely. I don't think that it's worth it to deprecate/remove Py_TYPE(). |
Is it possible to delay deletion of type objects until the garbage collector runs? I think in this case |
Since Python 3.12, The problem is that if a function uses Py_TYPE() borrowed reference and calls arbitary Python code, the Python code can trigger a GC collection. If the Python code clears the last reference to the type, the borrowed reference becomes a dangling pointer, and the code is likely to crash. Example of such crash in PEP 737 – Unify type name formatting: https://peps.python.org/pep-0737/#use-t-format-with-py-type-pass-a-type |
I'm trying to understand this sentence: is reference counting deferred to the eval loop, or is it just the cyclic garbage collector? I would definitely expect |
Right, and this is essentially what I'm thinking by the difference between a "short-lived read" and "need to store the result", though I did not word it well. My point is that in nogil world arbitrary python code can be running all the time on other threads. I think the best you can hope is that when you call into arbitrary python code the stop-the-world GC might halt you so that it can run (but I'm not too sure exactly on the process of this yet). So this is why I ask if it makes sense to delay type object deletion until the GC.
Me too :) |
What's New In Python 3.12 says (highlight is mine):
Creating a heap type creates multiple reference cycles. For example, a type contains itself in its internal MRO tuple. And each method contains a strong reference to the type (which contains the methods). A garbage collection is needed to delete a heap type. |
Ah I see, so what I'm asking for is already true thanks to the cycles. |
In Python 3.11, when a object tracked by the GC is created (by In Python 3.12, this case can happen if the code "around" the borrowed reference calls arbitrary code which can trigger a GC collection, such as "arbitrary Python code". For example, if an object is deallocaed and it's finalizer function is implemented as a Python Well, in general, it's simpler to just say: borrowed references are dangerous :-) |
This may already have been cleared up, but for the record, this is not true. We would like it to be true, but it isn't. What's delayed is calls to the cyclical GC, which used to be called directly by allocations. But |
Py_TYPE(obj)
currently returns a borrowed reference, which is only valid until:obj
is GC'd, orobj
changesChanging a type is possible from Python, using assignment to
__class__
. That makesPy_TYPE(obj)
unsafe, especially with the GIL removed.Py_TYPE
is ubiquitous, we can't really get rid of it (or change its semantics).However, changing the type is a rare, specialized operation. Perhaps we can penalize it to make
Py_TYPE
safe.How would this sound?
A
toB
, thenB
takes a reference to A, which is only freed whenB
itself is freed.Now,
PyTYPE(obj)
is guaranteed to outliveobj
, at the cost of:B
withid(A)
keys, or per-interpreter with(id(A), id(B))
keys)... which seems reasonable for
__class__
assignment.The text was updated successfully, but these errors were encountered: