PyO3 / pyo3

Rust bindings for the Python interpreter
https://pyo3.rs
Other
11.47k stars 694 forks source link

[Feature request] Directly expose tp_bases, tp_mro, and tp_subclasses on PyType in high-level API #4192

Closed Hooksie closed 1 month ago

Hooksie commented 1 month ago

Please note, am I generally unfamiliar with the Python C ffi layer, so please excuse any errors or weird assumptions.

I am prototyping a library in pyo3 that introspects type hierarchy when defining new types. In pure Python, i would do this through either __bases__ or __mro__ (and in some rarer cases, __subclasses__()).

Since these all exist within the slots of the PyTypeObject, I wanted to be able to access these directly. Instead, it appears I need to call (for example) cls.getattr("__bases__") and then downcast to a tuple for safe code. Alternatively, I can use as_type_ptr() but end up with unsafe code (and I'm still not sure this is a good idea).

Ideally, it would be nice to have PyType::bases (accessing tp_bases), PyType::mro (accessing tp_mro), and PyType::subclasses (accessing tp_subclasses) available as higher-level APIs.

davidhewitt commented 1 month ago

I have someone at the PyCon US sprints experimenting with this today, so hopefully we can figure out an implementation 😄

Cheukting commented 1 month ago

I have someone at the PyCon US sprints experimenting with this today, so hopefully we can figure out an implementation 😄

That's me :-)

Cheukting commented 1 month ago

According to this (https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_subclasses) seems tp_subclasses is for internal use only. Maybe we should work on __bases__ and __mro__ first.

Hooksie commented 1 month ago

@Cheukting I was reading the docs, and noticed the same as well. I think exposing tp_subclasses probably doesnt fall into the same category as the other two here. I think it's reasonable to disregard for now