2 #include "../oc/code.h"
24 #include <unordered_map>
26 #include <nanobind/nanobind.h>
27 namespace nb = nanobind;
34 extern void* (*nrnpy_get_pyobj)(
Object* obj);
70 extern IvocVect* (*nrnpy_vec_from_python_p_)(
void*);
71 extern Object** (*nrnpy_vec_to_python_p_)(
void*);
72 extern Object** (*nrnpy_vec_as_numpy_helper_)(int,
double*);
116 #define HocTopContextSet \
117 if (hoc_thisobject) { \
120 assert(hoc_thisobject == 0);
121 #define HocContextRestore
141 if (PyType_Type.tp_init((
PyObject*) cls, args, kwds) < 0) {
158 if (ob->
index == ix) {
162 PyErr_Format(PyExc_IndexError,
"%s[%ld] instance does not exist", sym->
name, ix);
178 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE,
186 PyErr_SetString(PyExc_ValueError,
"Invalid data_handle");
195 }
catch (std::exception
const& e) {
196 std::ostringstream oss;
197 oss <<
"subscript out of range (array size or number of dimensions changed?)";
198 PyErr_SetString(PyExc_IndexError, oss.str().c_str());
207 if (!PyArg_ParseTuple(args,
"s", &cmd)) {
211 return PyBool_FromLong(b);
219 PyArg_ParseTuple(args,
"|d", &
hoc_ac_);
220 return Py_BuildValue(
"d",
hoc_ac_);
231 "Execute a hoc command, return True on success, False on failure."},
232 {
"hoc_ac",
hoc_ac_safe, METH_VARARGS,
"Get (or set) the scalar hoc_ac_."},
233 {
nullptr,
nullptr, 0,
nullptr}};
247 if (self->indices_) {
248 delete[]
self->indices_;
274 self->sym_ =
nullptr;
275 self->indices_ =
nullptr;
282 for (Py_ssize_t
i = 0;
i < PyTuple_Size(
subtype->tp_mro);
i++) {
288 hbase->
sym_ = symbol_result->second;
293 if (kwds && PyDict_Check(kwds) && (base = PyDict_GetItemString(kwds,
"hocbase"))) {
297 PyErr_SetString(PyExc_TypeError,
"HOC base class not valid");
300 PyDict_DelItemString(kwds,
"hocbase");
307 auto r = nb::steal(
hocobj_call(hbase, args, kwds));
317 return subself.release().ptr();
329 self->sym_ =
nullptr;
330 self->indices_ =
nullptr;
347 auto*
const self =
reinterpret_cast<PyHocObject*
>(pself);
356 cp.append(self->sym_->name);
358 for (
int i = 0;
i <
self->nindex_; ++
i) {
368 cp.append(
"<hoc ref value ");
372 cp.append(
"<hoc ref str \"");
373 cp.append(self->u.s_);
376 cp.append(
"<hoc ref pstr \"");
377 cp.append(*self->u.pstr_);
380 cp.append(
"<hoc ref value \"");
384 cp.append(
"<all section iterator next>");
386 cp.append(
"<SectionList iterator>");
388 std::ostringstream oss;
392 cp.append(
"<incomplete pointer to hoc array ");
393 cp.append(self->sym_->name);
396 cp.append(
"<TopLevelHocInterpreter>");
398 return Py_BuildValue(
"s", cp.c_str());
417 const nb::tuple tup(args);
418 for (
int i = 0;
i < tup.size(); ++
i) {
419 nb::object po(tup[
i]);
425 if (!str.is_valid()) {
432 hoc_execerr_ext(
"python string arg cannot decode into c_str. Pyerr message: %s",
487 if (!sym && strcmp(
name,
"delay") == 0) {
489 }
else if (!sym && ho->
aliases) {
498 if (sym && sym->
type == UNDEF) {
502 PyErr_Format(PyExc_LookupError,
"'%s' is not a defined hoc variable name.",
name);
548 int rval = PyNumber_Check(po);
550 if (rval == 1 && po->ob_type->tp_as_sequence) {
584 po.ptr()->ob_type =
location->second;
588 return po.release().ptr();
631 auto const px = hoc_pop_handle<double>();
635 result = nb::steal(Py_BuildValue(
"d", *px));
652 return result.release().ptr();
660 if (PyArg_Parse(po,
"s", &
s) == 1) {
667 if (
double x; PyArg_Parse(po,
"d", &x) == 1) {
668 auto px = hoc_pop_handle<double>();
674 PyErr_SetString(PyExc_AttributeError,
"POINTER is NULL");
686 PyErr_SetString(PyExc_TypeError,
"argument cannot be a hoc object intermediate");
708 return (
void*) Py_BuildValue(
"i", (
long)
hoc_xpop());
713 return (
void*) PyBool_FromLong((
long)
hoc_xpop());
717 static void*
fcall(
void* vself,
void* vargs) {
723 std::vector<neuron::unique_cstr> strings_to_free;
726 self->nindex_ =
narg;
738 if (self->sym_->type == BLTIN) {
744 }
else if (self->sym_->type == TEMPLATE) {
759 return result.release().ptr();
765 fc[1].
sym =
self->sym_;
791 if (kwrds && PyDict_Check(kwrds)) {
793 PyObject* keys = PyDict_Keys(kwrds);
794 assert(PyList_Check(keys));
795 int n = PyList_Size(keys);
796 for (
int i = 0;
i <
n; ++
i) {
799 printf(
"%s %s\n", PyUnicode_AsUTF8(
key), PyUnicode_AsUTF8(PyObject_Str(
value)));
802 section = PyDict_GetItemString(kwrds,
"sec");
803 int num_kwargs = PyDict_Size(kwrds);
804 if (num_kwargs > 1) {
805 PyErr_SetString(PyExc_RuntimeError,
"invalid keyword argument");
819 PyErr_SetString(PyExc_TypeError,
"sec is not a Section");
825 PyErr_SetString(PyExc_RuntimeError,
"invalid keyword argument");
836 }
catch (std::exception
const& e) {
837 std::ostringstream oss;
838 oss <<
"hocobj_call error: " << e.what();
839 PyErr_SetString(PyExc_RuntimeError, oss.str().c_str());
843 PyErr_SetString(PyExc_TypeError,
"object is not callable");
851 return result.release().ptr();
866 if (sym->
type == VAR &&
907 for (
i = 0;
i <
n; ++
i) {
927 }
catch (std::exception
const& e) {
928 std::ostringstream oss;
929 oss <<
"number of dimensions error:" << e.what();
930 PyErr_SetString(PyExc_IndexError, oss.str().c_str());
945 return result.release().ptr();
962 return result.release().ptr();
973 auto*
const hpo =
reinterpret_cast<PyHocObject*
>(po);
983 auto nn = nb::steal(Py_BuildValue(
""));
985 if (
s->type == UNDEF) {
989 if (strcmp(
s->name,
"del") == 0) {
990 PyDict_SetItemString(dict,
"delay", nn.ptr());
992 PyDict_SetItemString(dict,
s->name, nn.ptr());
1003 pdoc = PyImport_ImportModule(
"neuron.doc");
1005 PyErr_SetString(PyExc_ImportError,
"Failed to import neuron.doc documentation module.");
1011 PyErr_SetString(PyExc_AttributeError,
1012 "neuron.doc module does not have attribute 'get_docstring'!");
1022 const auto n =
name.c_str();
1028 if (strcmp(
n,
"__doc__") == 0) {
1033 docobj = nb::make_tuple(
"", hclass->
sym->
name);
1036 docobj = nb::make_tuple(
"",
"");
1040 return result.release().ptr();
1047 return PyType_Type.tp_getattro(
self, pyname);
1054 auto descr = nb::borrow(PyDict_GetItemString(
topmethdict,
n));
1056 descrgetfunc f = descr.ptr()->ob_type->tp_descr_get;
1058 return f(descr.ptr(), subself, (
PyObject*) Py_TYPE(subself));
1069 PyErr_SetString(PyExc_TypeError,
"not a compound type");
1076 char*
n =
name.c_str();
1093 return PyObject_GenericGetAttr(
p, pyname);
1098 return result.release().ptr();
1101 if (strcmp(
n,
"__dict__") == 0) {
1105 sl =
self->ho_->ctemplate->symtable;
1106 }
else if (self->sym_ && self->sym_->type == TEMPLATE) {
1107 sl =
self->sym_->u.ctemplate->symtable;
1109 auto dict = nb::steal(PyDict_New());
1121 PyDict_SetItemString(dict.ptr(),
"__array_interface__", Py_None);
1122 }
else if (
is_obj_type(self->ho_,
"RangeVarPlot") ||
1124 PyDict_SetItemString(dict.ptr(),
"plot", Py_None);
1126 return dict.release().ptr();
1127 }
else if (strncmp(
n,
"_ref_", 5) == 0) {
1129 PyErr_SetString(PyExc_TypeError,
"not a HocTopLevelInterpreter or HocObject");
1132 sym =
getsym(
n + 5, self->ho_, 0);
1134 return PyObject_GenericGetAttr((
PyObject*) subself, pyname);
1140 }
else if (self->type_ ==
PyHoc::HocObject && !self->ho_->ctemplate->constructor) {
1147 char** cpp =
OPSTR(sym);
1150 return result.release().ptr();
1154 "Hoc pointer error, %s is not a hoc variable or range variable or strdef",
1160 }
else if (
is_obj_type(self->ho_,
"Vector") && strcmp(
n,
"__array_interface__") == 0) {
1163 Vect*
v = (
Vect*) self->ho_->u.this_pointer;
1164 int size =
v->size();
1167 return Py_BuildValue(
"{s:(i),s:s,s:i,s:(N,O)}",
1175 PyLong_FromVoidPtr(x),
1178 }
else if (
is_obj_type(self->ho_,
"RangeVarPlot") && strcmp(
n,
"plot") == 0) {
1180 }
else if (
is_obj_type(self->ho_,
"PlotShape") && strcmp(
n,
"plot") == 0) {
1182 }
else if (strcmp(
n,
"__doc__") == 0) {
1186 docobj = nb::make_tuple(self->ho_->ctemplate->sym->name,
1187 self->sym_ ? self->sym_->name :
"");
1188 }
else if (self->sym_) {
1190 docobj = nb::make_tuple(
"", self->sym_->name);
1193 docobj = nb::make_tuple(
"",
"");
1197 return result.release().ptr();
1202 strncmp(
n,
"__nrnsec_0x", 11) == 0) {
1205 PyErr_SetString(PyExc_NameError,
n);
1214 return result.release().ptr();
1218 PyErr_SetString(PyExc_NameError,
n);
1227 return result.release().ptr();
1231 return PyObject_GenericGetAttr((
PyObject*) subself, pyname);
1239 PyErr_SetString(PyExc_TypeError,
1240 "No hoc method for a callable. Missing parentheses before the '.'?");
1244 PyErr_SetString(PyExc_TypeError,
"Missing array index");
1252 po->
ho_ =
self->ho_;
1258 if (
t == VAR ||
t ==
STRING ||
t == OBJECTVAR ||
t == RANGEVAR ||
t == SECTION ||
1266 PyErr_SetString(PyExc_TypeError,
"No value");
1270 if (
t == SECTION ||
t == SECTIONREF) {
1274 return ret.release().ptr();
1277 auto handle = hoc_pop_handle<double>();
1280 return nrnpy_hoc_pop(
"use-the-component-fork hocobj_getattr");
1289 return ret_ho_.release().ptr();
1293 return ret_ho_.release().ptr();
1298 switch (sym->
type) {
1307 PyErr_SetString(PyExc_TypeError,
"Section access unspecified");
1318 PyErr_SetString(PyExc_TypeError,
"Cannot be a reference");
1370 case HOCOBJFUNCTION:
1377 po->
ho_ =
self->ho_;
1385 case SETPOINTERKEYWORD:
1394 PyErr_Format(PyExc_TypeError,
1395 "Cannot access %s directly; it is a range variable and may be accessed "
1396 "via a section or segment.",
1399 PyErr_Format(PyExc_TypeError,
1400 "Cannot access %s (NEURON type %d) directly.",
1407 return result.release().ptr();
1412 if (!PyArg_ParseTuple(args,
"O", &
name)) {
1426 if (name_str.c_str() && strcmp(name_str.c_str(),
"__doc__") == 0) {
1428 nb::object
result = nb::steal(PyObject_GenericGetAttr(subself,
name));
1431 return result.release().ptr();
1441 nb::object
result = nb::steal(PyObject_GenericGetAttr(subself,
name));
1444 return result.release().ptr();
1460 int issub = ((PyTypeObject*) PyObject_Type(subself) !=
hocobject_type);
1464 if (PyObject_HasAttr(subself, pyname)) {
1467 return PyObject_GenericSetAttr(subself, pyname,
value);
1479 char*
n =
name.c_str();
1488 return PyObject_GenericSetAttr(subself, pyname,
value);
1492 return PyObject_GenericSetAttr(
p, pyname,
value);
1493 }
else if (strncmp(
n,
"_ref_", 5) == 0) {
1495 if (rvsym && rvsym->
type == RANGEVAR) {
1498 PyErr_SetString(PyExc_TypeError,
"Point_process not located in a section");
1504 sym =
getsym(
n, self->ho_, 1);
1506 sym =
getsym(
n, self->ho_, 1);
1517 po->
ho_ =
self->ho_;
1531 PyErr_SetString(PyExc_TypeError,
"No value");
1536 PyErr_Format(PyExc_TypeError,
"'%s' requires subscript for assignment",
n);
1540 PyErr_SetString(PyExc_TypeError,
"not assignable");
1545 switch (sym->
type) {
1548 PyErr_SetString(PyExc_TypeError,
"Wrong number of subscripts");
1555 PyErr_SetString(PyExc_TypeError,
"Section access unspecified");
1562 if (PyArg_Parse(
value,
"i", &
i) != 0 &&
i > 0 &&
i <= 32767) {
1565 PyErr_SetString(PyExc_ValueError,
1566 "nseg must be an integer in range 1 to 32767");
1570 err = PyArg_Parse(
value,
"d", &x) == 0;
1590 if (PyArg_Parse(
value,
"s", &
s) == 1) {
1606 if (PyArg_Parse(
value,
"O", &po) == 1) {
1607 if (po == Py_None) {
1613 PyErr_SetString(PyExc_TypeError,
1614 "argument cannot be a hoc object intermediate");
1630 PyErr_SetString(PyExc_TypeError,
"not assignable");
1642 int nsub = a ? a->
nsub : 0;
1643 if (nsub <= po->nindex_) {
1644 std::ostringstream oss;
1645 oss <<
"Too many subscripts (Redeclared the array?), hoc var " << po->
sym_->
name
1646 <<
" now has " << nsub <<
" but trying to access dimension " << (po->
nindex_);
1647 PyErr_SetString(PyExc_TypeError, oss.str().c_str());
1674 if (ix < 0 ||
n <= ix) {
1677 PyErr_Format(PyExc_IndexError,
1680 (po->
ho_ && po->
sym_) ?
"." :
"",
1708 PyErr_SetString(PyExc_TypeError,
"hoc all section iterator() has no len()");
1711 PyErr_SetString(PyExc_TypeError,
"hoc SectionList iterator() has no len()");
1714 PyErr_SetString(PyExc_TypeError,
"Most HocObject have no len()");
1749 return po.release().ptr();
1760 nb::object
self = nb::borrow(raw_self);
1764 return PySeqIter_New(
self.ptr());
1766 return PySeqIter_New(
self.ptr());
1777 return po2.release().ptr();
1782 return self.release().ptr();
1784 return PySeqIter_New(
self.ptr());
1787 return self.release().ptr();
1789 PyErr_SetString(PyExc_TypeError,
"Not an iterable HocObject");
1855 if (curitem != ql) {
1914 }
else if (po->
sym_->
type == TEMPLATE) {
1937 PyErr_SetString(PyExc_IndexError,
"index for hoc ref must be 0");
1946 result = nb::steal(Py_BuildValue(
"d", *h));
1948 }
catch (std::exception
const& e) {
1950 PyErr_SetString(PyExc_IndexError, e.what());
1954 result = nb::steal(Py_BuildValue(
"d", po->
u.
x_));
1956 result = nb::steal(Py_BuildValue(
"s", po->
u.
s_));
1962 return result.release().ptr();
1974 return PyFloat_FromDouble(
vector_vec(hv)[ix]);
1981 if (ix < 0 || ix >= hl->
count()) {
1988 PyErr_SetString(PyExc_TypeError,
"unsubscriptable object");
1995 PyErr_SetString(PyExc_TypeError,
"unsubscriptable object");
1997 }
else if (po->
sym_->
type == TEMPLATE) {
2002 if (ob->
index == ix) {
2006 PyErr_Format(PyExc_IndexError,
"%s[%ld] instance does not exist", po->
sym_->
name, ix);
2010 PyErr_Format(PyExc_TypeError,
"unsubscriptable object, type %d\n", po->
type_);
2028 return result.release().ptr();
2069 return result.release().ptr();
2075 if (!PySlice_Check(slice)) {
2080 PyErr_SetString(PyExc_TypeError,
"Obj is NULL");
2084 PyErr_SetString(PyExc_TypeError,
"sequence index must be integer, not 'slice'");
2087 auto*
v = (
Vect*) po->ho_->u.this_pointer;
2088 Py_ssize_t start = 0;
2090 Py_ssize_t
step = 0;
2091 Py_ssize_t slicelen = 0;
2093 PySlice_GetIndicesEx(slice, len, &start, &end, &
step, &slicelen);
2095 PyErr_SetString(PyExc_ValueError,
"slice step cannot be zero");
2107 PyErr_SetString(PyExc_TypeError,
"incomplete hoc pointer");
2111 PyErr_SetString(PyExc_IndexError,
"index for hoc ref must be 0");
2118 PyArg_Parse(arg,
"d",
static_cast<double const*
>(h));
2122 }
catch (std::exception
const& e) {
2124 PyErr_SetString(PyExc_IndexError, e.what());
2128 PyArg_Parse(arg,
"d", &po->
u.
x_);
2131 PyArg_Parse(arg,
"s", &ts);
2135 PyArg_Parse(arg,
"s", &ts);
2139 PyArg_Parse(arg,
"O", &tp);
2152 if (
i >= vec_size ||
i < 0) {
2153 PyErr_SetString(PyExc_IndexError,
"index out of bounds");
2161 PyErr_SetString(PyExc_TypeError,
"unsubscriptable object");
2166 int nsub = a ? a->
nsub : 0;
2167 std::ostringstream oss;
2168 oss <<
"Wrong number of subscripts, hoc var " << po->
sym_->
name <<
" has " << nsub
2169 <<
" but compiled with " << (po->
nindex_ + 1);
2170 PyErr_SetString(PyExc_TypeError, oss.str().c_str());
2178 PyErr_SetString(PyExc_TypeError,
"not assignable");
2193 err = PyArg_Parse(arg,
"d",
hoc_pxpop()) != 1;
2205 if (PyArg_Parse(arg,
"O", &pyo) == 1) {
2216 PyErr_SetString(PyExc_TypeError,
"not assignable");
2225 if (!PySlice_Check(slice)) {
2230 PyErr_SetString(PyExc_TypeError,
"Obj is NULL");
2234 PyErr_SetString(PyExc_TypeError,
"sequence index must be integer, not 'slice'");
2237 auto v = (
Vect*) po->ho_->u.this_pointer;
2238 Py_ssize_t start = 0;
2240 Py_ssize_t
step = 0;
2241 Py_ssize_t slicelen = 0;
2243 PySlice_GetIndicesEx(slice, cap, &start, &end, &
step, &slicelen);
2245 auto iter = nb::steal(PyObject_GetIter(arg));
2247 PyErr_SetString(PyExc_TypeError,
"can only assign an iterable");
2250 for (Py_ssize_t
i = 0;
i < slicelen; ++
i) {
2251 auto val = nb::steal(PyIter_Next(iter.ptr()));
2253 PyErr_SetString(PyExc_IndexError,
2254 "iterable object must have the same length as slice (it's too short)");
2259 auto val = nb::steal(PyIter_Next(iter.ptr()));
2261 PyErr_SetString(PyExc_IndexError,
2262 "iterable object must have the same length as slice (it's too long)");
2270 if (PyArg_ParseTuple(args,
"O", &pa) == 1) {
2275 auto pn = nb::steal(PyNumber_Float(pa));
2276 result->u.x_ = PyFloat_AsDouble(pn.ptr());
2281 if (!str.is_valid()) {
2283 "string arg must have only ascii characters");
2286 char* cpa = str.c_str();
2292 return result_guard.release().ptr();
2294 PyErr_SetString(PyExc_TypeError,
"single arg must be number, string, or Object");
2322 return result_guard.release().ptr();
2339 char*
n = str.c_str();
2340 if (!str.is_valid()) {
2342 "POINTER name can contain only ascii characters");
2351 PyErr_SetString(PyExc_TypeError,
"Point_process not located in a section");
2354 gh = &(
prop->dparam[sym->
u.
rng.index]);
2365 PyErr_SetString(PyExc_TypeError,
2366 "setpointer(_ref_hocvar, 'POINTER_name', point_process or "
2380 po = Py_BuildValue(
"O", PyLong_FromVoidPtr(ho));
2383 PyErr_SetString(PyExc_TypeError,
"HocObject does not wrap a Hoc Object");
2400 result = self_ptr < other_ptr;
2403 result = self_ptr <= other_ptr;
2406 result = self_ptr == other_ptr;
2409 result = self_ptr != other_ptr;
2412 result = self_ptr > other_ptr;
2415 result = self_ptr >= other_ptr;
2418 return PyBool_FromLong(
result);
2423 auto* pyhoc_other =
reinterpret_cast<PyHocObject*
>(other);
2424 void* self_ptr =
self->
ho_;
2425 void* other_ptr = other;
2426 bool are_equal =
true;
2428 if (pyhoc_other->type_ == self->type_) {
2429 switch (self->type_) {
2435 self_ptr = (
void*)
self;
2438 if (self->ho_ != pyhoc_other->ho_) {
2441 }
else if (op == Py_EQ) {
2445 PyErr_SetString(PyExc_TypeError,
"this comparison is undefined");
2448 self_ptr =
self->sym_;
2449 other_ptr = pyhoc_other->sym_;
2453 self_ptr =
static_cast<double*
>(
self->u.px_);
2454 other_ptr =
static_cast<double*
>(pyhoc_other->u.px_);
2458 if (op != Py_EQ && op != Py_NE) {
2460 PyErr_SetString(PyExc_TypeError,
"this comparison is undefined");
2463 if (self->ho_ != pyhoc_other->ho_) {
2465 other_ptr = pyhoc_other->ho_;
2468 if (self->nindex_ != pyhoc_other->nindex_ || self->sym_ != pyhoc_other->sym_) {
2469 return PyBool_FromLong(op == Py_NE);
2471 for (
int i = 0;
i <
self->nindex_;
i++) {
2472 if (self->indices_[
i] != pyhoc_other->indices_[
i]) {
2476 return PyBool_FromLong(are_equal == (op == Py_EQ));
2478 other_ptr = pyhoc_other->ho_;
2483 }
else if (op == Py_NE) {
2487 PyErr_SetString(PyExc_TypeError,
"this comparison is undefined");
2496 if (PyArg_ParseTuple(args,
"O", &po)) {
2509 if (PyObject_HasAttrString(po,
"__array_interface__")) {
2510 auto ai = nb::steal(PyObject_GetAttrString(po,
"__array_interface__"));
2513 data = PyLong_AsVoidPtr(PyTuple_GetItem(PyDict_GetItemString(ai.ptr(),
"data"), 0));
2515 if (PyErr_Occurred()) {
2518 PyObject* pstride = PyDict_GetItemString(ai.ptr(),
"strides");
2519 if (pstride == Py_None) {
2521 }
else if (PyTuple_Check(pstride)) {
2522 if (PyTuple_Size(pstride) == 1) {
2523 PyObject* psize = PyTuple_GetItem(pstride, 0);
2524 if (PyLong_Check(psize)) {
2525 stride = PyLong_AsLong(psize);
2530 PyErr_SetString(PyExc_TypeError,
2531 "array_interface stride element of invalid type.");
2538 PyErr_SetString(PyExc_TypeError,
"array_interface stride object of invalid type.");
2543 return static_cast<char*
>(
data);
2548 if (!PyNumber_Check(obj)) {
2550 Sprintf(
buf,
"item %d is not a valid number", obj_id);
2553 return PyFloat_AsDouble(obj);
2567 if (!PySequence_Check(po.ptr())) {
2568 if (!PyIter_Check(po.ptr())) {
2570 " does not support the Python Sequence or Iterator protocol");
2580 int size = nb::len(po);
2587 if (array_interface_ptr) {
2588 for (
int i = 0,
j = 0;
i < size; ++
i,
j +=
stride) {
2589 x[
i] = *(
double*) (array_interface_ptr +
j);
2595 if (PyList_Check(po.ptr())) {
2597 for (
long i = 0;
i < size; ++
i) {
2601 for (
long i = 0;
i < size; ++
i) {
2627 delete[](*save_data);
2629 *save_data_size =
result.size();
2630 *save_data =
new char[*save_data_size];
2631 memcpy(*save_data,
result.c_str(), *save_data_size);
2633 *save_data_size = 0;
2639 nb::bytearray py_data(
data, size);
2649 hoc_execerror(
"SaveState:",
"Missing data restore function.");
2677 return PyFloat_AsDouble(pyobj.ptr());
2702 auto args = nb::steal(PyTuple_New(
narg + 3));
2704 PyTuple_SetItem(args.ptr(), 0, pyname.release().ptr());
2705 for (
int iarg = 0; iarg <
narg; iarg++) {
2706 const int iiarg = iarg + 1;
2709 PyTuple_SetItem(args.ptr(), iarg + 3, active_obj.release().ptr());
2713 ptr_nrn->
u.
px_ = hoc_hgetarg<double>(iiarg);
2716 PyTuple_SetItem(args.ptr(), iarg + 3, py_ptr);
2718 if (handle_strptr > 0) {
2722 PyTuple_SetItem(args.ptr(), iarg + 3, py_ptr);
2725 PyTuple_SetItem(args.ptr(), iarg + 3, py_str.release().ptr());
2728 auto py_double = nb::steal(PyFloat_FromDouble(*
getarg(iiarg)));
2729 PyTuple_SetItem(args.ptr(), iarg + 3, py_double.release().ptr());
2738 my_obj = nb::none();
2740 PyTuple_SetItem(args.ptr(), 1, my_obj.release().ptr());
2747 my_obj2 = nb::none();
2750 PyTuple_SetItem(args.ptr(), 2, my_obj2.release().ptr());
2751 auto po = nb::steal(PyObject_CallObject(
gui_callback, args.ptr()));
2752 if (PyErr_Occurred()) {
2756 po = nb::steal(PyLong_FromLong(0));
2758 return po.release().ptr();
2793 if (!po.is_none()) {
2805 int size = hv->
size();
2823 if (!PySequence_Check(po.ptr())) {
2826 if (size != PySequence_Size(po.ptr())) {
2830 if (!(po = nb::steal(PyList_New(size)))) {
2831 hoc_execerror(
"Could not create new Python List with correct size.", 0);
2841 for (
int i = 0,
j = 0;
i < size; ++
i,
j +=
stride) {
2842 *(
double*) (y +
j) = x[
i];
2844 }
else if (PyList_Check(po.ptr())) {
2845 for (
int i = 0;
i < size; ++
i) {
2846 auto pn = nb::steal(PyFloat_FromDouble(x[
i]));
2847 if (!pn || PyList_SetItem(po.ptr(),
i, pn.release().ptr()) == -1) {
2854 for (
int i = 0;
i < size; ++
i) {
2855 auto pn = nb::steal(PyFloat_FromDouble(x[
i]));
2856 if (!pn || PySequence_SetItem(po.ptr(),
i, pn.ptr()) == -1) {
2892 nanobind::gil_scoped_acquire
lock{};
2896 PyErr_SetString(PyExc_TypeError,
"get_plotshape_variable only takes PlotShape objects");
2902 spi = ((ShapePlot*) that);
2913 py_obj = nb::none();
2916 return Py_BuildValue(
"sNffN",
2918 py_obj.release().ptr(),
2921 py_sl.release().ptr());
2930 PyErr_SetString(PyExc_TypeError,
"HocObject: Only Vector instance can be pickled");
2937 nb::module_ mod = nb::module_::import_(
"neuron");
2941 nb::object obj = mod.attr(
"_pkl");
2943 PyErr_SetString(PyExc_Exception,
"neuron module has no _pkl method.");
2959 nb::bytes byte_order((
const void*) (&x),
sizeof(
double));
2960 nb::bytes vec_data(vec->
data(), vec->
size() *
sizeof(
double));
2961 nb::tuple state = nb::make_tuple(1, byte_order, vec->
size(), vec_data);
2963 return nb::make_tuple(obj, nb::make_tuple(0), state).release().ptr();
2971 #define BYTEHEADER \
2975 int BYTESWAP_FLAG = 0;
2976 #define BYTESWAP(_X__, _TYPE__) \
2977 if (BYTESWAP_FLAG == 1) { \
2978 _IN__ = (char*) &(_X__); \
2979 for (_II__ = 0; _II__ < sizeof(_TYPE__); _II__++) { \
2980 _OUT__[_II__] = _IN__[sizeof(_TYPE__) - _II__ - 1]; \
2982 (_X__) = *((_TYPE__*) &_OUT__); \
2989 nb::object endian_data;
2997 if (!PyArg_ParseTuple(args,
"(iOiO)", &version, &pendian_data, &size, &prawdata)) {
3001 rawdata = nb::borrow(prawdata);
3002 endian_data = nb::borrow(pendian_data);
3006 if (!PyBytes_Check(rawdata.ptr()) || !PyBytes_Check(endian_data.ptr())) {
3007 PyErr_SetString(PyExc_TypeError,
"pickle not returning string");
3012 if (PyBytes_AsStringAndSize(endian_data.ptr(), &
two, &len) < 0) {
3015 if (len !=
sizeof(
double)) {
3016 PyErr_SetString(PyExc_ValueError,
"endian_data size is not sizeof(double)");
3020 if (*((
double*)
two) != 2.0) {
3025 if (PyBytes_AsStringAndSize(rawdata.ptr(), &str, &len) < 0) {
3028 if (len != Py_ssize_t(size *
sizeof(
double))) {
3029 PyErr_SetString(PyExc_ValueError,
"buffer size does not match array size");
3032 if (BYTESWAP_FLAG) {
3033 double* x = (
double*) str;
3034 for (
int i = 0;
i < size; ++
i) {
3048 #if defined(HAVE_DLFCN_H) && !defined(MINGW)
3050 int rval =
dladdr((
const void*) Py_Initialize, &
info);
3052 PyErr_SetString(PyExc_Exception,
3053 "dladdr: Py_Initialize could not be matched to a shared object");
3056 if (!
info.dli_fname) {
3057 PyErr_SetString(PyExc_Exception,
3058 "dladdr: No symbol matching Py_Initialize could be found.");
3061 return Py_BuildValue(
"s",
info.dli_fname);
3074 {
"hocobjptr",
hocobj_vptr_safe, METH_NOARGS,
"Hoc Object pointer as a long int"},
3078 "o1.same(o2) return True if o1 and o2 wrap the same internal HOC Object"},
3079 {
"hname",
hocobj_name_safe, METH_NOARGS,
"More specific than __str__() or __attr__()."},
3082 {
nullptr,
nullptr, 0,
nullptr}};
3086 {
"ref",
mkref_safe, METH_VARARGS,
"Wrap to allow call by reference in a hoc function"},
3087 {
"cas",
nrnpy_cas_safe, METH_VARARGS,
"Return the currently accessed section."},
3088 {
"allsec",
nrnpy_forall_safe, METH_VARARGS,
"Return iterator over all sections."},
3091 METH_VARARGS | METH_KEYWORDS,
3092 "Return a new Section"},
3093 {
"setpointer",
setpointer_safe, METH_VARARGS,
"Assign hoc variable address to NMODL POINTER"},
3097 "Return full path to file that contains Py_Initialize()"},
3098 {
nullptr,
nullptr, 0,
nullptr}};
3103 auto nn = nb::steal(Py_BuildValue(
"s", meth->ml_doc));
3107 err = PyDict_SetItemString(dict, meth->ml_name, nn.ptr());
3140 bool potentially_valid =
false;
3143 potentially_valid =
true;
3145 potentially_valid =
true;
3148 if (!potentially_valid) {
3149 Py_INCREF(Py_NotImplemented);
3150 return Py_NotImplemented;
3153 return PyObject_CallFunction(
nrnpy_vec_math, strcpy(
buf,
"siOO"), op, reversed, obj1, obj2);
3161 Py_INCREF(Py_NotImplemented);
3162 return Py_NotImplemented;
3198 char endian_character = 0;
3200 auto psys = nb::steal(PyImport_ImportModule(
"sys"));
3202 PyErr_SetString(PyExc_ImportError,
"Failed to import sys to determine system byteorder.");
3206 auto pbo = nb::steal(PyObject_GetAttrString(psys.ptr(),
"byteorder"));
3208 PyErr_SetString(PyExc_AttributeError,
"sys module does not have attribute 'byteorder'!");
3213 if (!byteorder.is_valid()) {
3217 if (strcmp(byteorder.c_str(),
"little") == 0) {
3218 endian_character =
'<';
3219 }
else if (strcmp(byteorder.c_str(),
"big") == 0) {
3220 endian_character =
'>';
3222 PyErr_SetString(PyExc_RuntimeError,
"Unknown system native byteorder.");
3225 return endian_character;
3234 auto iterator = nb::steal(PyObject_GetIter(pargs));
3242 while ((item = nb::steal(PyIter_Next(iterator.ptr())))) {
3244 hoc_execerror(
"iterable must contain only Section objects", 0);
3250 if (PyErr_Occurred()) {
3270 PyObject* modules = PyImport_GetModuleDict();
3272 PyObject* module = PyDict_GetItemString(modules,
"neuron.coreneuron");
3274 auto val = nb::steal(PyObject_GetAttrString(module, option));
3276 long enable = PyLong_AsLong(val.ptr());
3283 if (PyErr_Occurred()) {
3305 extern char* (*nrnpy_nrncore_arg_p_)(
double tstop);
3307 PyObject* modules = PyImport_GetModuleDict();
3309 PyObject* module = PyDict_GetItemString(modules,
"neuron.coreneuron");
3311 auto callable = nb::steal(PyObject_GetAttrString(module,
"nrncore_arg"));
3313 auto ts = nb::steal(Py_BuildValue(
"(d)", tstop));
3315 auto arg = nb::steal(PyObject_CallObject(callable.ptr(), ts.ptr()));
3318 if (!str.is_valid()) {
3321 "neuron.coreneuron.nrncore_arg() must return an ascii string");
3324 if (strlen(str.c_str()) > 0) {
3325 return strdup(str.c_str());
3332 if (PyErr_Occurred()) {
3344 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
3369 nanobind::gil_scoped_acquire
lock{};
3371 char endian_character = 0;
3374 PyObject* modules = PyImport_GetModuleDict();
3375 if ((m = PyDict_GetItemString(modules,
"hoc")) && PyModule_Check(m)) {
3402 size_t alignment =
alignof(
Symbol*);
3404 if (remainder != 0) {
3417 if (!custom_hocclass) {
3420 if (PyModule_AddObject(m,
"HocClass", custom_hocclass) < 0) {
3429 pto = (PyTypeObject*)
3437 if (PyType_Ready(pto) < 0) {
3440 if (PyModule_AddObject(m,
name, (
PyObject*) pto) < 0) {
3450 err = PyDict_SetItemString(
topmethdict, meth->ml_name, descr.ptr());
3478 if (endian_character == 0) {
3485 err = PyDict_SetItemString(modules,
"hoc", m);
3503 if (!PyCallable_Check(
func)) {
3506 auto result = nb::steal(PyObject_CallFunction(
func,
"d", x));
3509 hoc_execerror(
"Python function call raised exception",
nullptr);
3511 if (!PyNumber_Check(
result.ptr())) {
3512 hoc_execerror(
"Expected a numeric result from Python function",
nullptr);
3515 if (PyErr_Occurred()) {
3516 hoc_execerror(
"Failed to convert result to float",
nullptr);
void nrn_pushsec(Section *sec)
void cable_prop_assign(Symbol *sym, double *pd, int op)
Section * nrn_noerr_access(void)
return 0 if no accessed section
double const * data() const
static neuron::unique_cstr as_ascii(PyObject *python_string)
static neuron::unique_cstr get_pyerr()
static void set_pyerr(PyObject *type, const char *message)
char * release()
Releases ownership of the string.
Symbol * hoc_table_lookup(const char *, Symlist *)
HocReturnType hoc_return_type_code
DLFCN_EXPORT int dladdr(const void *addr, Dl_info *info)
static double interp(double frac, double x1, double x2)
int hoc_is_object_arg(int narg)
void hoc_push_ndim(int d)
void hoc_pushstr(char **d)
void hoc_execerr_ext(const char *fmt,...)
printf style specification of hoc_execerror message.
double hoc_call_func(Symbol *s, int narg)
void vector_resize(IvocVect *v, int n)
void hoc_pushpx(double *d)
void hoc_pushobj(Object **d)
void * hoc_sec_internal_name2ptr(const char *s, int eflag)
int hoc_is_str_arg(int narg)
int hoc_is_temp_charptr(char **cpp)
Objectdata * hoc_objectdata
void hoc_assign_str(char **cpp, const char *buf)
int is_obj_type(Object *obj, const char *type_name)
int hoc_is_double_arg(int narg)
char ** hoc_temp_charptr(void)
void hoc_obj_ref(Object *obj)
char * hoc_object_name(Object *ob)
void * hoc_pysec_name2ptr(const char *s, int)
Symbol * hoc_lookup(const char *)
int hoc_is_pdouble_arg(int narg)
void hoc_obj_unref(Object *obj)
void hoc_push_object(Object *d)
void hoc_push(neuron::container::generic_data_handle handle)
char ** hoc_pgargstr(int narg)
Objectdata * hoc_objectdata_restore(Objectdata *obdsav)
Objectdata * hoc_objectdata_save(void)
bool is_array(const Symbol &sym)
void hoc_l_delete(hoc_Item *)
Point_process * ob2pntproc_0(Object *ob)
Object ** hoc_objgetarg(int)
static double location(void *v)
Object ** new_vect(Vect *v, ssize_t delta, ssize_t start, ssize_t step)
#define ITERATE(itm, lst)
void move(Item *q1, Item *q2, Item *q3)
@ HocForallSectionIterator
double * vector_vec(IvocVect *v)
void hoc_execerror(const char *s1, const char *s2)
int vector_capacity(IvocVect *v)
handle_interface< non_owning_identifier< storage > > handle
Non-owning handle to a Mechanism instance.
int Sprintf(char(&buf)[N], const char *fmt, Args &&... args)
Redirect sprintf to snprintf if the buffer size can be deduced.
std::string to_string(const T &obj)
static convert_cxx_exceptions_trait< F, Args... >::return_type convert_cxx_exceptions(F f, Args &&... args)
void section_unref(Section *)
int const size_t const size_t n
Symbol * nrnpy_pyobj_sym_
static PyType_Spec hocclass_spec
static PyObject * hocobj_baseattr_safe(PyObject *subself, PyObject *args)
static void hocobj_dealloc(PyHocObject *self)
int nrnpy_numbercheck(PyObject *po)
static HocReturnType component(PyHocObject *po)
static PyObject * plotshape_plot
static char * double_array_interface(PyObject *po, long &stride)
static Symbol * getsym(char *name, Object *ho, int fail)
double pyobj_to_double_or_fail(PyObject *obj, long obj_id)
static PyObject * cpp2refstr(char **cpp)
static PyObject * hocobj_name(PyObject *pself, PyObject *args)
static PyObject * hocobj_same(PyHocObject *pself, PyObject *args)
static PyObject * hocobj_getattro(PyObject *subself, PyObject *name)
static int hocobj_slice_setitem(PyObject *self, PyObject *slice, PyObject *arg)
static PyType_Spec obj_spec_from_name(const char *name)
static Symbol * sym_mat_x
static PyObject * py_hocobj_add(PyObject *obj1, PyObject *obj2)
static cTemplate * hoc_vec_template_
static cTemplate * hoc_list_template_
static cTemplate * hoc_sectionlist_template_
static IvocVect * nrnpy_vec_from_python(void *v)
static int nrncore_file_mode_value()
return value of neuron.coreneuron.file_mode
NRN_EXPORT PyObject * nrnpy_hoc()
static PyObject * hocobj_iter(PyObject *raw_self)
PyTypeObject * psection_type
static PyObject * curargs_
Object * hoc_obj_look_inside_stack(int)
static PyObject * py_hocobj_uabs(PyObject *obj)
static PyObject * nrnexec(PyObject *self, PyObject *args)
void(* nrnpy_decref)(void *pyobj)
static int hocobj_init(PyObject *subself, PyObject *args, PyObject *kwds)
static PyObject * hocclass_getitem(PyObject *self, Py_ssize_t ix)
static PyObject * store_savestate_
static PyObject * gui_helper_3_helper_(const char *name, Object *obj, int handle_strptr)
static PyObject * hocobj_call(PyHocObject *self, PyObject *args, PyObject *kwrds)
static int hocclass_init(hocclass *cls, PyObject *args, PyObject *kwds)
static void * nrnpy_hoc_bool_pop()
static PyObject * hocobj_slice_getitem(PyObject *self, PyObject *slice)
static PyObject * setpointer_safe(PyObject *self, PyObject *args)
static PyObject * gui_callback
static Inst * save_pc(Inst *newpc)
Symlist * hoc_top_level_symlist
void(* nrnpy_sectionlist_helper_)(void *, Object *)
static PyObject * setpointer(PyObject *self, PyObject *args)
static PyType_Slot hocclass_slots[]
int nrn_is_hocobj_ptr(PyObject *po, neuron::container::data_handle< double > &pd)
static Object ** vec_as_numpy_helper(int size, double *data)
Object ** hoc_objpop()
Pop pointer to object pointer and return top elem from stack.
int ivoc_list_count(Object *)
static PyObject * hocobj_same_safe(PyHocObject *pself, PyObject *args)
static void * nrnpy_hoc_int_pop()
static Object ** gui_helper_3_(const char *name, Object *obj, int handle_strptr)
int hoc_max_builtin_class_id
double cable_prop_eval(Symbol *sym)
static PyObject * hocobj_vptr_safe(PyObject *pself, PyObject *args)
Symbol * ivoc_alias_lookup(const char *name, Object *ob)
static PyObject * hocpickle_reduce(PyObject *self, PyObject *args)
void nrnpython_reg_real_nrnpy_hoc_cpp(neuron::python::impl_ptrs *ptrs)
static PyObject * py_hocobj_uneg(PyObject *obj)
std::vector< const char * > py_exposed_classes
static PyObject * hoc_ac(PyObject *self, PyObject *args)
static PyObject *(* vec_as_numpy)(int, double *)
static void add2topdict(PyObject *)
static PyObject * py_hocobj_upos(PyObject *obj)
int hoc_stack_type()
Get the type of the top entry.
static void * fcall(void *vself, void *vargs)
static PyObject * hocpickle_reduce_safe(PyObject *self, PyObject *args)
static void pyobject_in_objptr(Object **, PyObject *)
static int araylen(Arrayinfo *a, PyHocObject *po)
static PyObject * libpython_path(PyObject *self, PyObject *args)
PyObject * nrnpy_cas(PyObject *, PyObject *)
static double object_to_double_(Object *obj)
static hoc_Item * next_valid_secitem(hoc_Item *q, hoc_Item *ql)
static void eval_component(PyHocObject *po, int ix)
void *(* nrnpy_get_pyobj)(Object *obj)
static int hocobj_setattro(PyObject *subself, PyObject *pyname, PyObject *value)
double(* nrnpy_call_func)(Object *, double)
static char * nrncore_arg(double tstop)
static PyObject * mkref(PyObject *self, PyObject *args)
PyObject * nrnpy_newsecobj_safe(PyObject *, PyObject *, PyObject *)
static PyObject * pfunc_get_docstring
static PyObject * py_hocobj_div(PyObject *obj1, PyObject *obj2)
static PyObject * hocobj_baseattr(PyObject *subself, PyObject *args)
Object **(* nrnpy_vec_as_numpy_helper_)(int, double *)
static int hocobj_setitem(PyObject *self, Py_ssize_t i, PyObject *arg)
NRN_EXPORT PyObject * nrn_hocobj_ptr(double *pd)
static int setup_doc_system()
int(* nrnpy_nrncore_file_mode_value_p_)()
value of neuron.coreneuron.file_mode as 0, 1 (-1 if error)
int hocobj_pushargs(PyObject *args, std::vector< neuron::unique_cstr > &s2free)
static PyObject * mkref_safe(PyObject *self, PyObject *args)
void hoc_tobj_unref(Object **)
static PyMethodDef hocobj_methods[]
static PyObject * hocobj_name_safe(PyObject *pself, PyObject *args)
static void nrnpy_restore_savestate_(int64_t size, char *data)
static void hocobj_pushtop(PyHocObject *po, Symbol *sym, int ix)
static PyMethodDef toplevel_methods[]
PyObject * nrn_type_from_metaclass(PyTypeObject *meta, PyObject *mod, PyType_Spec *spec, PyObject *bases)
void hoc_object_component()
static PyObject * nrnpy_rvp_pyobj_callback
static PyObject * hocobj_richcmp(PyHocObject *self, PyObject *other, int op)
static bool pyobj_is_vector(PyObject *obj)
NRN_EXPORT int nrnpy_set_gui_callback(PyObject *new_gui_callback)
static PyObject * py_hocobj_math_unary(const char *op, PyObject *obj)
static PyObject * hocobj_repr(PyObject *p)
static Symbol * sym_vec_x
PyObject * nrnpy_cas_safe(PyObject *, PyObject *)
static PyObject * hocobj_vptr(PyObject *pself, PyObject *args)
static PyObject * hocpickle_setstate_safe(PyObject *self, PyObject *args)
static int get_nrncore_opt_value(const char *option)
static PyObject * libpython_path_safe(PyObject *self, PyObject *args)
Object **(* nrnpy_vec_to_python_p_)(void *)
static PyObject * rvp_plot
static PyObject * py_hocobj_sub(PyObject *obj1, PyObject *obj2)
Object * hoc_newobj1(Symbol *, int)
static PyHocObject * intermediate(PyHocObject *po, Symbol *sym, int ix)
PyObject * nrnpy_forall(PyObject *self, PyObject *args)
NRN_EXPORT int nrnpy_vec_math_register(PyObject *callback)
static PyObject * py_hocobj_math(const char *op, PyObject *obj1, PyObject *obj2)
void(* nrnpy_restore_savestate)(int64_t, char *)
static int refuse_to_look
static PyMethodDef HocMethods[]
NRN_EXPORT int nrnpy_set_vec_as_numpy(PyObject *(*p)(int, double *))
int nrn_netcon_weight(NetCon *, double **)
static PyObject * hocobj_getitem(PyObject *self, Py_ssize_t ix)
static char array_interface_typestr[5]
char *(* nrnpy_nrncore_arg_p_)(double tstop)
Gets the python string returned by neuron.coreneuron.nrncore_arg(tstop) return a strdup() copy of the...
PyObject * hocobj_call_arg(int i)
PyObject * toplevel_get(PyObject *subself, const char *n)
static int hocobj_nonzero(PyObject *self)
static PyObject * restore_savestate_
static PyObject * hocclass_getattro(PyObject *self, PyObject *pyname)
NRN_EXPORT PyObject * get_plotshape_data(PyObject *sp)
static PyObject * nrnpy_vec_math
static Arrayinfo * hocobj_aray(Symbol *sym, Object *ho)
static Object ** nrnpy_vec_to_python(void *v)
static std::unordered_map< Symbol *, PyTypeObject * > sym_to_type_map
static void nrnpy_decref_(void *pyobj)
static Py_ssize_t hocobj_len(PyObject *self)
static PyObject * hocobj_iternext(PyObject *self)
static int set_final_from_stk(PyObject *po)
static void symlist2dict(Symlist *sl, PyObject *dict)
static int hoc_evalpointer_err()
if hoc_evalpointer calls hoc_execerror, return 1
static int araychk(Arrayinfo *a, PyHocObject *po, int ix)
static Py_ssize_t seclist_count(Object *ho)
static PyObject * nrnexec_safe(PyObject *self, PyObject *args)
static long hocobj_hash(PyHocObject *self)
static int nrncore_enable_value()
return value of neuron.coreneuron.enable
static void nrnpy_store_savestate_(char **save_data, uint64_t *save_data_size)
int(* nrnpy_nrncore_enable_value_p_)()
value of neuron.coreneuron.enable as 0, 1 (-1 if error)
static PyObject * hocobj_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
static Object ** gui_helper_(const char *name, Object *obj)
PyObject * nrnpy_forall_safe(PyObject *, PyObject *)
Objectdata * hoc_top_level_data
char get_endian_character()
static PyObject * iternext_sl(PyHocObject *po, hoc_Item *ql)
PyObject * nrn_hocobj_handle(neuron::container::data_handle< double > d)
int nrn_secref_nchild(Section *)
static Symbol * sym_netcon_weight
static std::unordered_map< PyTypeObject *, Symbol * > type_to_sym_map
Symlist * hoc_built_in_symlist
static PyObject * hoc_ac_safe(PyObject *self, PyObject *args)
Object * nrnpy_po2ho(PyObject *po)
PyObject * nrn_ptr_richcmp(void *self_ptr, void *other_ptr, int op)
PyObject * nrnpy_ho2po(Object *o)
static void sectionlist_helper_(void *sl, Object *args)
PyTypeObject * hocobject_type
static PyObject * py_hocobj_mul(PyObject *obj1, PyObject *obj2)
static PyObject * hocobj_getsec(Symbol *sym)
static PyObject * hocobj_getattr(PyObject *subself, PyObject *pyname)
static char ** gui_helper_3_str_(const char *name, Object *obj, int handle_strptr)
static void * nrnpy_get_pyobj_(Object *obj)
PyObject * nrnpy_hoc_pop(const char *mes)
static PyObject * hocpickle_setstate(PyObject *self, PyObject *args)
static Object * rvp_rxd_to_callable_(Object *obj)
bool nrn_chk_data_handle(const neuron::container::data_handle< double > &pd)
static std::vector< std::string > exposed_py_type_names
#define BYTESWAP(_X__, _TYPE__)
static const char * hocobj_docstring
static PyObject * topmethdict
int nrn_matrix_dim(void *, int)
static double nrnpy_call_func_(Object *, double)
NRN_EXPORT int nrnpy_rvp_pyobj_callback_register(PyObject *callback)
Object *(* nrnpy_rvp_rxd_to_callable)(Object *)
bool hoc_valid_stmt(const char *, Object *)
static int hocobj_objectvar(Symbol *sym)
IvocVect *(* nrnpy_vec_from_python_p_)(void *)
NRN_EXPORT int nrnpy_set_toplevel_callbacks(PyObject *rvp_plot0, PyObject *plotshape_plot0, PyObject *get_mech_object_0, PyObject *store_savestate, PyObject *restore_savestate)
static PyObject * get_mech_object_
void(* nrnpy_store_savestate)(char **save_data, uint64_t *save_data_size)
static struct PyModuleDef hocmodule
static PyType_Slot nrnpy_HocObjectType_slots[]
neuron::container::generic_data_handle * nrnpy_setpointer_helper(PyObject *pyname, PyObject *mech)
int nrn_pointer_assign(Prop *prop, Symbol *sym, PyObject *value)
NPySecObj * newpysechelp(Section *sec)
Object * nrnpy_pyobject_in_obj(PyObject *po)
PyObject * nrnpy_hoc2pyobject(Object *ho)
bool is_python_string(PyObject *python_string)
#define PyString_FromString
static double done(void *v)
static double ref(void *v)
double seclist_size(void *v)
void lvappendsec_and_ref(void *sl, Section *sec)
Object ** hoc_temp_objptr(Object *)
PyObject_HEAD Section * sec_
static void * fpycall(void *(*)(void *, void *), void *, void *)
PyObject_HEAD Object * ho_
PyHoc::IteratorState its_
neuron::container::data_handle< double > px_
virtual const char * varname() const =0
virtual Object * neuron_section_list()=0
virtual void * varobj() const =0
struct Symbol::@45::@46 rng
union hoc_Item::@48 element
data_handle next_array_element(int shift=1) const
Get a data handle to a different element of the same array variable.
Non-template stable handle to a generic value.
Collection of pointers to functions with python-version-specific implementations.
double(* object_to_double)(Object *)
Object **(* gui_helper)(const char *name, Object *obj)
Object **(* gui_helper3)(const char *name, Object *obj, int handle_strptr)
char **(* gui_helper3_str)(const char *, Object *, int)