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);
Share:
17,230

Related videos on Youtube

detly
Author by

detly

Updated on June 01, 2021

Comments

  • detly
    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
    Frédéric Hamidi over 13 years
    I agree the docs are a little terse in that case. I updated my answer with the required call to PyObject_Init().
  • detly
    detly over 13 years
    Wait, PyObject_Init() doesn't take any arguments, so how do you pass in the requisite initialisation arguments?
  • Frédéric Hamidi
    Frédéric Hamidi over 13 years
    @detly, you need to call the class object. See my updated answer.
  • detly
    detly over 13 years
    Aah, that makes more sense. Is it normal to get a compiler error ("assignment from incompatible pointer type")?
  • Frédéric Hamidi
    Frédéric Hamidi over 13 years
    @detly, since PyTypeObject "derives" from PyObject internally, and an explicit cast is used, there should be no warning. What's your compiler?
  • detly
    detly over 13 years
    GCC 4.4.5... and now that I've had a chance to check, it's only a warning, not an error.
  • jkp
    jkp about 13 years
    If 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
    Frédéric Hamidi about 13 years
    @jkp, if I'm not mistaken, the class object should already have INCREFed 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 not DECREF it either. See edcjones.tripod.com/refcount.html for the gory details.
  • Wiktor Tomczak
    Wiktor Tomczak about 6 years
    one-liner: PyObject_CallFunction((PyObject *)&pyfoo_T, "si", "hello", 42); combines PyObject_CallObject + Py_BuildValue
  • dbn
    dbn almost 5 years
    If there is only one argument, the Py_BuildValue call needs parenthesis in the format string.
  • cheshirekow
    cheshirekow almost 4 years
    Can 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
    theonlygusti about 3 years
    Is this answer out of date? I can't find it in documentation