Why are some Python api like "register_class()" encoded in C differently than other api?

Why is the Python api register_class() encoded in C differently than other api ?

What are some reasons for someone to create other Python functions in the same manner as register_class() ?

I don’t really understand the question. Can you maybe be a bit more specific?

Aside from the binding mechanism listed below, I - think - that there are two main ways that the Python api are encoded. One way encodes Python functions and variables in

There you’ll find functions that, at least at some level, act as a Python binding mechanism. Functions like: RNA_def_struct(), RNA_def_property()

In other areas of the C codebase you’ll also see code like MESH_OT_primitive_grid_add()

BUT for register_class() and a number of other api we see the third method for binding:

PyMethodDef meth_bpy_register_class = {"register_class", pyrna_register_class, METH_O, pyrna_register_class_doc};

static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class)

I don’t fully understand why register_class() or unregister_class() or other similar PyCFunction api are bound to Python differently.

I’m looking into the possibility of creating a script based sorting and filtering system for the Outliner and that’s a big reason why I’m interested.

I suspect that the difference is that some objects are C++ classes -> already in a class format, with overloaded operators, and methods. However, a portion of the source is still written in C, which only supports structs and functions, rather than any kind of classes.

1 Like


Yeah, I think I kinda see where you’re going… I don’t know if you’re right or even if I fully yet understand what you’ve wrote but I sorta see.

WIth very little research into the matter, I was suspecting that since the other two Python binding mechanisms I listed are not very direct ways of binding, and that since PyCFunction functions are pretty direct - that PyCFunction functions like register_class() acted as a foundation for the other two binding mechanisms. In other words, I was suspecting all other C api are not even actually bound to Python but rather are executed internally within PyCFunction functions. But I don’t really know for sure yet

EDIT: After looking a little more at the code - I’m suspecting more and more that you might be right.

My response was just a guess.

Googling yielded this stackexchange:

As far as I can tell, the register_class function is actually for registering classes in addons, not for binding C functions. I suspect that many of the C APIs for python are actually loaded as addons, rather than in a special way, to simplify the loading process, and only maintain less code.

I would suspect that the classes provided by the python API are python classes that call specific PyCFunctions in their methods. I suspect that PyCFunction can only call C functions, not C++ functions or classes, because C++ uses name mangling to support overloading. I may be entirely off the mark here though.

Now, looking deeper into the code base, I suspect that the RNA_* methods in makesrna/intern actually generate the Python bindings from the C/C++ source, automatically updating the python api to match the C/C++ api. It would appear the register_class only applies to addons, not the underlying api.

1 Like

I think “binding” was too strong of a word, I edited my comment to say that the other api may have been executed internally within the PyCFunction functions. Of course, I’m pretty sure you’re guess is much more likely to be right than mine, in fact I’m holding onto my idea by a thread. Thanks for the help.

I am still interested in more info if anyone else has anything to add.

1 Like

You know what, unless someone thinks otherwise, I think I’ll just go with using the binding functions in …\makesrna\intern for creating api for sorting and filtering the Outliner.

Thanks again.