diff --git a/userland/libs/python_embed/pure.c b/userland/libs/python_embed/pure.c index 672ec32..377701c 100644 --- a/userland/libs/python_embed/pure.c +++ b/userland/libs/python_embed/pure.c @@ -254,13 +254,16 @@ my_native_module_MyDerivedNativeClass_init(my_native_module_MyDerivedNativeClass { static char *kwlist[] = {"first", "last", "number", "first2", "last2", "number2", NULL}; PyObject *first = NULL, *last = NULL, *first2 = NULL, *last2 = NULL, *tmp; - int number; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOiOOi", kwlist, - &first, &last, &number, &first2, &last2, &self->number2)) + int ret; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOOOi", kwlist, + &first, &last, &tmp, &first2, &last2, &self->number2)) return -1; - /* Call parent class constructor. TODO learn how to remove the - * "*2" args that are consumed by this constructor.. */ - if (my_native_module_MyNativeClassType.tp_init((PyObject *) self, args, kwds) < 0) + /* args is a PyTuple, extract the first 3 arguments into a new + * tuple to serve as arguments of the base class. */ + PyObject *base_args = PySequence_GetSlice(args, 0, 3); + ret = my_native_module_MyNativeClassType.tp_init((PyObject *) self, base_args, kwds); + Py_DECREF(base_args); + if (ret < 0) return -1; if (first2) { tmp = self->first2; @@ -306,7 +309,8 @@ my_native_module_MyDerivedNativeClass_name2(my_native_module_MyDerivedNativeClas PyErr_SetString(PyExc_AttributeError, "last2"); return NULL; } - return PyUnicode_FromFormat("%S %S %S %S", self->base.first, self->base.last, self->first2, self->last2); + return PyUnicode_FromFormat("%S %S %S %S", + self->base.first, self->base.last, self->first2, self->last2); } static PyMethodDef my_native_module_MyDerivedNativeClass_methods[] = { diff --git a/userland/libs/python_embed/pure.py b/userland/libs/python_embed/pure.py index a110ba6..82e5fac 100644 --- a/userland/libs/python_embed/pure.py +++ b/userland/libs/python_embed/pure.py @@ -23,7 +23,7 @@ def test_native_class(): my_native_object.first = 'ih' assert my_native_object.name() == 'ih ' - # TODO see TODO in pure.c. - #my_derived_native_object = my_native_module.MyDerivedNativeClass('ab', 'cd', 13, 'ef', 'gh', 21) - #print(my_derived_native_object.name2()) + my_derived_native_object = my_native_module.MyDerivedNativeClass('ab', 'cd', 13, 'ef', 'gh', 21) + assert my_derived_native_object.name() == 'ab cd' + assert my_derived_native_object.name2() == 'ab cd ef gh' return 13 diff --git a/userland/libs/python_embed/pure_cpp.cpp b/userland/libs/python_embed/pure_cpp.cpp index 887e375..2828f83 100644 --- a/userland/libs/python_embed/pure_cpp.cpp +++ b/userland/libs/python_embed/pure_cpp.cpp @@ -137,12 +137,12 @@ my_native_module_MyNativeClass_init(my_native_module_MyNativeClass *self, PyObje } static PyMemberDef my_native_module_MyNativeClass_members[] = { - {"first", T_OBJECT_EX, offsetof(my_native_module_MyNativeClass, first), 0, - "first name"}, - {"last", T_OBJECT_EX, offsetof(my_native_module_MyNativeClass, last), 0, - "last name"}, - {"number", T_INT, offsetof(my_native_module_MyNativeClass, number), 0, - "custom number"}, + {(char*)"first", T_OBJECT_EX, offsetof(my_native_module_MyNativeClass, first), 0, + (char*)"first name"}, + {(char*)"last", T_OBJECT_EX, offsetof(my_native_module_MyNativeClass, last), 0, + (char*)"last name"}, + {(char*)"number", T_INT, offsetof(my_native_module_MyNativeClass, number), 0, + (char*)"custom number"}, {NULL} }; @@ -232,13 +232,16 @@ my_native_module_MyDerivedNativeClass_init(my_native_module_MyDerivedNativeClass { static const char *kwlist[] = {"first", "last", "number", "first2", "last2", "number2", NULL}; PyObject *first = NULL, *last = NULL, *first2 = NULL, *last2 = NULL, *tmp; - int number; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOiOOi", (char**)kwlist, - &first, &last, &number, &first2, &last2, &self->number2)) + int ret; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOOOi", (char**)kwlist, + &first, &last, &tmp, &first2, &last2, &self->number2)) return -1; - /* Call parent class constructor. TODO learn how to remove the - * "*2" args that are consumed by this constructor.. */ - if (my_native_module_MyNativeClassType.tp_init((PyObject *) self, args, kwds) < 0) + /* args is a PyTuple, extract the first 3 arguments into a new + * tuple to serve as arguments of the base class. */ + PyObject *base_args = PySequence_GetSlice(args, 0, 3); + ret = my_native_module_MyNativeClassType.tp_init((PyObject *) self, base_args, kwds); + Py_DECREF(base_args); + if (ret < 0) return -1; if (first2) { tmp = self->first2; @@ -256,12 +259,12 @@ my_native_module_MyDerivedNativeClass_init(my_native_module_MyDerivedNativeClass } static PyMemberDef my_native_module_MyDerivedNativeClass_members[] = { - {"first2", T_OBJECT_EX, offsetof(my_native_module_MyDerivedNativeClass, first2), 0, - "first2 name2"}, - {"last2", T_OBJECT_EX, offsetof(my_native_module_MyDerivedNativeClass, last2), 0, - "last2 name2"}, - {"number2", T_INT, offsetof(my_native_module_MyDerivedNativeClass, number2), 0, - "custom number2"}, + {(char*)"first2", T_OBJECT_EX, offsetof(my_native_module_MyDerivedNativeClass, first2), 0, + (char*)"first2 name2"}, + {(char*)"last2", T_OBJECT_EX, offsetof(my_native_module_MyDerivedNativeClass, last2), 0, + (char*)"last2 name2"}, + {(char*)"number2", T_INT, offsetof(my_native_module_MyDerivedNativeClass, number2), 0, + (char*)"custom number2"}, {NULL} };