Python Forum
Create a new subclass in a Python extension based on an existing class
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Create a new subclass in a Python extension based on an existing class
#1
I am writing a custom module using the C API for an application. In the extension, I want to define a new enum.IntEnum subclass to be part of the C module.

I can't figure out how to do that. All the help that I can find is for creating a completely new custom class or module but nothing for a subclass of an existing Python class.

By extension, I can't find any information on how to use the members of the subclass withing the C code.

Any help on this is appreciated. Thank you.
Reply
#2
This seems strange to me. Why do you need the subclass of enum.IntEnum do be defined in C language? Can' you just subclass the Python class using Python code (such code could be embedded in your C code) ?
« We can solve any problem by introducing an extra level of indirection »
Reply
#3
(Mar-24-2025, 04:02 PM)Gribouillis Wrote: This seems strange to me. Why do you need the subclass of enum.IntEnum do be defined in C language? Can' you just subclass the Python class using Python code (such code could be embedded in your C code) ?

How can I embed the Python code into C code? Are you referring to PyRun_SimpleScriptFlags()? I am fine with embedding Python code into the C code.
Reply
#4
Can you provide more information about what you are trying to accomplish? Maybe an example of the enumeration and how it would be used in the C code?
Reply
#5
(Mar-24-2025, 07:03 PM)deanhystad Wrote: Can you provide more information about what you are trying to accomplish? Maybe an example of the enumeration and how it would be used in the C code?

The C code maintains 3 different types of threads. The thread functions requires some parameters, which need to be configured before they are started. So, I have 3 different structures:

struct thread1 {
    int params1;
    int params2;
};

struct thread2 {
    int params3;
    int params4;
};

strcut thread3 {
    int params5;
    int params6;
};
In the method exposed by the C code where the configuration happens, I want to have something like this:

switch (thread_type) {
case THREAD1:
    ...
    break;
case THREAD2:
    ....
    break;
case THREAD3;
    ....
    break;
};
So both the Python code and the C code work with the same values, I want the module exposed by the C code to contain the following enumeration:

@enum.unique()
class ThreadType(enum.IntEnum):
    THREAD1 = enum.auto()
    THREAD2 = enum.auto()
    THREAD3 = enum.auto()
In this way, higher level python code can do:

import my_c_extension

data = {'param1': 2, 'param2': 10 }
my_c_extension.configure_thread(my_c_extension.ThreadType.THREAD1, data)
Hope this helps give a clearer picture.
Reply
#6
(Mar-24-2025, 05:37 PM)voidtrance Wrote: How can I embed the Python code into C code? Are you referring to PyRun_SimpleScriptFlags()? I am fine with embedding Python code into the C code.
I compiled an example, starting from the extension module shown here, and I added Python code to define the subclass at module initialization. Here is the complete C code
// file mycextension.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>

int multiplier(int a, int b)
{
    return a * b;
}

static PyObject *c_multiplier(PyObject *self, PyObject *args)
{
    int a;
    int b;
    int ret;
    if (!PyArg_ParseTuple(args, "ii", &a, &b))
    {
        return NULL;
    }
    ret = multiplier(a, b);
    return Py_BuildValue("i", ret);
}

static PyMethodDef module_methods[] = {
    {"multiplier", c_multiplier, METH_VARARGS, "Multiply two numbers."},
    {NULL, NULL, 0, NULL}};

static struct PyModuleDef c_extension =
    {
        PyModuleDef_HEAD_INIT,
        "c_extension", // the name of the module in Python
        "",            // The docstring in Python
        -1,            /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
        module_methods};

PyMODINIT_FUNC PyInit_c_extension(void)
{
    PyObject *ns;
    PyObject *mod;
    char* code =
    "import enum\n"
    "@enum.unique\n"
    "class ThreadType(enum.IntEnum):\n"
    "    THREAD1 = enum.auto()\n"
    "    THREAD2 = enum.auto()\n"
    "    THREAD3 = enum.auto()\n";
    mod = PyModule_Create(&c_extension);
    ns = PyObject_GetAttrString(mod, "__dict__");
    PyRun_String(code, Py_file_input, ns, ns);
    Py_DECREF(ns);
    return mod;
}
Here is the setup.py file
from distutils.core import setup, Extension

module = Extension("c_extension", sources=["mycextension.c"])

setup(
    name="c_extension",
    version="0.1",
    description="An example of C extension made callable to the Python API.",
    ext_modules=[module],
)
All this is installed by invoking python -m pip install . in the extension's directory.
Here is the result in the Python console
>>> import c_extension
>>> c_extension.ThreadType.THREAD1
<ThreadType.THREAD1: 1>
« We can solve any problem by introducing an extra level of indirection »
Reply
#7
(Mar-25-2025, 06:09 PM)Gribouillis Wrote: I compiled an example, starting from the extension module shown here, and I added Python code to define the subclass at module initialization.

Thank you for your help!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How to re-register .py file extension to new moved Python dir (on Windows)? pstein 5 1,203 Nov-06-2024, 03:06 PM
Last Post: DeaD_EyE
  How does this code create a class? Pedroski55 6 1,923 Apr-21-2024, 06:15 AM
Last Post: Gribouillis
  Python best library for Excel reports & review of existing code MasterOfDestr 4 5,011 Feb-14-2024, 03:39 PM
Last Post: MasterOfDestr
  Create dual folder on different path/drive based on the date agmoraojr 2 1,272 Jan-21-2024, 10:02 AM
Last Post: snippsat
  Python C Extension Module loading issue on Cygwin mesibo 0 1,323 Sep-22-2023, 05:41 AM
Last Post: mesibo
  Python beginner that needs an expression added to existing script markham 1 1,283 Sep-04-2023, 05:24 AM
Last Post: Pedroski55
  create new column based on condition arvin 12 4,123 Dec-13-2022, 04:53 PM
Last Post: jefsummers
  select Eof extension files based on text list of filenames with if condition RolanRoll 1 2,123 Apr-04-2022, 09:29 PM
Last Post: Larz60+
  Subclass initialized property used in parent class method. Is it bad coding practice? saavedra29 5 3,463 Feb-07-2022, 07:29 PM
Last Post: saavedra29
  Cannot convert the series to <class 'int'> when trying to create new dataframe column Mark17 3 10,259 Jan-20-2022, 05:15 PM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020