]> granicus.if.org Git - icinga2/commitdiff
Python: implement support for marshalling arrays
authorGunnar Beutner <gunnar.beutner@netways.de>
Thu, 14 Mar 2013 13:00:10 +0000 (14:00 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Thu, 14 Mar 2013 13:06:07 +0000 (14:06 +0100)
Fixes #3858

lib/python/pythonlanguage.cpp
lib/python/pythonlanguage.h

index e9491472122ba92951d0a8a5821123e0ff23cee3..77a5425bf861acda2cf5372de509ccac4b4d3bcd 100644 (file)
@@ -27,7 +27,7 @@ REGISTER_SCRIPTLANGUAGE("Python", PythonLanguage);
 
 PyMethodDef PythonLanguage::m_NativeMethodDef[] = {
        { "RegisterFunction", &PythonLanguage::PyRegisterFunction, METH_VARARGS, NULL },
-       { NULL, NULL } /* sentinel */
+       { NULL, NULL, NULL, NULL } /* sentinel */
 };
 
 PythonLanguage::PythonLanguage(void)
@@ -60,12 +60,11 @@ void PythonLanguage::InitializeOnce(void)
        PyEval_ReleaseLock();
 
        String name;
-       ScriptFunction::Ptr function;
-       BOOST_FOREACH(tie(name, function), ScriptFunction::GetFunctions()) {
-               RegisterNativeFunction(name, function);
+       BOOST_FOREACH(tie(name, tuples::ignore), ScriptFunction::GetFunctions()) {
+               RegisterNativeFunction(name);
        }
 
-       ScriptFunction::OnRegistered.connect(boost::bind(&PythonLanguage::RegisterNativeFunction, this, _1, _2));
+       ScriptFunction::OnRegistered.connect(boost::bind(&PythonLanguage::RegisterNativeFunction, this, _1));
        ScriptFunction::OnUnregistered.connect(boost::bind(&PythonLanguage::UnregisterNativeFunction, this, _1));
 
        m_Initialized = true;
@@ -153,9 +152,26 @@ PyObject *PythonLanguage::MarshalToPython(const Value& value)
                                        PyObject *dv = MarshalToPython(value);
 
                                        PyDict_SetItemString(pdict, key.CStr(), dv);
+
+                                       Py_DECREF(dv);
                                }
 
                                return pdict;
+                       } else if (value.IsObjectType<Array>()) {
+                               Array::Ptr arr = value;
+                               ObjectLock olock(arr);
+
+                               PyObject *plist = PyList_New(0);
+
+                               BOOST_FOREACH(const Value& value, arr) {
+                                       PyObject *dv = MarshalToPython(value);
+
+                                       PyList_Append(plist, dv);
+
+                                       Py_DECREF(dv);
+                               }
+
+                               return plist;
                        }
 
                        Py_INCREF(Py_None);
@@ -177,13 +193,24 @@ Value PythonLanguage::MarshalFromPython(PyObject *value)
                Py_ssize_t pos = 0;
 
                while (PyDict_Next(value, &pos, &dk, &dv)) {
-                   String ik = PyString_AsString(dk);
-                   Value iv = MarshalFromPython(dv);
+                       String ik = PyString_AsString(dk);
+                       Value iv = MarshalFromPython(dv);
 
-                   dict->Set(ik, iv);
+                       dict->Set(ik, iv);
                }
 
                return dict;
+       } else if (PyList_Check(value)) {
+               Array::Ptr arr = boost::make_shared<Array>();
+
+               for (Py_ssize_t pos = 0; pos < PyList_Size(value); pos++) {
+                       PyObject *dv = PyList_GetItem(value, pos);
+                       Value iv = MarshalFromPython(dv);
+
+                       arr->Add(iv);
+               }
+
+               return arr;
        } else if (PyTuple_Check(value) && PyTuple_Size(value) == 2) {
                PyObject *ptype, *pname;
 
@@ -287,8 +314,6 @@ PyObject *PythonLanguage::PyCallNativeFunction(PyObject *self, PyObject *args)
        try {
                ScriptTask::Ptr task = boost::make_shared<ScriptTask>(function, arguments);
                task->Start();
-               task->Wait();
-
                result = task->GetResult();
        } catch (const std::exception& ex) {
                PyEval_RestoreThread(tstate);
@@ -308,9 +333,8 @@ PyObject *PythonLanguage::PyCallNativeFunction(PyObject *self, PyObject *args)
  * Registers a native function.
  *
  * @param name The name of the native function.
- * @param function The function.
  */
-void PythonLanguage::RegisterNativeFunction(const String& name, const ScriptFunction::Ptr& function)
+void PythonLanguage::RegisterNativeFunction(const String& name)
 {
        ObjectLock olock(this);
 
@@ -357,7 +381,7 @@ void PythonLanguage::UnregisterNativeFunction(const String& name)
        (void) PyThreadState_Swap(tstate);
 }
 
-PyObject *PythonLanguage::PyRegisterFunction(PyObject *self, PyObject *args)
+PyObject *PythonLanguage::PyRegisterFunction(PyObject *, PyObject *args)
 {
        char *name;
        PyObject *object;
@@ -390,8 +414,6 @@ PyObject *PythonLanguage::PyRegisterFunction(PyObject *self, PyObject *args)
  */
 PythonInterpreter *PythonLanguage::GetCurrentInterpreter(void)
 {
-       ObjectLock olock(this);
-
        return m_CurrentInterpreter;
 }
 
@@ -402,7 +424,5 @@ PythonInterpreter *PythonLanguage::GetCurrentInterpreter(void)
  */
 void PythonLanguage::SetCurrentInterpreter(PythonInterpreter *interpreter)
 {
-       ObjectLock olock(this);
-
        m_CurrentInterpreter = interpreter;
 }
index fc92ff2cc7679fb907eb84eb47b6d4e1788ffe13..22efffa32b6bcc296966341eda7af8158ce91cf4 100644 (file)
@@ -58,7 +58,7 @@ private:
        PyObject *m_TracebackModule;
        static PythonInterpreter *m_CurrentInterpreter;
 
-       void RegisterNativeFunction(const String& name, const ScriptFunction::Ptr& function);
+       void RegisterNativeFunction(const String& name);
        void UnregisterNativeFunction(const String& name);
 
        static PyObject *PyCallNativeFunction(PyObject *self, PyObject *args);