4

What is the appropriate way to return a tuple containing a None value from a C extension to Python? I know that a single None value can be created using

result = Py_BuildValue("");

and that a tuple can be created using something like

result = Py_BuildValue("(ii)", 123, 456);

but I do not see a way to combine this to get, for example, a tuple containing a proper integer and a None value.

Reinier Torenbeek
  • 16,669
  • 7
  • 46
  • 69

2 Answers2

5

There's only ever one None object in Python, and you can always refer to it in C as Py_None.

The code...

result = Py_BuildValue("");

...just increments the refcount of Py_None and returns its pointer, so it's the same as...

Py_INCREF(Py_None);
result = Py_None;

If you just want to return None, then use...

Py_INCREF(Py_None);
return Py_None;

...or, since Python 2.4, you can do the same thing with a macro...

Py_RETURN_NONE;

If you return it in a tuple, like this...

return Py_BuildValue("(O)", Py_None);

...there's no need to increment the refcount - Py_BuildValue() does that for you.

But if you return it in a tuple like this...

PyObject* tuple = PyTuple_New(1);
Py_INCREF(Py_None);
PyTuple_SetItem(tuple, 0, Py_None);
return tuple;

...then you have to increment the refcount, because PyTuple_SetItem() doesn't do it for you.

Aya
  • 39,884
  • 6
  • 55
  • 55
  • Is the explicit reference counting increment required when using `Py_BuildValue("(O)", Py_None)`? The [documentation of `Py_BuildValue()`](http://docs.python.org/2/c-api/arg.html#Py_BuildValue) for `O` states: *Pass a Python object untouched (except for its reference count, which is incremented by one)* – Reinier Torenbeek May 06 '13 at 14:56
  • @ReinierTorenbeek Sorry. I rechecked the docs, and accidentally read the wrong section, updated the answer, then realized the error, and reverted the answer. – Aya May 06 '13 at 14:57
  • @ReinierTorenbeek Updated answer again. FWIW, the latter approach will be marginally faster, because it doesn't have to parse a format string. – Aya May 06 '13 at 15:11
3
result = Py_BuildValue("(isi)", 123, NULL, 456);

Ref.: http://docs.python.org/2/c-api/arg.html#Py_BuildValue

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • 2
    ...or `Py_BuildValue("(iOi)", 123, Py_None, 456)` – Aya May 06 '13 at 14:29
  • Thanks, this works fine. Sorry for un-accepting your answer, I acted too quickly. I accepted Aya's answer because it seems more appropriate. Using a `NULL` string feels somewhat like a hack to me. – Reinier Torenbeek May 06 '13 at 14:43