From 14e01fd4a493c14455e5bcf164681e02bb01c894 Mon Sep 17 00:00:00 2001 From: Chase Geigle Date: Tue, 28 Mar 2017 04:08:02 -0500 Subject: [PATCH] Bump meta and pybind11 deps; improve parser::visitor bindings. --- deps/meta | 2 +- deps/pybind11 | 2 +- src/metapy_analyzers.cpp | 1 + src/metapy_embeddings.cpp | 1 + src/metapy_index.cpp | 1 + src/metapy_parser.cpp | 38 ++++++++++++++++++++++++++++++++------ src/metapy_sequence.cpp | 13 +++++++++++-- 7 files changed, 48 insertions(+), 10 deletions(-) diff --git a/deps/meta b/deps/meta index 349064d..06b69e8 160000 --- a/deps/meta +++ b/deps/meta @@ -1 +1 @@ -Subproject commit 349064dc15ce99bf12ad7656bd223b77403e8c0b +Subproject commit 06b69e8c980fdb89a4129cce7a96e51c02edaaef diff --git a/deps/pybind11 b/deps/pybind11 index d361ea1..d6fdafb 160000 --- a/deps/pybind11 +++ b/deps/pybind11 @@ -1 +1 @@ -Subproject commit d361ea15fb72bfba21f6d3aac9491467a13ebb21 +Subproject commit d6fdafb203560dc3fbb905e065b2b9cb478b0127 diff --git a/src/metapy_analyzers.cpp b/src/metapy_analyzers.cpp index 2bba38b..aa66f30 100644 --- a/src/metapy_analyzers.cpp +++ b/src/metapy_analyzers.cpp @@ -14,6 +14,7 @@ #include #include "metapy_analyzers.h" +#include "metapy_identifiers.h" #include "metapy_probe_map.h" #include "cpptoml.h" diff --git a/src/metapy_embeddings.cpp b/src/metapy_embeddings.cpp index 1bab54f..4575423 100644 --- a/src/metapy_embeddings.cpp +++ b/src/metapy_embeddings.cpp @@ -14,6 +14,7 @@ #include "cpptoml.h" #include "meta/embeddings/word_embeddings.h" #include "metapy_embeddings.h" +#include "metapy_identifiers.h" namespace py = pybind11; using namespace meta; diff --git a/src/metapy_index.cpp b/src/metapy_index.cpp index 6c297c9..193e1ec 100644 --- a/src/metapy_index.cpp +++ b/src/metapy_index.cpp @@ -12,6 +12,7 @@ #include #include +#include "metapy_identifiers.h" #include "metapy_index.h" #include "cpptoml.h" diff --git a/src/metapy_parser.cpp b/src/metapy_parser.cpp index febbb23..3dbdcea 100644 --- a/src/metapy_parser.cpp +++ b/src/metapy_parser.cpp @@ -30,6 +30,7 @@ #include "meta/parser/io/ptb_reader.h" +#include "metapy_identifiers.h" #include "metapy_parser.h" namespace py = pybind11; @@ -143,6 +144,7 @@ void metapy_bind_parser(py::module& m) py::class_{m_parse, "LeafNode"} .def(py::init()) + .def(py::init()) .def("word", [](const leaf_node& ln) { return *ln.word(); }); py::class_{m_parse, "InternalNode"} @@ -172,9 +174,28 @@ void metapy_bind_parser(py::module& m) [](internal_node& n, const node* descendent) { n.head_constituent(descendent); }) - .def("each_child", [](internal_node& n, std::function fn) { - n.each_child(fn); - }); + // weirdness: need to ensure that the child nodes passed down to + // the python lambda preserve the lifetime of the current internal + // node in case they are stored internally + .def("each_child", + [](internal_node& n, py::function fn) { + n.each_child([&](node* child) { + auto handle = py::cast( + *child, py::return_value_policy::reference_internal, + py::cast(n)); + fn(handle); + }); + }) + .def("__getitem__", + [](internal_node& n, int64_t offset) { + uint64_t idx = offset >= 0 ? static_cast(offset) + : n.num_children() + offset; + if (idx >= n.num_children()) + throw py::index_error(); + return n.child(idx); + }, + py::keep_alive<0, 1>()) + .def("__len__", &internal_node::num_children); py::class_{m_parse, "ParseTree"} .def("__init__", @@ -194,9 +215,14 @@ void metapy_bind_parser(py::module& m) tree.pretty_print(ss); return ss.str(); }) - .def("visit", [](parse_tree& tree, parser::visitor& vtor) { - return tree.visit(vtor); - }); + // keep_alive here is to ensure that the visitor keeps the tree + // alive as long as it is still referenced, since it might hold an + // internal pointer into the tree + .def("visit", + [](parse_tree& tree, parser::visitor& vtor) { + return tree.visit(vtor); + }, + py::keep_alive<2, 1>()); py::implicitly_convertible(); diff --git a/src/metapy_sequence.cpp b/src/metapy_sequence.cpp index 2d9df1c..81c0ea8 100644 --- a/src/metapy_sequence.cpp +++ b/src/metapy_sequence.cpp @@ -17,6 +17,9 @@ #include "meta/sequence/perceptron.h" #include "meta/sequence/sequence.h" +#include "metapy_identifiers.h" +#include "metapy_sequence.h" + namespace py = pybind11; using namespace meta; @@ -56,14 +59,20 @@ void metapy_bind_sequence(py::module& m) .def("add_observation", &sequence::sequence::add_observation) .def("add_symbol", &sequence::sequence::add_symbol) .def("__getitem__", - [](sequence::sequence& seq, sequence::sequence::size_type idx) { + [](sequence::sequence& seq, int64_t offset) { + std::size_t idx = offset >= 0 + ? static_cast(offset) + : seq.size() + offset; if (idx >= seq.size()) throw py::index_error(); return seq[idx]; }) .def("__setitem__", - [](sequence::sequence& seq, sequence::sequence::size_type idx, + [](sequence::sequence& seq, int64_t offset, sequence::observation obs) { + std::size_t idx = offset >= 0 + ? static_cast(offset) + : seq.size() + offset; if (idx >= seq.size()) throw py::index_error(); seq[idx] = std::move(obs);