[belatedly catching up on capi-sig]
On Wed, 10 Jun 2020 at 00:56, Petr Viktorin firstname.lastname@example.org wrote:
Given that, I believe that some kind of MRO walker is still the best immediate solution, mainly because it's easiest to implement.
The other reason I still like using the MRO walker as the foundation is that once there's a way for tp_new and/or tp_init to look up the relevant info, or for individual slots to look it up on first use, then making the access during runtime fast becomes a problem that's well suited to being accelerated via context local variables.
Now, the main problem with "PyType_DefiningTypeFromSlotFunc" is that it looked slot functions, which can be set from Python code, and doing so can easily introduce C-level failures. To solve this, my next thought is instead looking for something only available in C: the PyModuleDef. Here's an implementation of such an MRO walker, which I call "_PyType_GetModuleByDef": https://github.com/encukou/cpython/blob/98dd889575cf7d1688495983ba791e14894a...
This seems like a plausible candidate to me, but the "break on non-heap-type" bit seems odd to me at first glance, as I'd have expected a "continue" there rather than a "break".
If there's an object model implementation related reason why we can't ever have a heap type appear in the MRO after a non-heap-type, then we could have a break-with-explanatory-comment instead, but even then, a "continue" seems to be just as good as having "break" (we'll just potentially loop a few more times before throwing the error)
My thinking is to start using this in 3.10 as internal API to get a feel for its strengths and weaknesses. It should be easy to rewrite the function to only use public API, and added to another project (like Cython). It should also be easy to make it public once we're sure it's the way forward.
What are your thoughts?
That approach definitely worked to give me confidence in Victor's public initialisation API changes that I didn't have in the original out-of-tree changes.