Commit 4026fb2a authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

Implement get_graph() method in Edge and Vertex classes

This also makes all Edge classes inherit from the same base class of the
same name.

This fixes tickets #94 and #95
parent 70b50865
...@@ -43,7 +43,7 @@ struct get_vertex_iterator ...@@ -43,7 +43,7 @@ struct get_vertex_iterator
python::object get_vertices(python::object g) python::object get_vertices(python::object g)
{ {
GraphInterface& gi = python::extract<GraphInterface&>(g()); GraphInterface& gi = python::extract<GraphInterface&>(g().attr("_Graph__graph"));
python::object iter; python::object iter;
run_action<>()(gi, bind<void>(get_vertex_iterator(), _1, run_action<>()(gi, bind<void>(get_vertex_iterator(), _1,
ref(g), ref(g),
...@@ -86,7 +86,7 @@ struct get_vertex_hard ...@@ -86,7 +86,7 @@ struct get_vertex_hard
python::object get_vertex(python::object g, size_t i) python::object get_vertex(python::object g, size_t i)
{ {
GraphInterface& gi = python::extract<GraphInterface&>(g()); GraphInterface& gi = python::extract<GraphInterface&>(g().attr("_Graph__graph"));
python::object v; python::object v;
if (gi.IsVertexFilterActive()) if (gi.IsVertexFilterActive())
run_action<>()(gi, run_action<>()(gi,
...@@ -111,7 +111,7 @@ struct get_edge_iterator ...@@ -111,7 +111,7 @@ struct get_edge_iterator
python::object get_edges(python::object g) python::object get_edges(python::object g)
{ {
GraphInterface& gi = python::extract<GraphInterface&>(g()); GraphInterface& gi = python::extract<GraphInterface&>(g().attr("_Graph__graph"));
python::object iter; python::object iter;
run_action<>()(gi, run_action<>()(gi,
bind<void>(get_edge_iterator(), _1, ref(g), ref(iter)))(); bind<void>(get_edge_iterator(), _1, ref(g), ref(iter)))();
...@@ -120,7 +120,7 @@ python::object get_edges(python::object g) ...@@ -120,7 +120,7 @@ python::object get_edges(python::object g)
python::object add_vertex(python::object g) python::object add_vertex(python::object g)
{ {
GraphInterface& gi = python::extract<GraphInterface&>(g()); GraphInterface& gi = python::extract<GraphInterface&>(g().attr("_Graph__graph"));
return python::object(PythonVertex(g, add_vertex(gi.GetGraph()))); return python::object(PythonVertex(g, add_vertex(gi.GetGraph())));
} }
...@@ -188,7 +188,7 @@ python::object add_edge(python::object g, const python::object& s, ...@@ -188,7 +188,7 @@ python::object add_edge(python::object g, const python::object& s,
PythonVertex& tgt = python::extract<PythonVertex&>(t); PythonVertex& tgt = python::extract<PythonVertex&>(t);
src.CheckValid(); src.CheckValid();
tgt.CheckValid(); tgt.CheckValid();
GraphInterface& gi = python::extract<GraphInterface&>(g()); GraphInterface& gi = python::extract<GraphInterface&>(g().attr("_Graph__graph"));
python::object new_e; python::object new_e;
run_action<>()(gi, bind<void>(add_new_edge(), _1, ref(g), ref(gi), src, tgt, run_action<>()(gi, bind<void>(add_new_edge(), _1, ref(g), ref(gi), src, tgt,
gi.GetEdgeIndex(), ref(new_e)))(); gi.GetEdgeIndex(), ref(new_e)))();
...@@ -308,8 +308,7 @@ struct export_python_interface ...@@ -308,8 +308,7 @@ struct export_python_interface
void operator()(const Graph*, set<string>& v_iterators) const void operator()(const Graph*, set<string>& v_iterators) const
{ {
using namespace boost::python; using namespace boost::python;
class_<PythonEdge<Graph>, bases<EdgeBase> >
class_<PythonEdge<Graph> >
("Edge", no_init) ("Edge", no_init)
.def("source", &PythonEdge<Graph>::GetSource, .def("source", &PythonEdge<Graph>::GetSource,
"Return the source vertex.") "Return the source vertex.")
...@@ -317,6 +316,8 @@ struct export_python_interface ...@@ -317,6 +316,8 @@ struct export_python_interface
"Return the target vertex.") "Return the target vertex.")
.def("is_valid", &PythonEdge<Graph>::IsValid, .def("is_valid", &PythonEdge<Graph>::IsValid,
"Return whether the edge is valid.") "Return whether the edge is valid.")
.def("get_graph", &PythonEdge<Graph>::GetGraph,
"Return the graph to which the edge belongs.")
.def(python::self == python::self) .def(python::self == python::self)
.def(python::self != python::self) .def(python::self != python::self)
.def("__str__", &PythonEdge<Graph>::GetString) .def("__str__", &PythonEdge<Graph>::GetString)
...@@ -401,11 +402,14 @@ void export_python_interface() ...@@ -401,11 +402,14 @@ void export_python_interface()
"Return an iterator over the in-edges.") "Return an iterator over the in-edges.")
.def("is_valid", &PythonVertex::IsValid, .def("is_valid", &PythonVertex::IsValid,
"Return whether the vertex is valid.") "Return whether the vertex is valid.")
.def("get_graph", &PythonVertex::GetGraph,
"Return the graph to which the vertex belongs.")
.def(python::self == python::self) .def(python::self == python::self)
.def(python::self != python::self) .def(python::self != python::self)
.def("__str__", &PythonVertex::GetString) .def("__str__", &PythonVertex::GetString)
.def("__int__", &PythonVertex::GetIndex) .def("__int__", &PythonVertex::GetIndex)
.def("__hash__", &PythonVertex::GetHash); .def("__hash__", &PythonVertex::GetHash);
class_<EdgeBase>("EdgeBase", no_init);
set<string> v_iterators; set<string> v_iterators;
typedef mpl::transform<graph_tool::detail::all_graph_views, typedef mpl::transform<graph_tool::detail::all_graph_views,
......
...@@ -84,7 +84,7 @@ public: ...@@ -84,7 +84,7 @@ public:
{ {
if (_g().ptr() == Py_None) if (_g().ptr() == Py_None)
return false; return false;
GraphInterface& gi = python::extract<GraphInterface&>(_g()); GraphInterface& gi = python::extract<GraphInterface&>(_g().attr("_Graph__graph"));
return _valid && return _valid &&
(_v != graph_traits<GraphInterface::multigraph_t>::null_vertex()) && (_v != graph_traits<GraphInterface::multigraph_t>::null_vertex()) &&
(_v < num_vertices(gi._state->_mg)); (_v < num_vertices(gi._state->_mg));
...@@ -102,6 +102,11 @@ public: ...@@ -102,6 +102,11 @@ public:
lexical_cast<string>(_v)); lexical_cast<string>(_v));
} }
python::object GetGraph() const
{
return _g();
}
GraphInterface::vertex_t GetDescriptor() const GraphInterface::vertex_t GetDescriptor() const
{ {
return _v; return _v;
...@@ -122,7 +127,7 @@ public: ...@@ -122,7 +127,7 @@ public:
size_t GetInDegree() const size_t GetInDegree() const
{ {
CheckValid(); CheckValid();
GraphInterface& gi = python::extract<GraphInterface&>(_g()); GraphInterface& gi = python::extract<GraphInterface&>(_g().attr("_Graph__graph"));
size_t in_deg; size_t in_deg;
run_action<>()(gi, bind<void>(get_degree<in_degreeS>(), run_action<>()(gi, bind<void>(get_degree<in_degreeS>(),
_1, _v, _1, _v,
...@@ -133,7 +138,7 @@ public: ...@@ -133,7 +138,7 @@ public:
size_t GetOutDegree() const size_t GetOutDegree() const
{ {
CheckValid(); CheckValid();
GraphInterface& gi = python::extract<GraphInterface&>(_g()); GraphInterface& gi = python::extract<GraphInterface&>(_g().attr("_Graph__graph"));
size_t out_deg; size_t out_deg;
run_action<>()(gi, bind<void>(get_degree<out_degreeS>(), _1, _v, run_action<>()(gi, bind<void>(get_degree<out_degreeS>(), _1, _v,
ref(out_deg)))(); ref(out_deg)))();
...@@ -161,7 +166,7 @@ public: ...@@ -161,7 +166,7 @@ public:
OutEdges() const OutEdges() const
{ {
CheckValid(); CheckValid();
GraphInterface& gi = python::extract<GraphInterface&>(_g()); GraphInterface& gi = python::extract<GraphInterface&>(_g().attr("_Graph__graph"));
python::object iter; python::object iter;
run_action<>()(gi, bind<void>(get_out_edges(), _1, run_action<>()(gi, bind<void>(get_out_edges(), _1,
ref(_g), _v, ref(iter)))(); ref(_g), _v, ref(iter)))();
...@@ -187,7 +192,7 @@ public: ...@@ -187,7 +192,7 @@ public:
InEdges() const InEdges() const
{ {
CheckValid(); CheckValid();
GraphInterface& gi = python::extract<GraphInterface&>(_g()); GraphInterface& gi = python::extract<GraphInterface&>(_g().attr("_Graph__graph"));
python::object iter; python::object iter;
run_action<>()(gi, bind<void>(get_in_edges(), _1, ref(_g), _v, run_action<>()(gi, bind<void>(get_in_edges(), _1, ref(_g), _v,
ref(iter)))(); ref(iter)))();
...@@ -208,7 +213,7 @@ public: ...@@ -208,7 +213,7 @@ public:
size_t GetIndex() const size_t GetIndex() const
{ {
CheckValid(); CheckValid();
GraphInterface& gi = python::extract<GraphInterface&>(_g()); GraphInterface& gi = python::extract<GraphInterface&>(_g().attr("_Graph__graph"));
return gi._vertex_index[_v]; return gi._vertex_index[_v];
} }
...@@ -234,8 +239,10 @@ private: ...@@ -234,8 +239,10 @@ private:
// below are classes related to the PythonEdge type // below are classes related to the PythonEdge type
class EdgeBase {}; // useful to unite all edge types
template <class Graph> template <class Graph>
class PythonEdge class PythonEdge : public EdgeBase
{ {
public: public:
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor; typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
...@@ -249,7 +256,7 @@ public: ...@@ -249,7 +256,7 @@ public:
{ {
if (_g().ptr() == Py_None) if (_g().ptr() == Py_None)
return false; return false;
GraphInterface& gi = python::extract<GraphInterface&>(_g()); GraphInterface& gi = python::extract<GraphInterface&>(_g().attr("_Graph__graph"));
GraphInterface::edge_t e(_e); GraphInterface::edge_t e(_e);
return (_valid && return (_valid &&
PythonVertex(_g, source(e, gi._state->_mg)).IsValid() && PythonVertex(_g, source(e, gi._state->_mg)).IsValid() &&
...@@ -267,6 +274,11 @@ public: ...@@ -267,6 +274,11 @@ public:
throw ValueException("invalid edge descriptor"); throw ValueException("invalid edge descriptor");
} }
python::object GetGraph() const
{
return _g();
}
GraphInterface::edge_t GetDescriptor() const GraphInterface::edge_t GetDescriptor() const
{ {
return _e; return _e;
...@@ -287,7 +299,7 @@ public: ...@@ -287,7 +299,7 @@ public:
python::object GetSource() const python::object GetSource() const
{ {
CheckValid(); CheckValid();
GraphInterface& gi = python::extract<GraphInterface&>(_g()); GraphInterface& gi = python::extract<GraphInterface&>(_g().attr("_Graph__graph"));
python::object v; python::object v;
run_action<>()(gi, bind<void>(get_source(), _1, ref(_g), ref(_e), run_action<>()(gi, bind<void>(get_source(), _1, ref(_g), ref(_e),
ref(v)))(); ref(v)))();
...@@ -309,7 +321,7 @@ public: ...@@ -309,7 +321,7 @@ public:
python::object GetTarget() const python::object GetTarget() const
{ {
CheckValid(); CheckValid();
GraphInterface& gi = python::extract<GraphInterface&>(_g()); GraphInterface& gi = python::extract<GraphInterface&>(_g().attr("_Graph__graph"));
python::object v; python::object v;
run_action<>()(gi, bind<void>(get_target(), _1, ref(_g), ref(_e), run_action<>()(gi, bind<void>(get_target(), _1, ref(_g), ref(_e),
ref(v)))(); ref(v)))();
...@@ -326,7 +338,7 @@ public: ...@@ -326,7 +338,7 @@ public:
size_t GetHash() const size_t GetHash() const
{ {
CheckValid(); CheckValid();
GraphInterface& gi = python::extract<GraphInterface&>(_g()); GraphInterface& gi = python::extract<GraphInterface&>(_g().attr("_Graph__graph"));
return hash<size_t>()(gi._edge_index[_e]); return hash<size_t>()(gi._edge_index[_e]);
} }
......
...@@ -782,7 +782,7 @@ class PropertyDict(dict): ...@@ -782,7 +782,7 @@ class PropertyDict(dict):
# The main graph interface # The main graph interface
################################################################################ ################################################################################
from libgraph_tool_core import Vertex, Edge, Vector_bool, Vector_int32_t, \ from libgraph_tool_core import Vertex, EdgeBase, Vector_bool, Vector_int32_t, \
Vector_int64_t, Vector_double, Vector_long_double, Vector_string, \ Vector_int64_t, Vector_double, Vector_long_double, Vector_string, \
new_vertex_property, new_edge_property, new_graph_property new_vertex_property, new_edge_property, new_graph_property
...@@ -934,7 +934,7 @@ class Graph(object): ...@@ -934,7 +934,7 @@ class Graph(object):
>>> assert(vlist == vlist2) >>> assert(vlist == vlist2)
""" """
return libcore.get_vertices(weakref.ref(self.__graph)) return libcore.get_vertices(weakref.ref(self))
def vertex(self, i, use_index=True): def vertex(self, i, use_index=True):
"""Return the vertex with index ``i``. If ``use_index=False``, the """Return the vertex with index ``i``. If ``use_index=False``, the
...@@ -943,7 +943,7 @@ class Graph(object): ...@@ -943,7 +943,7 @@ class Graph(object):
if use_index: if use_index:
self.stash_filter(vertex=True) self.stash_filter(vertex=True)
try: try:
v = libcore.get_vertex(weakref.ref(self.__graph), int(i)) v = libcore.get_vertex(weakref.ref(self), int(i))
finally: finally:
if use_index: if use_index:
self.pop_filter(vertex=True) self.pop_filter(vertex=True)
...@@ -983,7 +983,7 @@ class Graph(object): ...@@ -983,7 +983,7 @@ class Graph(object):
ordering. ordering.
""" """
return libcore.get_edges(weakref.ref(self.__graph)) return libcore.get_edges(weakref.ref(self))
def add_vertex(self, n=1): def add_vertex(self, n=1):
"""Add a vertex to the graph, and return it. If ``n > 1``, ``n`` """Add a vertex to the graph, and return it. If ``n > 1``, ``n``
...@@ -992,7 +992,7 @@ class Graph(object): ...@@ -992,7 +992,7 @@ class Graph(object):
vlist = [] vlist = []
vfilt = self.get_vertex_filter() vfilt = self.get_vertex_filter()
for i in xrange(n): for i in xrange(n):
v = libcore.add_vertex(weakref.ref(self.__graph)) v = libcore.add_vertex(weakref.ref(self))
if vfilt[0] is not None: if vfilt[0] is not None:
vfilt[0][v] = not vfilt[1] vfilt[0][v] = not vfilt[1]
vlist.append(v) vlist.append(v)
...@@ -1031,7 +1031,7 @@ class Graph(object): ...@@ -1031,7 +1031,7 @@ class Graph(object):
"""Add a new edge from ``source`` to ``target`` to the graph, and return """Add a new edge from ``source`` to ``target`` to the graph, and return
it.""" it."""
self.__check_perms("add_edge") self.__check_perms("add_edge")
e = libcore.add_edge(weakref.ref(self.__graph), source, target) e = libcore.add_edge(weakref.ref(self), source, target)
efilt = self.get_edge_filter() efilt = self.get_edge_filter()
if efilt[0] is not None: if efilt[0] is not None:
efilt[0][e] = not efilt[1] efilt[0][e] = not efilt[1]
...@@ -1040,7 +1040,7 @@ class Graph(object): ...@@ -1040,7 +1040,7 @@ class Graph(object):
def remove_edge(self, edge): def remove_edge(self, edge):
"""Remove an edge from the graph.""" """Remove an edge from the graph."""
self.__check_perms("del_edge") self.__check_perms("del_edge")
return libcore.remove_edge(self.__graph, edge) return libcore.remove_edge(self, edge)
def remove_edge_if(self, predicate): def remove_edge_if(self, predicate):
"""Remove all edges from the graph, for which ``predicate(e)`` evaluates """Remove all edges from the graph, for which ``predicate(e)`` evaluates
...@@ -1570,7 +1570,7 @@ def value_types(): ...@@ -1570,7 +1570,7 @@ def value_types():
# Vertex and Edge Types # Vertex and Edge Types
# ===================== # =====================
from libgraph_tool_core import Vertex, Edge from libgraph_tool_core import Vertex, Edge, EdgeBase
Vertex.__doc__ = """Vertex descriptor. Vertex.__doc__ = """Vertex descriptor.
...@@ -1644,6 +1644,7 @@ def _edge_repr(self): ...@@ -1644,6 +1644,7 @@ def _edge_repr(self):
# There are several edge classes... me must cycle through them all to modify # There are several edge classes... me must cycle through them all to modify
# them. # them.
def init_edge_classes(): def init_edge_classes():
for directed in [True, False]: for directed in [True, False]:
for e_reversed in [True, False]: for e_reversed in [True, False]:
...@@ -1668,9 +1669,17 @@ def init_edge_classes(): ...@@ -1668,9 +1669,17 @@ def init_edge_classes():
init_edge_classes() init_edge_classes()
# Add convenience function to vector classes # some shenanigans to make it seem there is only a single edge class
EdgeBase.__doc__ = Edge.__doc__
EdgeBase.source = Edge.source
EdgeBase.target = Edge.target
EdgeBase.is_valid = Edge.is_valid
EdgeBase.get_graph = Edge.get_graph
Edge = EdgeBase
Edge.__name__ = "Edge"
# Add convenience function to vector classes
def _get_array_view(self): def _get_array_view(self):
return self.get_array()[:] return self.get_array()[:]
......
...@@ -321,7 +321,7 @@ def bfs_search(g, source, visitor=BFSVisitor()): ...@@ -321,7 +321,7 @@ def bfs_search(g, source, visitor=BFSVisitor()):
try: try:
libgraph_tool_search.bfs_search(g._Graph__graph, libgraph_tool_search.bfs_search(g._Graph__graph,
weakref.ref(g._Graph__graph), weakref.ref(g),
int(source), visitor) int(source), visitor)
except StopSearch: except StopSearch:
pass pass
...@@ -556,7 +556,7 @@ def dfs_search(g, source, visitor=DFSVisitor()): ...@@ -556,7 +556,7 @@ def dfs_search(g, source, visitor=DFSVisitor()):
try: try:
libgraph_tool_search.dfs_search(g._Graph__graph, libgraph_tool_search.dfs_search(g._Graph__graph,
weakref.ref(g._Graph__graph), weakref.ref(g),
int(source), visitor) int(source), visitor)
except StopSearch: except StopSearch:
pass pass
...@@ -832,7 +832,7 @@ def dijkstra_search(g, source, weight, visitor=DijkstraVisitor(), dist_map=None, ...@@ -832,7 +832,7 @@ def dijkstra_search(g, source, weight, visitor=DijkstraVisitor(), dist_map=None,
try: try:
libgraph_tool_search.dijkstra_search(g._Graph__graph, libgraph_tool_search.dijkstra_search(g._Graph__graph,
weakref.ref(g._Graph__graph), weakref.ref(g),
int(source), int(source),
_prop("v", g, dist_map), _prop("v", g, dist_map),
_prop("v", g, pred_map), _prop("v", g, pred_map),
...@@ -1078,7 +1078,7 @@ def bellman_ford_search(g, source, weight, visitor=BellmanFordVisitor(), ...@@ -1078,7 +1078,7 @@ def bellman_ford_search(g, source, weight, visitor=BellmanFordVisitor(),
try: try:
minimized = \ minimized = \
libgraph_tool_search.bellman_ford_search(g._Graph__graph, libgraph_tool_search.bellman_ford_search(g._Graph__graph,
weakref.ref(g._Graph__graph), weakref.ref(g),
int(source), int(source),
_prop("v", g, dist_map), _prop("v", g, dist_map),
_prop("v", g, pred_map), _prop("v", g, pred_map),
...@@ -1508,7 +1508,7 @@ def astar_search(g, source, weight, visitor=AStarVisitor(), ...@@ -1508,7 +1508,7 @@ def astar_search(g, source, weight, visitor=AStarVisitor(),
"add_edge": False}) "add_edge": False})
libgraph_tool_search.astar_search(g._Graph__graph, libgraph_tool_search.astar_search(g._Graph__graph,
weakref.ref(g._Graph__graph), weakref.ref(g),
int(source), _prop("v", g, dist_map), int(source), _prop("v", g, dist_map),
_prop("v", g, pred_map), _prop("v", g, pred_map),
_prop("e", g, weight), visitor, _prop("e", g, weight), visitor,
...@@ -1522,7 +1522,7 @@ def astar_search(g, source, weight, visitor=AStarVisitor(), ...@@ -1522,7 +1522,7 @@ def astar_search(g, source, weight, visitor=AStarVisitor(),
" dist_map.") " dist_map.")
g._Graph__perms.update({"del_vertex": False}) g._Graph__perms.update({"del_vertex": False})
libgraph_tool_search.astar_search_implicit\ libgraph_tool_search.astar_search_implicit\
(g._Graph__graph, weakref.ref(g._Graph__graph), int(source), (g._Graph__graph, weakref.ref(g), int(source),
_prop("v", g, dist_map), _prop("v", g, pred_map), _prop("v", g, dist_map), _prop("v", g, pred_map),
_prop("v", g, cost_map), _prop("e", g, weight), visitor, _prop("v", g, cost_map), _prop("e", g, weight), visitor,
compare, combine, zero, infinity, h) compare, combine, zero, infinity, h)
......
...@@ -53,7 +53,7 @@ def find_vertex(g, prop, match): ...@@ -53,7 +53,7 @@ def find_vertex(g, prop, match):
"out" or "total", representing a degree type.""" "out" or "total", representing a degree type."""
val = _convert(prop, match) val = _convert(prop, match)
ret = libgraph_tool_util.\ ret = libgraph_tool_util.\
find_vertex_range(weakref.ref(g._Graph__graph), _degree(g, prop), find_vertex_range(weakref.ref(g), _degree(g, prop),
(val, val)) (val, val))
return ret return ret
...@@ -63,7 +63,7 @@ def find_vertex_range(g, prop, range): ...@@ -63,7 +63,7 @@ def find_vertex_range(g, prop, range):
parameter prop can be either a :class:`~graph_tool.PropertyMap` or string parameter prop can be either a :class:`~graph_tool.PropertyMap` or string
with value"in", "out" or "total", representing a degree type.""" with value"in", "out" or "total", representing a degree type."""
ret = libgraph_tool_util.\ ret = libgraph_tool_util.\
find_vertex_range(weakref.ref(g._Graph__graph), _degree(g, prop), find_vertex_range(weakref.ref(g), _degree(g, prop),
(_convert(prop, range[0]), _convert(prop, range[1]))) (_convert(prop, range[0]), _convert(prop, range[1])))
return ret return ret
...@@ -73,7 +73,7 @@ def find_edge(g, prop, match): ...@@ -73,7 +73,7 @@ def find_edge(g, prop, match):
must be a :class:`~graph_tool.PropertyMap`.""" must be a :class:`~graph_tool.PropertyMap`."""
val = _convert(prop, match) val = _convert(prop, match)
ret = libgraph_tool_util.\ ret = libgraph_tool_util.\
find_edge_range(weakref.ref(g._Graph__graph), _prop("e", g, prop), find_edge_range(weakref.ref(g), _prop("e", g, prop),
(val, val)) (val, val))
return ret return ret
...@@ -82,6 +82,6 @@ def find_edge_range(g, prop, range): ...@@ -82,6 +82,6 @@ def find_edge_range(g, prop, range):
"""Find all vertices `e` for which `range[0] <= prop[e] <= range[1]`. The """Find all vertices `e` for which `range[0] <= prop[e] <= range[1]`. The
parameter prop can be either a :class:`~graph_tool.PropertyMap`.""" parameter prop can be either a :class:`~graph_tool.PropertyMap`."""
ret = libgraph_tool_util.\ ret = libgraph_tool_util.\
find_edge_range(weakref.ref(g._Graph__graph), _prop("e", g, prop), find_edge_range(weakref.ref(g), _prop("e", g, prop),
(_convert(prop, range[0]), _convert(prop, range[1]))) (_convert(prop, range[0]), _convert(prop, range[1])))
return ret return ret
Markdown is supported
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