2 #include "../oc/code.h"
26 #include <unordered_map>
28 #include <nanobind/nanobind.h>
29 namespace nb = nanobind;
36 extern void* (*nrnpy_get_pyobj)(
Object* obj);
76 extern IvocVect* (*nrnpy_vec_from_python_p_)(
void*);
77 extern Object** (*nrnpy_vec_to_python_p_)(
void*);
78 extern Object** (*nrnpy_vec_as_numpy_helper_)(int,
double*);
122 #define HocTopContextSet \
123 if (hoc_thisobject) { \
126 assert(hoc_thisobject == 0);
127 #define HocContextRestore
147 if (PyType_Type.tp_init((
PyObject*) cls, args, kwds) < 0) {
164 if (ob->
index == ix) {
168 PyErr_Format(PyExc_IndexError,
"%s[%ld] instance does not exist", sym->
name, ix);
184 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE,
192 PyErr_SetString(PyExc_ValueError,
"Invalid data_handle");
201 }
catch (std::exception
const& e) {
202 std::ostringstream oss;
203 oss <<
"subscript out of range (array size or number of dimensions changed?)";
204 PyErr_SetString(PyExc_IndexError, oss.str().c_str());
213 if (!PyArg_ParseTuple(args,
"s", &cmd)) {
217 return PyBool_FromLong(b);
225 PyArg_ParseTuple(args,
"|d", &
hoc_ac_);
226 return Py_BuildValue(
"d",
hoc_ac_);
237 "Execute a hoc command, return True on success, False on failure."},
238 {
"hoc_ac",
hoc_ac_safe, METH_VARARGS,
"Get (or set) the scalar hoc_ac_."},
239 {
nullptr,
nullptr, 0,
nullptr}};
253 if (self->indices_) {
254 delete[]
self->indices_;
280 self->sym_ =
nullptr;
281 self->indices_ =
nullptr;
288 for (Py_ssize_t
i = 0;
i < PyTuple_Size(
subtype->tp_mro);
i++) {
294 hbase->
sym_ = symbol_result->second;
299 if (kwds && PyDict_Check(kwds) && (base = PyDict_GetItemString(kwds,
"hocbase"))) {
303 PyErr_SetString(PyExc_TypeError,
"HOC base class not valid");
306 PyDict_DelItemString(kwds,
"hocbase");
313 auto r = nb::steal(
hocobj_call(hbase, args, kwds));
323 return subself.release().ptr();
335 self->sym_ =
nullptr;
336 self->indices_ =
nullptr;
353 auto*
const self =
reinterpret_cast<PyHocObject*
>(pself);
362 cp.append(self->sym_->name);
364 for (
int i = 0;
i <
self->nindex_; ++
i) {
374 cp.append(
"<hoc ref value ");
378 cp.append(
"<hoc ref str \"");
379 cp.append(self->u.s_);
382 cp.append(
"<hoc ref pstr \"");
383 cp.append(*self->u.pstr_);
386 cp.append(
"<hoc ref value \"");
390 cp.append(
"<all section iterator next>");
392 cp.append(
"<SectionList iterator>");
394 std::ostringstream oss;
398 cp.append(
"<incomplete pointer to hoc array ");
399 cp.append(self->sym_->name);
402 cp.append(
"<TopLevelHocInterpreter>");
404 return Py_BuildValue(
"s", cp.c_str());
423 const nb::tuple tup(args);
424 for (
int i = 0;
i < tup.size(); ++
i) {
425 nb::object po(tup[
i]);
431 if (!str.is_valid()) {
438 hoc_execerr_ext(
"python string arg cannot decode into c_str. Pyerr message: %s",
493 if (!sym && strcmp(
name,
"delay") == 0) {
495 }
else if (!sym && ho->
aliases) {
504 if (sym && sym->
type == UNDEF) {
508 PyErr_Format(PyExc_LookupError,
"'%s' is not a defined hoc variable name.",
name);
554 int rval = PyNumber_Check(po);
556 if (rval == 1 && po->ob_type->tp_as_sequence) {
590 po.ptr()->ob_type =
location->second;
594 return po.release().ptr();
637 auto const px = hoc_pop_handle<double>();
658 return result.release().ptr();
666 if (PyArg_Parse(po,
"s", &
s) == 1) {
673 if (
double x; PyArg_Parse(po,
"d", &x) == 1) {
674 auto px = hoc_pop_handle<double>();
680 PyErr_SetString(PyExc_AttributeError,
"POINTER is NULL");
692 PyErr_SetString(PyExc_TypeError,
"argument cannot be a hoc object intermediate");
714 return (
void*) PyLong_FromLong((
long)
hoc_xpop());
719 return (
void*) PyBool_FromLong((
long)
hoc_xpop());
723 static void*
fcall(
void* vself,
void* vargs) {
729 std::vector<neuron::unique_cstr> strings_to_free;
732 self->nindex_ =
narg;
744 if (self->sym_->type == BLTIN) {
750 }
else if (self->sym_->type == TEMPLATE) {
765 return result.release().ptr();
771 fc[1].
sym =
self->sym_;
797 if (kwrds && PyDict_Check(kwrds)) {
799 PyObject* keys = PyDict_Keys(kwrds);
800 assert(PyList_Check(keys));
801 int n = PyList_Size(keys);
802 for (
int i = 0;
i <
n; ++
i) {
805 printf(
"%s %s\n", PyUnicode_AsUTF8(
key), PyUnicode_AsUTF8(PyObject_Str(
value)));
808 section = PyDict_GetItemString(kwrds,
"sec");
809 int num_kwargs = PyDict_Size(kwrds);
810 if (num_kwargs > 1) {
811 PyErr_SetString(PyExc_RuntimeError,
"invalid keyword argument");
825 PyErr_SetString(PyExc_TypeError,
"sec is not a Section");
831 PyErr_SetString(PyExc_RuntimeError,
"invalid keyword argument");
842 }
catch (std::exception
const& e) {
843 std::ostringstream oss;
844 oss <<
"hocobj_call error: " << e.what();
845 PyErr_SetString(PyExc_RuntimeError, oss.str().c_str());
849 PyErr_SetString(PyExc_TypeError,
"object is not callable");
857 return result.release().ptr();
872 if (sym->
type == VAR &&
913 for (
i = 0;
i <
n; ++
i) {
933 }
catch (std::exception
const& e) {
934 std::ostringstream oss;
935 oss <<
"number of dimensions error:" << e.what();
936 PyErr_SetString(PyExc_IndexError, oss.str().c_str());
951 return result.release().ptr();
968 return result.release().ptr();
979 auto*
const hpo =
reinterpret_cast<PyHocObject*
>(po);
989 auto nn = nb::steal(Py_BuildValue(
""));
991 if (
s->type == UNDEF) {
995 if (strcmp(
s->name,
"del") == 0) {
996 PyDict_SetItemString(dict,
"delay", nn.ptr());
998 PyDict_SetItemString(dict,
s->name, nn.ptr());
1009 pdoc = PyImport_ImportModule(
"neuron.doc");
1011 PyErr_SetString(PyExc_ImportError,
"Failed to import neuron.doc documentation module.");
1017 PyErr_SetString(PyExc_AttributeError,
1018 "neuron.doc module does not have attribute 'get_docstring'!");
1028 const auto n =
name.c_str();
1034 if (strcmp(
n,
"__doc__") == 0) {
1039 docobj = nb::make_tuple(
"", hclass->
sym->
name);
1042 docobj = nb::make_tuple(
"",
"");
1046 return result.release().ptr();
1053 return PyType_Type.tp_getattro(
self, pyname);
1060 auto descr = nb::borrow(PyDict_GetItemString(
topmethdict,
n));
1062 descrgetfunc f = descr.ptr()->ob_type->tp_descr_get;
1064 return f(descr.ptr(), subself, (
PyObject*) Py_TYPE(subself));
1075 PyErr_SetString(PyExc_TypeError,
"not a compound type");
1082 char*
n =
name.c_str();
1099 return PyObject_GenericGetAttr(
p, pyname);
1104 return result.release().ptr();
1107 if (strcmp(
n,
"__dict__") == 0) {
1111 sl =
self->ho_->ctemplate->symtable;
1112 }
else if (self->sym_ && self->sym_->type == TEMPLATE) {
1113 sl =
self->sym_->u.ctemplate->symtable;
1115 auto dict = nb::steal(PyDict_New());
1127 PyDict_SetItemString(dict.ptr(),
"__array_interface__", Py_None);
1128 }
else if (
is_obj_type(self->ho_,
"RangeVarPlot") ||
1130 PyDict_SetItemString(dict.ptr(),
"plot", Py_None);
1132 return dict.release().ptr();
1133 }
else if (strncmp(
n,
"_ref_", 5) == 0) {
1135 PyErr_SetString(PyExc_TypeError,
"not a HocTopLevelInterpreter or HocObject");
1138 sym =
getsym(
n + 5, self->ho_, 0);
1140 return PyObject_GenericGetAttr((
PyObject*) subself, pyname);
1146 }
else if (self->type_ ==
PyHoc::HocObject && !self->ho_->ctemplate->constructor) {
1153 char** cpp =
OPSTR(sym);
1156 return result.release().ptr();
1160 "Hoc pointer error, %s is not a hoc variable or range variable or strdef",
1166 }
else if (
is_obj_type(self->ho_,
"Vector") && strcmp(
n,
"__array_interface__") == 0) {
1169 Vect*
v = (
Vect*) self->ho_->u.this_pointer;
1170 int size =
v->size();
1173 return Py_BuildValue(
"{s:(i),s:s,s:i,s:(N,O)}",
1181 PyLong_FromVoidPtr(x),
1184 }
else if (
is_obj_type(self->ho_,
"RangeVarPlot") && strcmp(
n,
"plot") == 0) {
1186 }
else if (
is_obj_type(self->ho_,
"PlotShape") && strcmp(
n,
"plot") == 0) {
1188 }
else if (strcmp(
n,
"__doc__") == 0) {
1192 docobj = nb::make_tuple(self->ho_->ctemplate->sym->name,
1193 self->sym_ ? self->sym_->name :
"");
1194 }
else if (self->sym_) {
1196 docobj = nb::make_tuple(
"", self->sym_->name);
1199 docobj = nb::make_tuple(
"",
"");
1203 return result.release().ptr();
1208 strncmp(
n,
"__nrnsec_0x", 11) == 0) {
1211 PyErr_SetString(PyExc_NameError,
n);
1220 return result.release().ptr();
1224 PyErr_SetString(PyExc_NameError,
n);
1233 return result.release().ptr();
1237 return PyObject_GenericGetAttr((
PyObject*) subself, pyname);
1245 PyErr_SetString(PyExc_TypeError,
1246 "No hoc method for a callable. Missing parentheses before the '.'?");
1250 PyErr_SetString(PyExc_TypeError,
"Missing array index");
1258 po->
ho_ =
self->ho_;
1264 if (
t == VAR ||
t ==
STRING ||
t == OBJECTVAR ||
t == RANGEVAR ||
t == SECTION ||
1272 PyErr_SetString(PyExc_TypeError,
"No value");
1276 if (
t == SECTION ||
t == SECTIONREF) {
1280 return ret.release().ptr();
1283 auto handle = hoc_pop_handle<double>();
1286 return nrnpy_hoc_pop(
"use-the-component-fork hocobj_getattr");
1295 return ret_ho_.release().ptr();
1299 return ret_ho_.release().ptr();
1304 switch (sym->
type) {
1313 PyErr_SetString(PyExc_TypeError,
"Section access unspecified");
1324 PyErr_SetString(PyExc_TypeError,
"Cannot be a reference");
1376 case HOCOBJFUNCTION:
1383 po->
ho_ =
self->ho_;
1391 case SETPOINTERKEYWORD:
1400 PyErr_Format(PyExc_TypeError,
1401 "Cannot access %s directly; it is a range variable and may be accessed "
1402 "via a section or segment.",
1405 PyErr_Format(PyExc_TypeError,
1406 "Cannot access %s (NEURON type %d) directly.",
1413 return result.release().ptr();
1418 if (!PyArg_ParseTuple(args,
"O", &
name)) {
1432 if (name_str.c_str() && strcmp(name_str.c_str(),
"__doc__") == 0) {
1434 nb::object
result = nb::steal(PyObject_GenericGetAttr(subself,
name));
1437 return result.release().ptr();
1447 nb::object
result = nb::steal(PyObject_GenericGetAttr(subself,
name));
1450 return result.release().ptr();
1466 int issub = ((PyTypeObject*) PyObject_Type(subself) !=
hocobject_type);
1470 if (PyObject_HasAttr(subself, pyname)) {
1473 return PyObject_GenericSetAttr(subself, pyname,
value);
1485 char*
n =
name.c_str();
1494 return PyObject_GenericSetAttr(subself, pyname,
value);
1498 return PyObject_GenericSetAttr(
p, pyname,
value);
1499 }
else if (strncmp(
n,
"_ref_", 5) == 0) {
1501 if (rvsym && rvsym->
type == RANGEVAR) {
1504 PyErr_SetString(PyExc_TypeError,
"Point_process not located in a section");
1510 sym =
getsym(
n, self->ho_, 1);
1512 sym =
getsym(
n, self->ho_, 1);
1523 po->
ho_ =
self->ho_;
1537 PyErr_SetString(PyExc_TypeError,
"No value");
1542 PyErr_Format(PyExc_TypeError,
"'%s' requires subscript for assignment",
n);
1546 PyErr_SetString(PyExc_TypeError,
"not assignable");
1551 switch (sym->
type) {
1554 PyErr_SetString(PyExc_TypeError,
"Wrong number of subscripts");
1561 PyErr_SetString(PyExc_TypeError,
"Section access unspecified");
1568 if (PyArg_Parse(
value,
"i", &
i) != 0 &&
i > 0 &&
i <= 32767) {
1571 PyErr_SetString(PyExc_ValueError,
1572 "nseg must be an integer in range 1 to 32767");
1576 err = PyArg_Parse(
value,
"d", &x) == 0;
1596 if (PyArg_Parse(
value,
"s", &
s) == 1) {
1612 if (PyArg_Parse(
value,
"O", &po) == 1) {
1613 if (po == Py_None) {
1619 PyErr_SetString(PyExc_TypeError,
1620 "argument cannot be a hoc object intermediate");
1636 PyErr_SetString(PyExc_TypeError,
"not assignable");
1648 int nsub = a ? a->
nsub : 0;
1649 if (nsub <= po->nindex_) {
1650 std::ostringstream oss;
1651 oss <<
"Too many subscripts (Redeclared the array?), hoc var " << po->
sym_->
name
1652 <<
" now has " << nsub <<
" but trying to access dimension " << (po->
nindex_);
1653 PyErr_SetString(PyExc_TypeError, oss.str().c_str());
1680 if (ix < 0 ||
n <= ix) {
1683 PyErr_Format(PyExc_IndexError,
1686 (po->
ho_ && po->
sym_) ?
"." :
"",
1714 PyErr_SetString(PyExc_TypeError,
"hoc all section iterator() has no len()");
1717 PyErr_SetString(PyExc_TypeError,
"hoc SectionList iterator() has no len()");
1720 PyErr_SetString(PyExc_TypeError,
"Most HocObject have no len()");
1755 return po.release().ptr();
1766 nb::object
self = nb::borrow(raw_self);
1770 return PySeqIter_New(
self.ptr());
1772 return PySeqIter_New(
self.ptr());
1783 return po2.release().ptr();
1788 return self.release().ptr();
1790 return PySeqIter_New(
self.ptr());
1793 return self.release().ptr();
1795 PyErr_SetString(PyExc_TypeError,
"Not an iterable HocObject");
1861 if (curitem != ql) {
1920 }
else if (po->
sym_->
type == TEMPLATE) {
1943 PyErr_SetString(PyExc_IndexError,
"index for hoc ref must be 0");
1952 result = nb::steal(Py_BuildValue(
"d", *h));
1954 }
catch (std::exception
const& e) {
1956 PyErr_SetString(PyExc_IndexError, e.what());
1960 result = nb::steal(Py_BuildValue(
"d", po->
u.
x_));
1962 result = nb::steal(Py_BuildValue(
"s", po->
u.
s_));
1968 return result.release().ptr();
1980 return PyFloat_FromDouble(
vector_vec(hv)[ix]);
1987 if (ix < 0 || ix >= hl->
count()) {
1994 PyErr_SetString(PyExc_TypeError,
"unsubscriptable object");
2001 PyErr_SetString(PyExc_TypeError,
"unsubscriptable object");
2003 }
else if (po->
sym_->
type == TEMPLATE) {
2008 if (ob->
index == ix) {
2012 PyErr_Format(PyExc_IndexError,
"%s[%ld] instance does not exist", po->
sym_->
name, ix);
2016 PyErr_Format(PyExc_TypeError,
"unsubscriptable object, type %d\n", po->
type_);
2034 return result.release().ptr();
2075 return result.release().ptr();
2081 if (!PySlice_Check(slice)) {
2086 PyErr_SetString(PyExc_TypeError,
"Obj is NULL");
2090 PyErr_SetString(PyExc_TypeError,
"sequence index must be integer, not 'slice'");
2093 auto*
v = (
Vect*) po->ho_->u.this_pointer;
2094 Py_ssize_t start = 0;
2096 Py_ssize_t
step = 0;
2097 Py_ssize_t slicelen = 0;
2099 PySlice_GetIndicesEx(slice, len, &start, &end, &
step, &slicelen);
2101 PyErr_SetString(PyExc_ValueError,
"slice step cannot be zero");
2113 PyErr_SetString(PyExc_TypeError,
"incomplete hoc pointer");
2117 PyErr_SetString(PyExc_IndexError,
"index for hoc ref must be 0");
2124 PyArg_Parse(arg,
"d",
static_cast<double const*
>(h));
2128 }
catch (std::exception
const& e) {
2130 PyErr_SetString(PyExc_IndexError, e.what());
2134 PyArg_Parse(arg,
"d", &po->
u.
x_);
2137 PyArg_Parse(arg,
"s", &ts);
2141 PyArg_Parse(arg,
"s", &ts);
2145 PyArg_Parse(arg,
"O", &tp);
2158 if (
i >= vec_size ||
i < 0) {
2159 PyErr_SetString(PyExc_IndexError,
"index out of bounds");
2167 PyErr_SetString(PyExc_TypeError,
"unsubscriptable object");
2172 int nsub = a ? a->
nsub : 0;
2173 std::ostringstream oss;
2174 oss <<
"Wrong number of subscripts, hoc var " << po->
sym_->
name <<
" has " << nsub
2175 <<
" but compiled with " << (po->
nindex_ + 1);
2176 PyErr_SetString(PyExc_TypeError, oss.str().c_str());
2184 PyErr_SetString(PyExc_TypeError,
"not assignable");
2199 err = PyArg_Parse(arg,
"d",
hoc_pxpop()) != 1;
2211 if (PyArg_Parse(arg,
"O", &pyo) == 1) {
2222 PyErr_SetString(PyExc_TypeError,
"not assignable");
2231 if (!PySlice_Check(slice)) {
2236 PyErr_SetString(PyExc_TypeError,
"Obj is NULL");
2240 PyErr_SetString(PyExc_TypeError,
"sequence index must be integer, not 'slice'");
2243 auto v = (
Vect*) po->ho_->u.this_pointer;
2244 Py_ssize_t start = 0;
2246 Py_ssize_t
step = 0;
2247 Py_ssize_t slicelen = 0;
2249 PySlice_GetIndicesEx(slice, cap, &start, &end, &
step, &slicelen);
2251 auto iter = nb::steal(PyObject_GetIter(arg));
2253 PyErr_SetString(PyExc_TypeError,
"can only assign an iterable");
2256 for (Py_ssize_t
i = 0;
i < slicelen; ++
i) {
2257 auto val = nb::steal(PyIter_Next(iter.ptr()));
2259 PyErr_SetString(PyExc_IndexError,
2260 "iterable object must have the same length as slice (it's too short)");
2265 auto val = nb::steal(PyIter_Next(iter.ptr()));
2267 PyErr_SetString(PyExc_IndexError,
2268 "iterable object must have the same length as slice (it's too long)");
2276 if (PyArg_ParseTuple(args,
"O", &pa) == 1) {
2281 auto pn = nb::steal(PyNumber_Float(pa));
2282 result->u.x_ = PyFloat_AsDouble(pn.ptr());
2287 if (!str.is_valid()) {
2289 "string arg must have only ascii characters");
2292 char* cpa = str.c_str();
2298 return result_guard.release().ptr();
2300 PyErr_SetString(PyExc_TypeError,
"single arg must be number, string, or Object");
2328 return result_guard.release().ptr();
2345 char*
n = str.c_str();
2346 if (!str.is_valid()) {
2348 "POINTER name can contain only ascii characters");
2357 PyErr_SetString(PyExc_TypeError,
"Point_process not located in a section");
2360 gh = &(
prop->dparam[sym->
u.
rng.index]);
2371 PyErr_SetString(PyExc_TypeError,
2372 "setpointer(_ref_hocvar, 'POINTER_name', point_process or "
2386 po = Py_BuildValue(
"O", PyLong_FromVoidPtr(ho));
2389 PyErr_SetString(PyExc_TypeError,
"HocObject does not wrap a Hoc Object");
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 result = self_ptr > other_ptr;
2421 result = self_ptr >= other_ptr;
2424 return PyBool_FromLong(
result);
2429 auto* pyhoc_other =
reinterpret_cast<PyHocObject*
>(other);
2430 void* self_ptr =
self->
ho_;
2431 void* other_ptr = other;
2432 bool are_equal =
true;
2434 if (pyhoc_other->type_ == self->type_) {
2435 switch (self->type_) {
2441 self_ptr = (
void*)
self;
2444 if (self->ho_ != pyhoc_other->ho_) {
2447 }
else if (op == Py_EQ) {
2451 PyErr_SetString(PyExc_TypeError,
"this comparison is undefined");
2454 self_ptr =
self->sym_;
2455 other_ptr = pyhoc_other->sym_;
2459 self_ptr =
static_cast<double*
>(
self->u.px_);
2460 other_ptr =
static_cast<double*
>(pyhoc_other->u.px_);
2464 if (op != Py_EQ && op != Py_NE) {
2466 PyErr_SetString(PyExc_TypeError,
"this comparison is undefined");
2469 if (self->ho_ != pyhoc_other->ho_) {
2471 other_ptr = pyhoc_other->ho_;
2474 if (self->nindex_ != pyhoc_other->nindex_ || self->sym_ != pyhoc_other->sym_) {
2475 return PyBool_FromLong(op == Py_NE);
2477 for (
int i = 0;
i <
self->nindex_;
i++) {
2478 if (self->indices_[
i] != pyhoc_other->indices_[
i]) {
2482 return PyBool_FromLong(are_equal == (op == Py_EQ));
2484 other_ptr = pyhoc_other->ho_;
2489 }
else if (op == Py_NE) {
2493 PyErr_SetString(PyExc_TypeError,
"this comparison is undefined");
2502 if (PyArg_ParseTuple(args,
"O", &po)) {
2515 if (PyObject_HasAttrString(po,
"__array_interface__")) {
2516 auto ai = nb::steal(PyObject_GetAttrString(po,
"__array_interface__"));
2519 data = PyLong_AsVoidPtr(PyTuple_GetItem(PyDict_GetItemString(ai.ptr(),
"data"), 0));
2521 if (PyErr_Occurred()) {
2524 PyObject* pstride = PyDict_GetItemString(ai.ptr(),
"strides");
2525 if (pstride == Py_None) {
2527 }
else if (PyTuple_Check(pstride)) {
2528 if (PyTuple_Size(pstride) == 1) {
2529 PyObject* psize = PyTuple_GetItem(pstride, 0);
2530 if (PyLong_Check(psize)) {
2531 stride = PyLong_AsLong(psize);
2536 PyErr_SetString(PyExc_TypeError,
2537 "array_interface stride element of invalid type.");
2544 PyErr_SetString(PyExc_TypeError,
"array_interface stride object of invalid type.");
2549 return static_cast<char*
>(
data);
2554 if (!PyNumber_Check(obj)) {
2556 Sprintf(
buf,
"item %d is not a valid number", obj_id);
2559 return PyFloat_AsDouble(obj);
2573 if (!PySequence_Check(po.ptr())) {
2574 if (!PyIter_Check(po.ptr())) {
2576 " does not support the Python Sequence or Iterator protocol");
2586 int size = nb::len(po);
2593 if (array_interface_ptr) {
2594 for (
int i = 0,
j = 0;
i < size; ++
i,
j +=
stride) {
2595 x[
i] = *(
double*) (array_interface_ptr +
j);
2601 if (PyList_Check(po.ptr())) {
2603 for (
long i = 0;
i < size; ++
i) {
2607 for (
long i = 0;
i < size; ++
i) {
2633 delete[](*save_data);
2635 *save_data_size =
result.size();
2636 *save_data =
new char[*save_data_size];
2637 memcpy(*save_data,
result.c_str(), *save_data_size);
2639 *save_data_size = 0;
2645 nb::bytearray py_data(
data, size);
2655 hoc_execerror(
"SaveState:",
"Missing data restore function.");
2683 return PyFloat_AsDouble(pyobj.ptr());
2708 auto args = nb::steal(PyTuple_New(
narg + 3));
2710 PyTuple_SetItem(args.ptr(), 0, pyname.release().ptr());
2711 for (
int iarg = 0; iarg <
narg; iarg++) {
2712 const int iiarg = iarg + 1;
2715 PyTuple_SetItem(args.ptr(), iarg + 3, active_obj.release().ptr());
2719 ptr_nrn->
u.
px_ = hoc_hgetarg<double>(iiarg);
2722 PyTuple_SetItem(args.ptr(), iarg + 3, py_ptr);
2724 if (handle_strptr > 0) {
2728 PyTuple_SetItem(args.ptr(), iarg + 3, py_ptr);
2731 PyTuple_SetItem(args.ptr(), iarg + 3, py_str.release().ptr());
2734 auto py_double = nb::steal(PyFloat_FromDouble(*
getarg(iiarg)));
2735 PyTuple_SetItem(args.ptr(), iarg + 3, py_double.release().ptr());
2744 my_obj = nb::none();
2746 PyTuple_SetItem(args.ptr(), 1, my_obj.release().ptr());
2753 my_obj2 = nb::none();
2756 PyTuple_SetItem(args.ptr(), 2, my_obj2.release().ptr());
2757 auto po = nb::steal(PyObject_CallObject(
gui_callback, args.ptr()));
2758 if (PyErr_Occurred()) {
2762 po = nb::steal(PyLong_FromLong(0));
2764 return po.release().ptr();
2799 if (!po.is_none()) {
2811 int size = hv->
size();
2829 if (!PySequence_Check(po.ptr())) {
2832 if (size != PySequence_Size(po.ptr())) {
2836 if (!(po = nb::steal(PyList_New(size)))) {
2837 hoc_execerror(
"Could not create new Python List with correct size.", 0);
2847 for (
int i = 0,
j = 0;
i < size; ++
i,
j +=
stride) {
2848 *(
double*) (y +
j) = x[
i];
2850 }
else if (PyList_Check(po.ptr())) {
2851 for (
int i = 0;
i < size; ++
i) {
2852 auto pn = nb::steal(PyFloat_FromDouble(x[
i]));
2853 if (!pn || PyList_SetItem(po.ptr(),
i, pn.release().ptr()) == -1) {
2860 for (
int i = 0;
i < size; ++
i) {
2861 auto pn = nb::steal(PyFloat_FromDouble(x[
i]));
2862 if (!pn || PySequence_SetItem(po.ptr(),
i, pn.ptr()) == -1) {
2898 nanobind::gil_scoped_acquire
lock{};
2902 PyErr_SetString(PyExc_TypeError,
"get_plotshape_variable only takes PlotShape objects");
2908 spi = ((ShapePlot*) that);
2919 py_obj = nb::none();
2922 return Py_BuildValue(
"sNffN",
2924 py_obj.release().ptr(),
2927 py_sl.release().ptr());
2936 PyErr_SetString(PyExc_TypeError,
"HocObject: Only Vector instance can be pickled");
2943 nb::module_ mod = nb::module_::import_(
"neuron");
2947 nb::object obj = mod.attr(
"_pkl");
2949 PyErr_SetString(PyExc_Exception,
"neuron module has no _pkl method.");
2965 nb::bytes byte_order((
const void*) (&x),
sizeof(
double));
2966 nb::bytes vec_data(vec->
data(), vec->
size() *
sizeof(
double));
2967 nb::tuple state = nb::make_tuple(1, byte_order, vec->
size(), vec_data);
2969 return nb::make_tuple(obj, nb::make_tuple(0), state).release().ptr();
2977 #define BYTEHEADER \
2981 int BYTESWAP_FLAG = 0;
2982 #define BYTESWAP(_X__, _TYPE__) \
2983 if (BYTESWAP_FLAG == 1) { \
2984 _IN__ = (char*) &(_X__); \
2985 for (_II__ = 0; _II__ < sizeof(_TYPE__); _II__++) { \
2986 _OUT__[_II__] = _IN__[sizeof(_TYPE__) - _II__ - 1]; \
2988 (_X__) = *((_TYPE__*) &_OUT__); \
2995 nb::object endian_data;
3003 if (!PyArg_ParseTuple(args,
"(iOiO)", &version, &pendian_data, &size, &prawdata)) {
3007 rawdata = nb::borrow(prawdata);
3008 endian_data = nb::borrow(pendian_data);
3012 if (!PyBytes_Check(rawdata.ptr()) || !PyBytes_Check(endian_data.ptr())) {
3013 PyErr_SetString(PyExc_TypeError,
"pickle not returning string");
3018 if (PyBytes_AsStringAndSize(endian_data.ptr(), &
two, &len) < 0) {
3021 if (len !=
sizeof(
double)) {
3022 PyErr_SetString(PyExc_ValueError,
"endian_data size is not sizeof(double)");
3026 if (*((
double*)
two) != 2.0) {
3031 if (PyBytes_AsStringAndSize(rawdata.ptr(), &str, &len) < 0) {
3034 if (len != Py_ssize_t(size *
sizeof(
double))) {
3035 PyErr_SetString(PyExc_ValueError,
"buffer size does not match array size");
3038 if (BYTESWAP_FLAG) {
3039 double* x = (
double*) str;
3040 for (
int i = 0;
i < size; ++
i) {
3054 #if defined(HAVE_DLFCN_H) && !defined(MINGW)
3056 int rval =
dladdr((
const void*) Py_Initialize, &
info);
3058 PyErr_SetString(PyExc_Exception,
3059 "dladdr: Py_Initialize could not be matched to a shared object");
3062 if (!
info.dli_fname) {
3063 PyErr_SetString(PyExc_Exception,
3064 "dladdr: No symbol matching Py_Initialize could be found.");
3067 return Py_BuildValue(
"s",
info.dli_fname);
3080 {
"hocobjptr",
hocobj_vptr_safe, METH_NOARGS,
"Hoc Object pointer as a long int"},
3084 "o1.same(o2) return True if o1 and o2 wrap the same internal HOC Object"},
3085 {
"hname",
hocobj_name_safe, METH_NOARGS,
"More specific than __str__() or __attr__()."},
3088 {
nullptr,
nullptr, 0,
nullptr}};
3092 {
"ref",
mkref_safe, METH_VARARGS,
"Wrap to allow call by reference in a hoc function"},
3093 {
"cas",
nrnpy_cas_safe, METH_VARARGS,
"Return the currently accessed section."},
3094 {
"allsec",
nrnpy_forall_safe, METH_VARARGS,
"Return iterator over all sections."},
3097 METH_VARARGS | METH_KEYWORDS,
3098 "Return a new Section"},
3099 {
"setpointer",
setpointer_safe, METH_VARARGS,
"Assign hoc variable address to NMODL POINTER"},
3103 "Return full path to file that contains Py_Initialize()"},
3104 {
nullptr,
nullptr, 0,
nullptr}};
3109 auto nn = nb::steal(Py_BuildValue(
"s", meth->ml_doc));
3113 err = PyDict_SetItemString(dict, meth->ml_name, nn.ptr());
3146 bool potentially_valid =
false;
3149 potentially_valid =
true;
3151 potentially_valid =
true;
3154 if (!potentially_valid) {
3155 Py_INCREF(Py_NotImplemented);
3156 return Py_NotImplemented;
3159 return PyObject_CallFunction(
nrnpy_vec_math, strcpy(
buf,
"siOO"), op, reversed, obj1, obj2);
3167 Py_INCREF(Py_NotImplemented);
3168 return Py_NotImplemented;
3204 char endian_character = 0;
3206 auto psys = nb::steal(PyImport_ImportModule(
"sys"));
3208 PyErr_SetString(PyExc_ImportError,
"Failed to import sys to determine system byteorder.");
3212 auto pbo = nb::steal(PyObject_GetAttrString(psys.ptr(),
"byteorder"));
3214 PyErr_SetString(PyExc_AttributeError,
"sys module does not have attribute 'byteorder'!");
3219 if (!byteorder.is_valid()) {
3223 if (strcmp(byteorder.c_str(),
"little") == 0) {
3224 endian_character =
'<';
3225 }
else if (strcmp(byteorder.c_str(),
"big") == 0) {
3226 endian_character =
'>';
3228 PyErr_SetString(PyExc_RuntimeError,
"Unknown system native byteorder.");
3231 return endian_character;
3240 auto iterator = nb::steal(PyObject_GetIter(pargs));
3248 while ((item = nb::steal(PyIter_Next(iterator.ptr())))) {
3250 hoc_execerror(
"iterable must contain only Section objects", 0);
3256 if (PyErr_Occurred()) {
3276 PyObject* modules = PyImport_GetModuleDict();
3278 PyObject* module = PyDict_GetItemString(modules,
"neuron.coreneuron");
3280 auto val = nb::steal(PyObject_GetAttrString(module, option));
3282 long enable = PyLong_AsLong(val.ptr());
3289 if (PyErr_Occurred()) {
3311 extern char* (*nrnpy_nrncore_arg_p_)(
double tstop);
3313 PyObject* modules = PyImport_GetModuleDict();
3315 PyObject* module = PyDict_GetItemString(modules,
"neuron.coreneuron");
3317 auto callable = nb::steal(PyObject_GetAttrString(module,
"nrncore_arg"));
3319 auto ts = nb::steal(Py_BuildValue(
"(d)", tstop));
3321 auto arg = nb::steal(PyObject_CallObject(callable.ptr(), ts.ptr()));
3324 if (!str.is_valid()) {
3327 "neuron.coreneuron.nrncore_arg() must return an ascii string");
3330 if (strlen(str.c_str()) > 0) {
3331 return strdup(str.c_str());
3338 if (PyErr_Occurred()) {
3350 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
3377 nanobind::gil_scoped_acquire
lock{};
3379 char endian_character = 0;
3382 PyObject* modules = PyImport_GetModuleDict();
3383 if ((m = PyDict_GetItemString(modules,
"hoc")) && PyModule_Check(m)) {
3410 size_t alignment =
alignof(
Symbol*);
3412 if (remainder != 0) {
3425 if (!custom_hocclass) {
3428 if (PyModule_AddObject(m,
"HocClass", custom_hocclass) < 0) {
3437 pto = (PyTypeObject*)
3445 if (PyType_Ready(pto) < 0) {
3448 if (PyModule_AddObject(m,
name, (
PyObject*) pto) < 0) {
3458 err = PyDict_SetItemString(
topmethdict, meth->ml_name, descr.ptr());
3486 if (endian_character == 0) {
3493 err = PyDict_SetItemString(modules,
"hoc", m);
3511 if (!PyCallable_Check(
func)) {
3514 auto result = nb::steal(PyObject_CallFunction(
func,
"d", x));
3517 hoc_execerror(
"Python function call raised exception",
nullptr);
3519 if (!PyNumber_Check(
result.ptr())) {
3520 hoc_execerror(
"Expected a numeric result from Python function",
nullptr);
3523 if (PyErr_Occurred()) {
3524 hoc_execerror(
"Failed to convert result to float",
nullptr);
3543 if (!PyObject_HasAttrString(py_obj, method)) {
3547 PyObject* py_method = PyObject_GetAttrString(py_obj, method);
3553 if (!PyCallable_Check(py_method)) {
3554 Py_DECREF(py_method);
3559 auto result = nb::steal(PyObject_CallFunctionObjArgs(py_method, py_arg,
nullptr));
3560 Py_DECREF(py_method);
3568 if (PyNumber_Check(
result.ptr())) {
3571 if (PyErr_Occurred()) {
3622 long long vll = (
long long)
value;
3624 if ((
double) vll ==
value) {
3625 py_arg = PyLong_FromLongLong(vll);
3630 py_arg = PyFloat_FromDouble(
value);
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)
std::string to_string(EnumT e, const std::array< std::pair< EnumT, std::string_view >, N > &mapping, const std::string_view enum_name)
Converts an enum value to its corresponding string representation.
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)
Type-safe sprintf replacement using snprintf with automatic buffer size deduction.
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_
int(* nrnpy_call_obj_method_double)(Object *obj, const char *method, double value)
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 int nrnpy_call_obj_method_(Object *, const char *, Object *)
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(* nrnpy_call_obj_method)(Object *obj, const char *method, Object *obj2)
int hocobj_pushargs(PyObject *args, std::vector< neuron::unique_cstr > &s2free)
static int nrnpy_call_obj_method_helper_(Object *obj, const char *method, PyObject *py_arg)
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 int nrnpy_call_obj_method_double_(Object *, const char *, double)
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)