MCPcopy Create free account
hub / github.com/Sigil-Ebook/Sigil / callPyObjMethod

Method callPyObjMethod

src/EmbedPython/EmbeddedPython.cpp:456–514  ·  view source on GitHub ↗

given an existing python object instance, invoke one of its methods grabs mutex to prevent need for Python GIL

Source from the content-addressed store, hash-verified

454// given an existing python object instance, invoke one of its methods
455// grabs mutex to prevent need for Python GIL
456QVariant EmbeddedPython::callPyObjMethod(PyObjectPtr &pyobj,
457 const QString &methname,
458 const QVariantList &args,
459 int *rv,
460 QString &tb,
461 bool ret_python_object)
462{
463 EmbeddedPython::m_mutex.lock();
464 PyGILState_STATE gstate = PyGILState_Ensure();
465
466 QVariant res = QVariant(QString());
467 PyObject* obj = pyobj.object();
468 PyObject* func = NULL;
469 PyObject* pyargs = NULL;
470 PyObject* pyres = NULL;
471 int idx = 0;
472
473 func = PyObject_GetAttrString(obj,methname.toUtf8().constData());
474 if (func == NULL) {
475 *rv = -1;
476 goto cleanup;
477 }
478
479 if (!PyCallable_Check(func)) {
480 *rv = -2;
481 goto cleanup;
482 }
483
484 // Build up Python argument List from args
485 pyargs = PyTuple_New(args.size());
486 idx = 0;
487 foreach(QVariant arg, args) {
488 PyTuple_SetItem(pyargs, idx, QVariantToPyObject(arg));
489 idx++;
490 }
491
492 pyres = PyObject_CallObject(func, pyargs);
493 if (pyres == NULL) {
494 *rv = -3;
495 goto cleanup;
496 }
497
498 *rv = 0;
499
500 res = PyObjectToQVariant(pyres, ret_python_object);
501
502 cleanup:
503 if (PyErr_Occurred() != NULL) {
504 QString default_error = "Python Object Method Invocation Error: " + methname;
505 tb = getPythonErrorTraceback(default_error);
506 }
507 Py_XDECREF(pyres);
508 Py_XDECREF(pyargs);
509 Py_XDECREF(func);
510
511 PyGILState_Release(gstate);
512 EmbeddedPython::m_mutex.unlock();
513 return res;

Calls 3

objectMethod · 0.80
QStringClass · 0.70
sizeMethod · 0.45

Tested by

no test coverage detected