C++: Extract internal property maps of an GraphInterface object


when using graph-tool from C++, you can use one or more PropertyMaps. In
the documentation they are always given as an extra argument. Since
graph-tool has internal PropertyMaps, is it possible to extract internal
PropertyMaps out of the GraphInterface object?

In pseudo code (like in the documentation):

void kcore_bind(GraphInterface& gi)
    // Vertex property map of type int32_t
    typedef typename vprop_map_t<int32_t>::type vprop_t;
    vprop_t c = boost::any_cast<vprop_t>(gi.get_internal_vertex_property_map("foo"));

        ([&](auto& g){ kcore_decomposition(g, c.get_unchecked()); },
         all_graph_views()) (gi.get_graph_view());

Is there a way to simulate the `get_internal_vertex_property_map`


No, that's not possible, because the internal property maps are not
stored in GraphInterface; they are kept only in the Python side of things.

But you map pass the property map dictionary (e.g. g.edge_properties) to
C++, and lookup from there.


Ok, thank you. I now do exactly that. Here is a minimal example in case
anyone else need it (I have not tested exactly this version, maybe some
errors are present). Maybe you also know a more elegant version.

#include <graph_tool.hh>
#include <Python.h>
#include <boost/python.hpp>
#include <cassert>
#include <exception>

template <class Property>
Property get_property(PyObject* prop_dict, const char* key) {
	PyObject* prop = PyObject_GetItem(prop_dict, PyUnicode_FromString(key));
	assert(prop != nullptr);

	PyObject* prop_any = PyObject_CallMethod(prop, "_get_any", nullptr);
	assert(prop_any != nullptr);

	boost::python::extract<boost::any> get_property(prop_any);

	try {
		return boost::any_cast<Property>(get_property());
	} catch (boost::bad_any_cast& e) {
		std::cerr << "Bad any cast for attribute '" << key << "'" << std::endl;
		throw e;

struct CPPGraph {
	graph_tool::GraphInterface* graph;
	typename graph_tool::vprop_map_t<std::string>::type strprop;
	typename graph_tool::vprop_map_t<int>::type intprop;
	typename graph_tool::vprop_map_t<unsigned char>::type boolprop;

	typename graph_tool::eprop_map_t<int>::type edge_intprop;
	typename graph_tool::eprop_map_t<unsigned char>::type edge_boolprop;

	CPPGraph(PyObject* graph) {
		PyObject* py_graph = PyObject_GetAttrString(graph, "_Graph__graph");
		assert(py_graph != nullptr);
		boost::python::extract<graph_tool::GraphInterface&> get_graph_interface(py_graph);
		this->graph = &get_graph_interface();

		PyObject* vprops = PyObject_GetAttrString(graph, "vertex_properties");
		assert(vprops != nullptr);
		strprop = get_property<decltype(strprop)>(vprops, "strprop");
		intprop = get_property<decltype(intprop)>(vprops, "intprop");
		boolprop = get_property<decltype(boolprop)>(vprops, "boolprop");

		PyObject* eprops = PyObject_GetAttrString(graph, "edge_properties");
		assert(eprops != nullptr);
		edge_intprop = get_property<decltype(edge_intprop)>(eprops, "edge_intprop");
		edge_boolprop = get_property<decltype(edge_boolprop)>(eprops, "bool_intprop");