Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
17 changes: 12 additions & 5 deletions arc/molecule/graph.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -218,18 +218,25 @@ cdef class Graph(object):

cpdef list get_all_edges(self):
"""
Returns a list of all edges in the graph.
Returns a list of all edges in the graph, each edge appearing once,
ordered by the graph's vertex order and, within a vertex, by the order
in which its edges were added. The order does not depend on the hash
values of the edges, so it is identical in every process.
"""
cdef set edge_set
cdef list edges
cdef set seen
cdef Vertex vertex
cdef Edge edge

edge_set = set()
edges = []
seen = set()
for vertex in self.vertices:
for edge in vertex.edges.values():
edge_set.add(edge)
if id(edge) not in seen:
seen.add(id(edge))
edges.append(edge)

return list(edge_set)
return edges

cpdef dict get_edges(self, Vertex vertex):
"""
Expand Down
35 changes: 35 additions & 0 deletions arc/molecule/graph_test.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#!/usr/bin/env python3
# encoding: utf-8

import os
import subprocess
import sys
import unittest

import arc
from arc.molecule.graph import Edge, Graph, Vertex


Expand Down Expand Up @@ -108,6 +112,37 @@ def test_get_all_edges(self):
self.assertIsInstance(edges, list)
self.assertEqual(len(edges), 5)

def test_get_all_edges_orders_the_edges_by_vertex(self):
"""
Test that Graph.get_all_edges() returns the edges in vertex order, each edge once.
"""
expected = []
for vertex in self.graph.vertices:
for edge in vertex.edges.values():
if not any(edge is seen for seen in expected):
expected.append(edge)
self.assertEqual(self.graph.get_all_edges(), expected)

def test_get_all_edges_order_does_not_depend_on_the_hash_seed(self):
"""
Test that Graph.get_all_edges() returns the same order in processes with different hash seeds.
"""
script = ('from arc.molecule.molecule import Molecule\n'
'mol = Molecule(smiles="c1ccccc1Cc1ccccc1")\n'
'atoms = mol.atoms\n'
'print([(atoms.index(edge.vertex1), atoms.index(edge.vertex2)) '
'for edge in mol.get_all_edges()])\n')
orders = list()
for seed in ('1', '35'):
arc_root = os.path.dirname(os.path.dirname(os.path.abspath(arc.__file__)))
environment = dict(os.environ, PYTHONHASHSEED=seed, PYTHONPATH=arc_root)
result = subprocess.run([sys.executable, '-c', script], capture_output=True, text=True,
env=environment, timeout=300)
self.assertEqual(result.returncode, 0, f'Subprocess failed: {result.stderr}')
orders.append(result.stdout.strip())
self.assertTrue(orders[0])
self.assertEqual(orders[0], orders[1])

def test_has_vertex(self):
"""
Test the Graph.has_vertex() method.
Expand Down
Loading