Skip to content

Commit

Permalink
Merge branch 'feature-undirected-kw'
Browse files Browse the repository at this point in the history
  • Loading branch information
maxfischer2781 committed Jul 27, 2018
2 parents fed570e + c1b2c40 commit cd0d6c6
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 15 deletions.
3 changes: 3 additions & 0 deletions graphi/types/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# pull in submodules in correct order to avoid import cycle
from . import undirected as _undirected
from . import adjacency_graph as _adjacency_graph
4 changes: 4 additions & 0 deletions graphi/types/adjacency_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
from .. import edge


from .undirected import undirectable


@undirectable
class AdjacencyGraph(abc.Graph):
r"""
Graph storing edge distances via adjacency lists
Expand Down
23 changes: 23 additions & 0 deletions graphi/types/undirected.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,29 @@
from .. import edge


def undirectable(graph_class):
"""Make an implementation of :py:class:`abc.Graph` undirectable by passing ``undirected=True`` to it"""
assert issubclass(graph_class, abc.Graph), 'only subclasses of Graph can be undirected'

@staticmethod
def __new_graph__(cls, *args, **kwargs):
undirected = kwargs.pop('undirected', False)
super_new = super(graph_class, cls).__new__
if super_new is object.__new__:
self = super_new(cls)
else:
self = super_new(cls, *args, **kwargs)
if undirected: # replicates type.__call__
if isinstance(self, cls):
self.__init__(*args, **kwargs)
return Undirected(self)
else:
return self

graph_class.__new__ = __new_graph__
return graph_class


from .adjacency_graph import AdjacencyGraph


Expand Down
29 changes: 14 additions & 15 deletions graphi_unittests/types_unittests/test_adjacency_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import graphi.types.adjacency_graph
import graphi.abc
from graphi import operators
from graphi.types.undirected import Undirected

from . import _graph_interface_mixins as mixins

Expand Down Expand Up @@ -52,16 +51,16 @@ def make_content_samples(self, lengths=range(5, 101, 20), connections=None, dist

def test_init_undirected(self):
with self.assertRaises(ValueError):
Undirected(self.graph_cls({
self.graph_cls({
1: {2: 1, 3: 1},
2: {1: 1},
3: {1: 2}
}))
}, undirected=True)

graph = Undirected(self.graph_cls({
graph = self.graph_cls({
1: {2: 1, 3: 1},
2: {1: 1}
}))
}, undirected=True)
self.assertEquals(graph[1:3], graph[3:1])

def test_containment(self):
Expand Down Expand Up @@ -94,7 +93,7 @@ def test_containment(self):

def test_set(self):
"""Adjacency Graph: change/add elements"""
graph = Undirected(self.graph_cls({
graph = self.graph_cls({
1: {2: 1, 3: 1, 4: 1, 5: 1, 6: 2, 8: 1},
2: {1: 1},
3: {1: 1},
Expand All @@ -103,7 +102,7 @@ def test_set(self):
6: {1: 2, 7: 1},
7: {6: 1},
8: {1: 1}
}))
}, undirected=True)
self.assertFalse(slice(1, 7) in graph)
graph[1:7] = 2
self.assertEqual(2, graph[1:7])
Expand Down Expand Up @@ -183,12 +182,12 @@ def test_deletion(self):
graph[8:1]

def test_deletion_undirected(self):
graph = Undirected(self.graph_cls({
graph = self.graph_cls({
1: {2: 1, 3: 1, 4: 1},
2: {1: 1},
3: {1: 1},
4: {1: 1}
}))
}, undirected=True)
del graph[1:2]
with self.assertRaises(graphi.abc.EdgeError):
graph[1:2]
Expand Down Expand Up @@ -217,23 +216,23 @@ def test_neighbours(self):
operators.neighbours(graph, 9)

def test_update(self):
graph = Undirected(self.graph_cls({
graph = self.graph_cls({
1: {2: 1, 3: 1, 4: 1},
2: {1: 1},
3: {1: 1},
4: {1: 1}
}))
}, undirected=True)
graph.update((5, 6))
self.assertIn(5, graph)
self.assertIn(6, graph)

def test_clear_undirected(self):
graph = Undirected(self.graph_cls({
graph = self.graph_cls({
1: {2: 1, 3: 1, 4: 1},
2: {1: 1},
3: {1: 1},
4: {1: 1}
}))
}, undirected=True)
self.assertEquals(len(graph), 4)
graph.clear()
self.assertEquals(len(graph), 0)
Expand All @@ -250,7 +249,7 @@ def test_clear_directed(self):
self.assertEquals(len(graph), 0)

def test_edge_view_undirected(self):
graph = Undirected(self.graph_cls({1, 2, 3, 4}))
graph = self.graph_cls({1, 2, 3, 4}, undirected=True)
nodes = [2, 3, 4]
for node in nodes:
graph[1:node] = 1
Expand Down Expand Up @@ -294,7 +293,7 @@ def test_edge_view_directed(self):
None in edge_view

def test_value_view_undirected(self):
graph = Undirected(self.graph_cls({1, 2, 3, 4}))
graph = self.graph_cls({1, 2, 3, 4}, undirected=True)
nodes = [2, 3, 4]
for value, node in enumerate(nodes):
graph[1:node] = value
Expand Down

0 comments on commit cd0d6c6

Please sign in to comment.