From 65e55c20faebdba2b3757bfe0be7b0f2c6371549 Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Thu, 15 Aug 2024 14:07:01 +0200 Subject: [PATCH] nanobind: use loads and dumps as callable (#3043) --- src/nrnpython/nrnpy_p2h.cpp | 47 ++++++++++--------------------------- 1 file changed, 12 insertions(+), 35 deletions(-) diff --git a/src/nrnpython/nrnpy_p2h.cpp b/src/nrnpython/nrnpy_p2h.cpp index fddf59ebbe..0164c2b667 100644 --- a/src/nrnpython/nrnpy_p2h.cpp +++ b/src/nrnpython/nrnpy_p2h.cpp @@ -635,19 +635,12 @@ static void setpickle() { // note that *size includes the null terminating character if it exists static std::vector pickle(PyObject* p) { - PyObject* arg = PyTuple_Pack(1, p); - PyObject* r = nrnpy_pyCallObject(dumps.ptr(), arg); - Py_XDECREF(arg); + auto r = nb::borrow(dumps(nb::borrow(p))); if (!r && PyErr_Occurred()) { PyErr_Print(); } assert(r); - assert(PyBytes_Check(r)); - std::size_t size = PyBytes_Size(r); - char* buf = PyBytes_AsString(r); - std::vector ret(buf, buf + size); - Py_XDECREF(r); - return ret; + return std::vector(r.c_str(), r.c_str() + r.size()); } static std::vector po2pickle(Object* ho) { @@ -661,10 +654,7 @@ static std::vector po2pickle(Object* ho) { } static nb::object unpickle(const char* s, std::size_t len) { - nb::bytes string(s, len); - nb::list args; - args.append(string); - return loads(*args); + return loads(nb::bytes(s, len)); } static nb::object unpickle(const std::vector& s) { @@ -743,33 +733,22 @@ std::vector call_picklef(const std::vector& fname, int narg) { // fname is a pickled callable, narg is the number of args on the // hoc stack with types double, char*, hoc Vector, and PythonObject // callable return must be pickleable. - PyObject* args = 0; - PyObject* result = 0; - PyObject* callable; - setpickle(); - PyObject* ps = PyBytes_FromStringAndSize(fname.data(), fname.size()); - args = PyTuple_Pack(1, ps); - callable = nrnpy_pyCallObject(loads.ptr(), args); + nb::bytes ps(fname.data(), fname.size()); + + auto callable = nb::borrow(loads(ps)); assert(callable); - Py_XDECREF(args); - Py_XDECREF(ps); - args = PyTuple_New(narg); + nb::list args{}; for (int i = 0; i < narg; ++i) { - PyObject* arg = nrnpy_hoc_pop("call_picklef"); - if (PyTuple_SetItem(args, narg - 1 - i, arg)) { - assert(0); - } - // Py_XDECREF(arg); + nb::object arg = nb::steal(nrnpy_hoc_pop("call_picklef")); + args.append(arg); } - result = nrnpy_pyCallObject(callable, args); - Py_DECREF(callable); - Py_DECREF(args); + nb::object result = callable(*args); if (!result) { char* mes = nrnpyerr_str(); if (mes) { - Fprintf(stderr, "%s\n", mes); + std::cerr << mes << std::endl; free(mes); hoc_execerror("PyObject method call failed:", NULL); } @@ -777,9 +756,7 @@ std::vector call_picklef(const std::vector& fname, int narg) { PyErr_Print(); } } - auto rs = pickle(result); - Py_XDECREF(result); - return rs; + return pickle(result.ptr()); } #include "nrnmpi.h"