void PythonTuple::SetItemAtIndex(uint32_t index, const PythonObject &object) { if (IsAllocated() && object.IsValid()) { // PyTuple_SetItem is documented to "steal" a reference, so we need to // convert it to an owned reference by incrementing it. Py_INCREF(object.get()); PyTuple_SetItem(m_py_obj, index, object.get()); } }
PythonObject PythonDictionary::GetItemForKey(const PythonObject &key) const { if (IsAllocated() && key.IsValid()) return PythonObject(PyRefType::Borrowed, PyDict_GetItem(m_py_obj, key.get())); return PythonObject(); }
void PythonList::AppendItem(const PythonObject &object) { if (IsAllocated() && object.IsValid()) { // `PyList_Append` does *not* steal a reference, so do not call `Py_INCREF` // here like we do with `PyList_SetItem`. PyList_Append(m_py_obj, object.get()); } }
PythonObject callFunctionWithArgs( PythonObject function, const std::vector<PythonObject>& args, const std::vector<std::pair<std::string, PythonObject>>& kwargs) { if (!PyCallable_Check(function.get())) { throw WrappyError("Wrappy: Supplied object isn't callable."); } // Build tuple size_t sz = args.size(); PythonObject tuple(PythonObject::owning {}, PyTuple_New(sz)); if (!tuple) { PyErr_Print(); throw WrappyError("Wrappy: Couldn't create python typle."); } for (size_t i = 0; i < sz; ++i) { PyObject* arg = args.at(i).get(); Py_XINCREF(arg); // PyTuple_SetItem steals a reference PyTuple_SetItem(tuple.get(), i, arg); } // Build kwargs dict PythonObject dict(PythonObject::owning {}, PyDict_New()); if (!dict) { PyErr_Print(); throw WrappyError("Wrappy: Couldn't create python dictionary."); } for (const auto& kv : kwargs) { PyDict_SetItemString(dict.get(), kv.first.c_str(), kv.second.get()); } PythonObject res(PythonObject::owning{}, PyObject_Call(function.get(), tuple.get(), dict.get())); if (!res) { PyErr_Print(); throw WrappyError("Wrappy: Error calling function"); } return res; }
TEST_F(PythonDataObjectsTest, TestPythonCallableInvoke) { auto list = m_builtins_module.ResolveName("list").AsType<PythonCallable>(); PythonInteger one(1); PythonString two("two"); PythonTuple three = {one, two}; PythonTuple tuple_to_convert = {one, two, three}; PythonObject result = list({tuple_to_convert}); EXPECT_TRUE(PythonList::Check(result.get())); auto list_result = result.AsType<PythonList>(); EXPECT_EQ(3U, list_result.GetSize()); EXPECT_EQ(one.get(), list_result.GetItemAtIndex(0).get()); EXPECT_EQ(two.get(), list_result.GetItemAtIndex(1).get()); EXPECT_EQ(three.get(), list_result.GetItemAtIndex(2).get()); }
void PythonDictionary::SetItemForKey(const PythonObject &key, const PythonObject &value) { if (IsAllocated() && key.IsValid() && value.IsValid()) PyDict_SetItem(m_py_obj, key.get(), value.get()); }
void PythonDictionary::SetItemForKey (const PythonString &key, const PythonObject &value) { if (m_py_obj && key && value) PyDict_SetItem(m_py_obj, key.get(), value.get()); }
PythonString::PythonString (const PythonObject &object) : PythonObject() { Reset(object.get()); // Use "Reset()" to ensure that py_obj is a string }
PythonDictionary::PythonDictionary (const PythonObject &object) : PythonObject() { Reset(object.get()); // Use "Reset()" to ensure that py_obj is a dictionary }
void PythonList::AppendItem (const PythonObject &object) { if (m_py_obj && object) PyList_Append(m_py_obj, object.get()); }
void PythonList::SetItemAtIndex (uint32_t index, const PythonObject & object) { if (m_py_obj && object) PyList_SetItem(m_py_obj, index, object.get()); }
PythonList::PythonList (const PythonObject &object) : PythonObject() { Reset(object.get()); // Use "Reset()" to ensure that py_obj is a list }
PythonInteger::PythonInteger (const PythonObject &object) : PythonObject() { Reset(object.get()); // Use "Reset()" to ensure that py_obj is a integer type }