diff --git a/src/nrnpython/nrnpy_p2h.cpp b/src/nrnpython/nrnpy_p2h.cpp index 8ea32f97b2..fc0a4d085b 100644 --- a/src/nrnpython/nrnpy_p2h.cpp +++ b/src/nrnpython/nrnpy_p2h.cpp @@ -18,7 +18,7 @@ namespace nb = nanobind; static char* nrnpyerr_str(); -static PyObject* nrnpy_pyCallObject(PyObject*, PyObject*); +static nb::object nrnpy_pyCallObject(nb::callable, PyObject*); static PyObject* main_module; static PyObject* main_namespace; @@ -42,15 +42,12 @@ static void p_destruct(void* v) { Member_func p_members[] = {{nullptr, nullptr}}; static void call_python_with_section(Object* pyact, Section* sec) { - PyObject* po = ((Py2Nrn*) pyact->u.this_pointer)->po_; - PyObject* r; + nb::callable po = nb::borrow(((Py2Nrn*) pyact->u.this_pointer)->po_); nanobind::gil_scoped_acquire lock{}; - PyObject* args = PyTuple_Pack(1, (PyObject*) newpysechelp(sec)); - r = nrnpy_pyCallObject(po, args); - Py_XDECREF(args); - Py_XDECREF(r); - if (!r) { + nb::tuple args = nb::make_tuple(reinterpret_cast(newpysechelp(sec))); + nb::object r = nrnpy_pyCallObject(po, args.ptr()); + if (!r.is_valid()) { char* mes = nrnpyerr_str(); if (mes) { Fprintf(stderr, "%s\n", mes); @@ -109,12 +106,12 @@ Object* nrnpy_pyobject_in_obj(PyObject* po) { return on; } -static PyObject* nrnpy_pyCallObject(PyObject* callable, PyObject* args) { +static nb::object nrnpy_pyCallObject(nb::callable callable, PyObject* args) { // When hoc calls a PythonObject method, then in case python // calls something back in hoc, the hoc interpreter must be // at the top level HocTopContextSet - PyObject* p = PyObject_CallObject(callable, args); + PyObject* p = PyObject_CallObject(callable.ptr(), args); #if 0 printf("PyObject_CallObject callable\n"); PyObject_Print(callable, stdout, 0); @@ -142,7 +139,7 @@ printf("\nreturn %p\n", p); } } **/ - return p; + return nb::steal(p); } static void py2n_component(Object* ob, Symbol* sym, int nindex, int isfunc) { @@ -199,7 +196,7 @@ static void py2n_component(Object* ob, Symbol* sym, int nindex, int isfunc) { } } // printf("PyObject_CallObject %s %p\n", sym->name, tail); - result = nrnpy_pyCallObject(tail, args); + result = nrnpy_pyCallObject(nb::borrow(tail), args).release().ptr(); Py_DECREF(args); // PyObject_Print(result, stdout, 0); // printf(" result of call\n"); @@ -330,36 +327,22 @@ static void hpoasgn(Object* o, int type) { } } -static PyObject* hoccommand_exec_help1(PyObject* po) { - PyObject* r; - // PyObject_Print(po, stdout, 0); - // printf("\n"); - if (PyTuple_Check(po)) { - PyObject* args = PyTuple_GetItem(po, 1); - if (!PyTuple_Check(args)) { - args = PyTuple_Pack(1, args); - } else { - Py_INCREF(args); +static nb::object hoccommand_exec_help1(nb::object po) { + if (nb::tuple::check_(po)) { + nb::object args = po[1]; + if (!nb::tuple::check_(args)) { + args = nb::make_tuple(args); } - // PyObject_Print(PyTuple_GetItem(po, 0), stdout, 0); - // printf("\n"); - // PyObject_Print(args, stdout, 0); - // printf("\n"); - // printf("threadstate %p\n", PyThreadState_GET()); - r = nrnpy_pyCallObject(PyTuple_GetItem(po, 0), args); - Py_DECREF(args); + return nrnpy_pyCallObject(po[0], args.ptr()); } else { - PyObject* args = PyTuple_New(0); - r = nrnpy_pyCallObject(po, args); - Py_DECREF(args); + return nrnpy_pyCallObject(nb::borrow(po), nb::tuple().ptr()); } - return r; } -static PyObject* hoccommand_exec_help(Object* ho) { +static nb::object hoccommand_exec_help(Object* ho) { PyObject* po = ((Py2Nrn*) ho->u.this_pointer)->po_; // printf("%s\n", hoc_object_name(ho)); - return hoccommand_exec_help1(po); + return hoccommand_exec_help1(nb::borrow(po)); } static double praxis_efun(Object* ho, Object* v) { @@ -370,9 +353,9 @@ static double praxis_efun(Object* ho, Object* v) { PyObject* po = Py_BuildValue("(OO)", pc, pv); Py_XDECREF(pc); Py_XDECREF(pv); - PyObject* r = hoccommand_exec_help1(po); + nb::object r = hoccommand_exec_help1(nb::borrow(po)); Py_XDECREF(po); - if (!r) { + if (!r.is_valid()) { char* mes = nrnpyerr_str(); if (mes) { Fprintf(stderr, "%s\n", mes); @@ -384,18 +367,14 @@ static double praxis_efun(Object* ho, Object* v) { } return 1e9; // SystemExit? } - PyObject* pn = PyNumber_Float(r); - double x = PyFloat_AsDouble(pn); - Py_XDECREF(pn); - Py_XDECREF(r); - return x; + return static_cast(nb::float_(r)); } static int hoccommand_exec(Object* ho) { nanobind::gil_scoped_acquire lock{}; - PyObject* r = hoccommand_exec_help(ho); - if (r == NULL) { + nb::object r = hoccommand_exec_help(ho); + if (!r.is_valid()) { char* mes = nrnpyerr_str(); if (mes) { std::string tmp{"Python Callback failed [hoccommand_exec]:\n"}; @@ -407,21 +386,18 @@ static int hoccommand_exec(Object* ho) { PyErr_Print(); } } - Py_XDECREF(r); - return (r != NULL); + return r.is_valid(); } static int hoccommand_exec_strret(Object* ho, char* buf, int size) { nanobind::gil_scoped_acquire lock{}; - PyObject* r = hoccommand_exec_help(ho); - if (r) { - PyObject* pn = PyObject_Str(r); - Py2NRNString str(pn); - Py_XDECREF(pn); + nb::object r = hoccommand_exec_help(ho); + if (r.is_valid()) { + nb::str pn(r); + Py2NRNString str(pn.ptr()); strncpy(buf, str.c_str(), size); buf[size - 1] = '\0'; - Py_XDECREF(r); } else { char* mes = nrnpyerr_str(); if (mes) { @@ -433,20 +409,16 @@ static int hoccommand_exec_strret(Object* ho, char* buf, int size) { PyErr_Print(); } } - return (r != NULL); + return r.is_valid(); } static void grphcmdtool(Object* ho, int type, double x, double y, int key) { - PyObject* po = ((Py2Nrn*) ho->u.this_pointer)->po_; - PyObject* r; + nb::callable po = nb::borrow(((Py2Nrn*) ho->u.this_pointer)->po_); nanobind::gil_scoped_acquire lock{}; - PyObject* args = PyTuple_Pack( - 4, PyInt_FromLong(type), PyFloat_FromDouble(x), PyFloat_FromDouble(y), PyInt_FromLong(key)); - r = nrnpy_pyCallObject(po, args); - Py_XDECREF(args); - Py_XDECREF(r); - if (!r) { + nb::tuple args = nb::make_tuple(type, x, y, key); + nb::object r = nrnpy_pyCallObject(po, args.ptr()); + if (!r.is_valid()) { char* mes = nrnpyerr_str(); if (mes) { Fprintf(stderr, "%s\n", mes); @@ -492,8 +464,7 @@ static Object* callable_with_args(Object* ho, int narg) { } static double func_call(Object* ho, int narg, int* err) { - PyObject* po = ((Py2Nrn*) ho->u.this_pointer)->po_; - PyObject* r; + nb::callable po = nb::borrow(((Py2Nrn*) ho->u.this_pointer)->po_); nanobind::gil_scoped_acquire lock{}; PyObject* args = PyTuple_New((Py_ssize_t) narg); @@ -512,10 +483,10 @@ static double func_call(Object* ho, int narg, int* err) { } } - r = nrnpy_pyCallObject(po, args); + nb::object r = nrnpy_pyCallObject(po, args); Py_XDECREF(args); double rval = 0.0; - if (r == NULL) { + if (!r.is_valid()) { if (!err || *err) { char* mes = nrnpyerr_str(); if (mes) { @@ -535,12 +506,9 @@ static double func_call(Object* ho, int narg, int* err) { *err = 1; } } else { - if (nrnpy_numbercheck(r)) { - PyObject* pn = PyNumber_Float(r); - rval = PyFloat_AsDouble(pn); - Py_XDECREF(pn); + if (nrnpy_numbercheck(r.ptr())) { + rval = static_cast(nb::float_(r)); } - Py_XDECREF(r); if (err) { *err = 0; } // success