Skip to content
Snippets Groups Projects
Unverified Commit d2623ecf authored by thorstenhater's avatar thorstenhater Committed by GitHub
Browse files

More pythonic membership on mechanism_catalogue. (#1306)

Introduce two minor changes to the Python API
to handle mechanism_catalogues idiomatically.

Instead of

import arbor as A

cat = A.default_catalogue()

if cat.has('hh'):
  print("Found HH.")

for mech in cat.keys():
   print("*", mech)

we can now write

import arbor as A

cat = A.default_catalogue()

if 'hh' in cat:
  print("Found HH.")

for mech in cat:
   print("*", mech)

which is closer to the expectations of Python users.
parent 54ab542f
No related branches found
No related tags found
No related merge requests found
......@@ -246,10 +246,19 @@ Mechanism catalogues
2. A further hierarchy of *derived* mechanisms, that allow specialization of
global parameters, ion bindings, and implementations.
.. py:method:: has(name)
.. py:method:: __contains__(name)
Test if mechanism with *name* is in the catalogue.
Note: This enables the following idiom
.. code-block:: Python
import arbor
if 'hh' in arbor.default_catalogue():
print("Found HH mechanism.")
:param name: name of mechanism.
:type name: str
:return: bool
......@@ -280,11 +289,20 @@ Mechanism catalogues
:return: mechanism metadata
:rtype: :class:`mechanism_info`
.. py:method:: names()
.. py:method:: __iter___()
Return a list names of all the mechanisms in the catalogue.
:return: list
Note: This enables the following idiom
.. code-block:: Python
import arbor
for name in arbor.default_catalogue():
print(name)
:return: :class:`py_mech_cat_iterator`
.. py:method:: derive(name, parent, globals={}, ions={})
......
......@@ -104,12 +104,29 @@ void register_mechanisms(pybind11::module& m) {
return util::pprintf("(arbor.mechanism_info)"); });
pybind11::class_<arb::mechanism_catalogue> cat(m, "catalogue");
struct py_mech_cat_iterator {
py_mech_cat_iterator(const arb::mechanism_catalogue &cat, pybind11::object ref) : names(cat.mechanism_names()), ref(ref), idx{0} { }
std::vector<std::string> names;
pybind11::object ref; // keep a reference to cat lest it dies while we iterate
size_t idx = 0;
std::string next() {
if (idx == names.size()) throw pybind11::stop_iteration();
return names[idx++];
}
};
pybind11::class_<py_mech_cat_iterator>(cat, "MechCatIterator")
.def("__iter__", [](py_mech_cat_iterator &it) -> py_mech_cat_iterator& { return it; })
.def("__next__", &py_mech_cat_iterator::next);
cat
.def(pybind11::init<const arb::mechanism_catalogue&>())
.def("has", &arb::mechanism_catalogue::has,
.def("__contains__", &arb::mechanism_catalogue::has,
"name"_a, "Is 'name' in the catalogue?")
.def("keys", &arb::mechanism_catalogue::mechanism_names,
"Return a list of all mechanisms in this catalogues.")
.def("__iter__",
[](pybind11::object cat) { return py_mech_cat_iterator(cat.cast<const arb::mechanism_catalogue &>(), cat); },
"Return an iterator over all mechanism names in this catalogues.")
.def("is_derived", &arb::mechanism_catalogue::is_derived,
"name"_a, "Is 'name' a derived mechanism or can it be implicitly derived?")
.def("__getitem__",
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment