Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check if nodes exist on add_edge methods #862

Merged
merged 18 commits into from
May 12, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
fixes:
- |
:meth:`rustworkx.PyGraph.add_edge` and :meth:`rustworkx.PyDiGraph.add_edge` and now raises an
`IndexError` when one of the nodes does not exist in the graph. Previously, it caused the Python
IvanIsCoding marked this conversation as resolved.
Show resolved Hide resolved
interpreter to exit with a `PanicException`
IvanIsCoding marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 1 addition & 1 deletion src/connectivity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ pub fn graph_complement(py: Python, graph: &graph::PyGraph) -> PyResult<graph::P
|| !complement_graph.has_edge(node_a.index(), node_b.index()))
{
// avoid creating parallel edges in multigraph
complement_graph.add_edge(node_a.index(), node_b.index(), py.None());
complement_graph.graph.add_edge(node_a, node_b, py.None());
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/digraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,11 @@ impl PyDiGraph {
pub fn add_edge(&mut self, parent: usize, child: usize, edge: PyObject) -> PyResult<usize> {
let p_index = NodeIndex::new(parent);
let c_index = NodeIndex::new(child);
if !self.graph.contains_node(p_index) || !self.graph.contains_node(c_index) {
IvanIsCoding marked this conversation as resolved.
Show resolved Hide resolved
return Err(PyIndexError::new_err(
"One of the endpoints of the edge does not exist in graph",
));
}
let out_index = self._add_edge(p_index, c_index, edge)?;
Ok(out_index)
}
Expand Down
11 changes: 8 additions & 3 deletions src/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -748,10 +748,15 @@ impl PyGraph {
/// of an existing edge with ``multigraph=False``) edge.
/// :rtype: int
#[pyo3(text_signature = "(self, node_a, node_b, edge, /)")]
pub fn add_edge(&mut self, node_a: usize, node_b: usize, edge: PyObject) -> usize {
pub fn add_edge(&mut self, node_a: usize, node_b: usize, edge: PyObject) -> PyResult<usize> {
let p_index = NodeIndex::new(node_a);
let c_index = NodeIndex::new(node_b);
self._add_edge(p_index, c_index, edge)
if !self.graph.contains_node(p_index) || !self.graph.contains_node(c_index) {
return Err(PyIndexError::new_err(
"One of the endpoints of the edge does not exist in graph",
));
}
Ok(self._add_edge(p_index, c_index, edge))
}

/// Add new edges to the graph.
Expand Down Expand Up @@ -1604,7 +1609,7 @@ impl PyGraph {
}

for (source, weight) in edges {
self.add_edge(source.index(), node_index.index(), weight);
self.add_edge(source.index(), node_index.index(), weight)?;
}

Ok(node_index.index())
Expand Down
2 changes: 1 addition & 1 deletion src/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ pub fn minimum_spanning_tree(
.edges
.iter()
{
spanning_tree.add_edge(edge.0, edge.1, edge.2.clone_ref(py));
spanning_tree.add_edge(edge.0, edge.1, edge.2.clone_ref(py))?;
}

Ok(spanning_tree)
Expand Down
5 changes: 5 additions & 0 deletions tests/rustworkx_tests/digraph/test_edges.py
Original file line number Diff line number Diff line change
Expand Up @@ -962,3 +962,8 @@ def test_extend_from_weighted_edge_list(self):
graph.extend_from_weighted_edge_list(edge_list)
self.assertEqual(len(graph), 4)
self.assertEqual(["a", "b", "c", "d", "e"], graph.edges())

def test_add_edge_non_existent(self):
g = rustworkx.PyDiGraph()
with self.assertRaises(IndexError):
g.add_edge(2, 3, None)
5 changes: 5 additions & 0 deletions tests/rustworkx_tests/graph/test_edges.py
Original file line number Diff line number Diff line change
Expand Up @@ -817,3 +817,8 @@ def test_extend_from_weighted_edge_list(self):
graph.extend_from_weighted_edge_list(edge_list)
self.assertEqual(len(graph), 4)
self.assertEqual(["a", "b", "c", "d", "e"], graph.edges())

def test_add_edge_non_existent(self):
g = rustworkx.PyGraph()
with self.assertRaises(IndexError):
g.add_edge(2, 3, None)