Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyObject_CallMethod with keyword arguments

I'm trying to embed a Python (2.7) library in my C application and I'm using the Python/C API to call Python code from C. I need to call a Python method that takes keyword arguments. Semantically, I'm trying to achieve the equivalent of the following line in Python:

myobject.dosomething('blahdy blah', somearg=True)

By reading the documentation, I have managed to get as far as the following, but this doesn't pass in the keyword arguments:

PyObject_CallMethod(myobject, "dosomething", "s", "blahdy blah");

I'm not super familiar with Python and I'm kind of stuck at this point as the documentation is not entirely clear on this and Google searches didn't turn up much useful info either. I'd appreciate any help.

like image 533
Tamas Czinege Avatar asked May 27 '13 16:05

Tamas Czinege


People also ask

What is keyword argument with example?

Keyword arguments (or named arguments) are values that, when passed into a function, are identifiable by specific parameter names. A keyword argument is preceded by a parameter and the assignment operator, = . Keyword arguments can be likened to dictionaries in that they map a value to a keyword.

What is the difference between arguments and keyword arguments?

There are two types of arguments in a function which are positional arguments (declared by a name only) and keyword arguments (declared by a name and a default value). When a function is called, values for positional arguments must be given.

What is Call () python?

To "call" means to make a reference in your code to a function that is written elsewhere. This function "call" can be made to the standard Python library (stuff that comes installed with Python), third-party libraries (stuff other people wrote that you want to use), or your own code (stuff you wrote).

What is PyObject?

PyObject is an object structure that you use to define object types for Python. All Python objects share a small number of fields that are defined using the PyObject structure. All other object types are extensions of this type. PyObject tells the Python interpreter to treat a pointer to an object as an object.


2 Answers

Tamas's answer will get the job done, but it will also leak memory. To avoid leaks, use

PyObject *args = Py_BuildValue("(s)", "blahdy blah");    
PyObject *keywords = PyDict_New();
PyDict_SetItemString(keywords, "somearg", Py_True);
PyObject *myobject_method = PyObject_GetAttrString(myobject, "do something");

PyObject *result = PyObject_Call(myobject_method, args, keywords);
Py_DECREF(args);
Py_DECREF(keywords);
Py_DECREF(myobject_method);

// Do something with the result

Py_DECREF(result);

Of course, if there are any errors or exceptions in the Python code some of the PyObjects will be NULL and your program will probably crash. Checking for NULL results and/or using Py_DECREFX() can help you avoid this.

like image 127
clwainwright Avatar answered Oct 13 '22 19:10

clwainwright


In the end I used PyObject_Call to do this (thanks Bakuriu for the hint!). Just in case anyone wonders how to do that, here's my code:

PyObject *args = Py_BuildValue("(s)", "blahdy blah");    
PyObject *keywords = PyDict_New();
PyDict_SetItemString(keywords, "somearg", Py_True);

PyObject_Call(PyObject_GetAttrString(myobject, "do something"), args, keywords);
Py_DECREF(args);
Py_DECREF(keywords);
like image 22
Tamas Czinege Avatar answered Oct 13 '22 19:10

Tamas Czinege