52

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?

denfromufa
  • 5,610
  • 13
  • 81
  • 138
detly
  • 29,332
  • 18
  • 93
  • 152

1 Answers1

58

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);
Azat Ibrakov
  • 9,998
  • 9
  • 38
  • 50
Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
  • 3
    I agree the docs are a little terse in that case. I updated my answer with the required call to `PyObject_Init()`. – Frédéric Hamidi Nov 12 '10 at 09:22
  • Wait, `PyObject_Init()` doesn't take any arguments, so how do you pass in the requisite initialisation arguments? – detly Nov 12 '10 at 09:25
  • @detly, you need to call the class object. See my updated answer. – Frédéric Hamidi Nov 12 '10 at 10:39
  • Aah, that makes more sense. Is it normal to get a compiler error ("assignment from incompatible pointer type")? – detly Nov 12 '10 at 16:45
  • 1
    @detly, since `PyTypeObject` "derives" from `PyObject` internally, and an explicit cast is used, there should be no warning. What's your compiler? – Frédéric Hamidi Nov 12 '10 at 17:01
  • GCC 4.4.5... and now that I've had a chance to check, it's only a warning, not an error. – detly Nov 13 '10 at 04:38
  • If returning this instance to a Python function, I'm assuming I don't need to increment the retain count to be safe? – jkp Apr 07 '11 at 15:07
  • 2
    @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 not `DECREF` it either. See http://edcjones.tripod.com/refcount.html for the gory details. – Frédéric Hamidi Apr 07 '11 at 16:11
  • 4
    one-liner: PyObject_CallFunction((PyObject *)&pyfoo_T, "si", "hello", 42); combines PyObject_CallObject + Py_BuildValue – Wiktor Tomczak Mar 05 '18 at 08:23
  • 1
    If there is only one argument, the Py_BuildValue call needs parenthesis in the format string. – dbn May 29 '19 at 21:41
  • 1
    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? – cheshirekow May 27 '20 at 19:07
  • Is this answer out of date? I can't find it in documentation – theonlygusti Mar 17 '21 at 03:54