Create an object using Python's C API
17,230
Call PyObject_New(), followed by PyObject_Init().
EDIT: The best way is to call the class object, just like in Python itself:
/* Pass two arguments, a string and an int. */
PyObject *argList = Py_BuildValue("si", "hello", 42);
/* Call the class object. */
PyObject *obj = PyObject_CallObject((PyObject *) &pyfoo_T, argList);
/* Release the argument list. */
Py_DECREF(argList);
Related videos on Youtube
Author by
detly
Updated on June 01, 2021Comments
-
detly almost 3 years
Say I have my object layout defined as:
typedef struct { PyObject_HEAD // Other stuff... } pyfoo;
...and my type definition:
static PyTypeObject pyfoo_T = { PyObject_HEAD_INIT(NULL) // ... pyfoo_new, };
How do I create a new instance of
pyfoo
somewhere within my C extension? -
Frédéric Hamidi over 13 yearsI agree the docs are a little terse in that case. I updated my answer with the required call to
PyObject_Init()
. -
detly over 13 yearsWait,
PyObject_Init()
doesn't take any arguments, so how do you pass in the requisite initialisation arguments? -
Frédéric Hamidi over 13 years@detly, you need to call the class object. See my updated answer.
-
detly over 13 yearsAah, that makes more sense. Is it normal to get a compiler error ("assignment from incompatible pointer type")?
-
Frédéric Hamidi over 13 years@detly, since
PyTypeObject
"derives" fromPyObject
internally, and an explicit cast is used, there should be no warning. What's your compiler? -
detly over 13 yearsGCC 4.4.5... and now that I've had a chance to check, it's only a warning, not an error.
-
jkp about 13 yearsIf returning this instance to a Python function, I'm assuming I don't need to increment the retain count to be safe?
-
Frédéric Hamidi about 13 years@jkp, if I'm not mistaken, the class object should already have
INCREF
ed the object it returned, because it just created it and intends to pass ownership to you in the first place. If you also intend to pass ownership of the new object to your caller, you should notDECREF
it either. See edcjones.tripod.com/refcount.html for the gory details. -
Wiktor Tomczak about 6 yearsone-liner: PyObject_CallFunction((PyObject *)&pyfoo_T, "si", "hello", 42); combines PyObject_CallObject + Py_BuildValue
-
dbn almost 5 yearsIf there is only one argument, the Py_BuildValue call needs parenthesis in the format string.
-
cheshirekow almost 4 yearsCan you expand on what you mean by "best"? Is there any reason to prefer CallObject over PyObject_New and PyObject_Init which are crossed out in the answer?
-
theonlygusti about 3 yearsIs this answer out of date? I can't find it in documentation