-
-
Notifications
You must be signed in to change notification settings - Fork 30.7k
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
gh-92678: Document Py_TPFLAGS_MANAGED_DICT and friends #95440
Conversation
Fidget-Spinner
commented
Jul 29, 2022
•
edited by bedevere-bot
Loading
edited by bedevere-bot
- Issue: MRO: Behavior change from 3.10 to 3.11: multiple inheritance issue with C-API (pybind11) #92678
I'll dive into the code tomorrow but I'll write down the questions that come to mind today. Hopefully they'll be easy to answer. What does it mean for If a type with |
Yes. The managed just means previously to set
The type that is being derived from.
I'm not sure about inheritance. Maybe @markshannon knows. However, AFAICS, any type that sets the |
On reflection, maybe One important thing to document is that object creation and deallocation are handled by the VM, but visiting, initialization and clearing are the responsibility of the extension. Consequently, we can create the "managed" dictionary automatically during object creation, or lazily on first access, and we can also de-allocate it automatically, we rely on the extension to visit and/or clear it. Hence the need for #95246. |
Regarding inheritance, semantically inheritance only requires that a class has the Therefore is perfectly OK for a class to have a "legacy" It is all down to memory layout, the C code in superclasses should work correctly on subclasses, so we need to preserve the layout of extension superclasses. For example, class
If we inherit from both, then the new class has a "legacy"
Things would be much simpler if all objects with |
* CPython no longer assumes that a ``__dict__`` exists after an object. C extension | ||
types with inheritance and ``__dict__`` may have MRO problems. To fix this, allow | ||
CPython to manage the ``__dict__`` of instances of your type by setting | ||
:const:`Py_TPFLAGS_MANAGED_DICT` in :c:member:`~PyTypeObject.tp_flags`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This really raises more questions than it answers. In what cases did CPython assume a __dict__
exists after an object? (Didn't it put it there itself before 3.11?) What does it mean for a type to be “with inheritance”? What kind of MRO problems can you fix with the flag?
If you inherit from
Ah, and the newly exposed If you override I see |
They are: they will mess up with the gc algorithm. When the gc starts decrementing the gc references to find cycles, it will decrement the references twice if the object is visited too many times. The contract is that it has to be visited once per strong reference. |
What does that mean? There is no such thing as inheritance in C. There has to be an assumption that if you are doing fancy stuff with classes implemented in C, that you know what you are doing. I'm beginning to think that the documentation for If Cython, pybind11 or mypyc can figure out how to use it safely, then good on them, but we shouldn't be encouraging its use. For 3.12 we'll add a better API, but it's way too late for 3.11. |
Using them as as bases.
Sorry, but it seems that there are very few people who can use |
So don't use it. No one needs to use it. |
So what's the suggestion for pybind11/mypyc? Does #92678 (comment) no longer apply, so we need to restart that discussion? |
The public docs for |
This docs are still correct for 3.11. For 3.12 I'd like to set |
That's up to them. |
But now you can't expect to find a valid |
You will find a valid PyDictObject * pointer, but it might be However, it appears that no one uses it, because what would you do with a pointer to the dictionary? Cython does access |
We don't need to document this anymore right? |
Print it out, pickle it,
I don't think so. 3.11 will get a revert and 3.12 should get a better API. Closing, please reopen if you disagree. |