Py_TYPE(obj) currently returns a borrowed reference, which is only valid until:
obj is GC'd, or
- the type of
obj changes
Changing a type is possible from Python, using assignment to __class__. That makes Py_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?
- When an object's type is changed from
A to B, then B takes a reference to A, which is only freed when B itself is freed.
Now, PyTYPE(obj) is guaranteed to outlive obj, at the cost of:
- keeping old types around
- extra bookkeeping (when an object's type is changed)
- a lazily allocated mapping of “old types” (either per-type, stored with
B with id(A) keys, or per-interpreter with (id(A), id(B)) keys)
... which seems reasonable for __class__ assignment.
Py_TYPE(obj)currently returns a borrowed reference, which is only valid until:objis GC'd, orobjchangesChanging a type is possible from Python, using assignment to
__class__. That makesPy_TYPE(obj)unsafe, especially with the GIL removed.Py_TYPEis 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_TYPEsafe.How would this sound?
AtoB, thenBtakes a reference to A, which is only freed whenBitself is freed.Now,
PyTYPE(obj)is guaranteed to outliveobj, at the cost of:Bwithid(A)keys, or per-interpreter with(id(A), id(B))keys)... which seems reasonable for
__class__assignment.