Fixed database typo and removed unnecessary class identifier.

This commit is contained in:
Batuhan Berk Başoğlu 2020-10-14 10:10:37 -04:00
parent 00ad49a143
commit 45fb349a7d
5098 changed files with 952558 additions and 85 deletions

View file

@ -0,0 +1,266 @@
"""
Unit tests for adjlist.
"""
import io
import pytest
import os
import tempfile
import networkx as nx
from networkx.testing import assert_nodes_equal, assert_edges_equal, assert_graphs_equal
class TestAdjlist:
@classmethod
def setup_class(cls):
cls.G = nx.Graph(name="test")
e = [("a", "b"), ("b", "c"), ("c", "d"), ("d", "e"), ("e", "f"), ("a", "f")]
cls.G.add_edges_from(e)
cls.G.add_node("g")
cls.DG = nx.DiGraph(cls.G)
cls.XG = nx.MultiGraph()
cls.XG.add_weighted_edges_from([(1, 2, 5), (1, 2, 5), (1, 2, 1), (3, 3, 42)])
cls.XDG = nx.MultiDiGraph(cls.XG)
def test_read_multiline_adjlist_1(self):
# Unit test for https://networkx.lanl.gov/trac/ticket/252
s = b"""# comment line
1 2
# comment line
2
3
"""
bytesIO = io.BytesIO(s)
G = nx.read_multiline_adjlist(bytesIO)
adj = {"1": {"3": {}, "2": {}}, "3": {"1": {}}, "2": {"1": {}}}
assert_graphs_equal(G, nx.Graph(adj))
def test_unicode(self):
G = nx.Graph()
name1 = chr(2344) + chr(123) + chr(6543)
name2 = chr(5543) + chr(1543) + chr(324)
G.add_edge(name1, "Radiohead", **{name2: 3})
fd, fname = tempfile.mkstemp()
nx.write_multiline_adjlist(G, fname)
H = nx.read_multiline_adjlist(fname)
assert_graphs_equal(G, H)
os.close(fd)
os.unlink(fname)
def test_latin1_err(self):
G = nx.Graph()
name1 = chr(2344) + chr(123) + chr(6543)
name2 = chr(5543) + chr(1543) + chr(324)
G.add_edge(name1, "Radiohead", **{name2: 3})
fd, fname = tempfile.mkstemp()
pytest.raises(
UnicodeEncodeError, nx.write_multiline_adjlist, G, fname, encoding="latin-1"
)
os.close(fd)
os.unlink(fname)
def test_latin1(self):
G = nx.Graph()
name1 = "Bj" + chr(246) + "rk"
name2 = chr(220) + "ber"
G.add_edge(name1, "Radiohead", **{name2: 3})
fd, fname = tempfile.mkstemp()
nx.write_multiline_adjlist(G, fname, encoding="latin-1")
H = nx.read_multiline_adjlist(fname, encoding="latin-1")
assert_graphs_equal(G, H)
os.close(fd)
os.unlink(fname)
def test_parse_adjlist(self):
lines = ["1 2 5", "2 3 4", "3 5", "4", "5"]
nx.parse_adjlist(lines, nodetype=int) # smoke test
with pytest.raises(TypeError):
nx.parse_adjlist(lines, nodetype="int")
lines = ["1 2 5", "2 b", "c"]
with pytest.raises(TypeError):
nx.parse_adjlist(lines, nodetype=int)
def test_adjlist_graph(self):
G = self.G
(fd, fname) = tempfile.mkstemp()
nx.write_adjlist(G, fname)
H = nx.read_adjlist(fname)
H2 = nx.read_adjlist(fname)
assert H != H2 # they should be different graphs
assert_nodes_equal(list(H), list(G))
assert_edges_equal(list(H.edges()), list(G.edges()))
os.close(fd)
os.unlink(fname)
def test_adjlist_digraph(self):
G = self.DG
(fd, fname) = tempfile.mkstemp()
nx.write_adjlist(G, fname)
H = nx.read_adjlist(fname, create_using=nx.DiGraph())
H2 = nx.read_adjlist(fname, create_using=nx.DiGraph())
assert H != H2 # they should be different graphs
assert_nodes_equal(list(H), list(G))
assert_edges_equal(list(H.edges()), list(G.edges()))
os.close(fd)
os.unlink(fname)
def test_adjlist_integers(self):
(fd, fname) = tempfile.mkstemp()
G = nx.convert_node_labels_to_integers(self.G)
nx.write_adjlist(G, fname)
H = nx.read_adjlist(fname, nodetype=int)
H2 = nx.read_adjlist(fname, nodetype=int)
assert H != H2 # they should be different graphs
assert_nodes_equal(list(H), list(G))
assert_edges_equal(list(H.edges()), list(G.edges()))
os.close(fd)
os.unlink(fname)
def test_adjlist_multigraph(self):
G = self.XG
(fd, fname) = tempfile.mkstemp()
nx.write_adjlist(G, fname)
H = nx.read_adjlist(fname, nodetype=int, create_using=nx.MultiGraph())
H2 = nx.read_adjlist(fname, nodetype=int, create_using=nx.MultiGraph())
assert H != H2 # they should be different graphs
assert_nodes_equal(list(H), list(G))
assert_edges_equal(list(H.edges()), list(G.edges()))
os.close(fd)
os.unlink(fname)
def test_adjlist_multidigraph(self):
G = self.XDG
(fd, fname) = tempfile.mkstemp()
nx.write_adjlist(G, fname)
H = nx.read_adjlist(fname, nodetype=int, create_using=nx.MultiDiGraph())
H2 = nx.read_adjlist(fname, nodetype=int, create_using=nx.MultiDiGraph())
assert H != H2 # they should be different graphs
assert_nodes_equal(list(H), list(G))
assert_edges_equal(list(H.edges()), list(G.edges()))
os.close(fd)
os.unlink(fname)
def test_adjlist_delimiter(self):
fh = io.BytesIO()
G = nx.path_graph(3)
nx.write_adjlist(G, fh, delimiter=":")
fh.seek(0)
H = nx.read_adjlist(fh, nodetype=int, delimiter=":")
assert_nodes_equal(list(H), list(G))
assert_edges_equal(list(H.edges()), list(G.edges()))
class TestMultilineAdjlist:
@classmethod
def setup_class(cls):
cls.G = nx.Graph(name="test")
e = [("a", "b"), ("b", "c"), ("c", "d"), ("d", "e"), ("e", "f"), ("a", "f")]
cls.G.add_edges_from(e)
cls.G.add_node("g")
cls.DG = nx.DiGraph(cls.G)
cls.DG.remove_edge("b", "a")
cls.DG.remove_edge("b", "c")
cls.XG = nx.MultiGraph()
cls.XG.add_weighted_edges_from([(1, 2, 5), (1, 2, 5), (1, 2, 1), (3, 3, 42)])
cls.XDG = nx.MultiDiGraph(cls.XG)
def test_parse_multiline_adjlist(self):
lines = [
"1 2",
"b {'weight':3, 'name': 'Frodo'}",
"c {}",
"d 1",
"e {'weight':6, 'name': 'Saruman'}",
]
nx.parse_multiline_adjlist(iter(lines)) # smoke test
with pytest.raises(TypeError):
nx.parse_multiline_adjlist(iter(lines), nodetype=int)
nx.parse_multiline_adjlist(iter(lines), edgetype=str) # smoke test
with pytest.raises(TypeError):
nx.parse_multiline_adjlist(iter(lines), nodetype=int)
lines = ["1 a"]
with pytest.raises(TypeError):
nx.parse_multiline_adjlist(iter(lines))
lines = ["a 2"]
with pytest.raises(TypeError):
nx.parse_multiline_adjlist(iter(lines), nodetype=int)
lines = ["1 2"]
with pytest.raises(TypeError):
nx.parse_multiline_adjlist(iter(lines))
lines = ["1 2", "2 {}"]
with pytest.raises(TypeError):
nx.parse_multiline_adjlist(iter(lines))
def test_multiline_adjlist_graph(self):
G = self.G
(fd, fname) = tempfile.mkstemp()
nx.write_multiline_adjlist(G, fname)
H = nx.read_multiline_adjlist(fname)
H2 = nx.read_multiline_adjlist(fname)
assert H != H2 # they should be different graphs
assert_nodes_equal(list(H), list(G))
assert_edges_equal(list(H.edges()), list(G.edges()))
os.close(fd)
os.unlink(fname)
def test_multiline_adjlist_digraph(self):
G = self.DG
(fd, fname) = tempfile.mkstemp()
nx.write_multiline_adjlist(G, fname)
H = nx.read_multiline_adjlist(fname, create_using=nx.DiGraph())
H2 = nx.read_multiline_adjlist(fname, create_using=nx.DiGraph())
assert H != H2 # they should be different graphs
assert_nodes_equal(list(H), list(G))
assert_edges_equal(list(H.edges()), list(G.edges()))
os.close(fd)
os.unlink(fname)
def test_multiline_adjlist_integers(self):
(fd, fname) = tempfile.mkstemp()
G = nx.convert_node_labels_to_integers(self.G)
nx.write_multiline_adjlist(G, fname)
H = nx.read_multiline_adjlist(fname, nodetype=int)
H2 = nx.read_multiline_adjlist(fname, nodetype=int)
assert H != H2 # they should be different graphs
assert_nodes_equal(list(H), list(G))
assert_edges_equal(list(H.edges()), list(G.edges()))
os.close(fd)
os.unlink(fname)
def test_multiline_adjlist_multigraph(self):
G = self.XG
(fd, fname) = tempfile.mkstemp()
nx.write_multiline_adjlist(G, fname)
H = nx.read_multiline_adjlist(fname, nodetype=int, create_using=nx.MultiGraph())
H2 = nx.read_multiline_adjlist(
fname, nodetype=int, create_using=nx.MultiGraph()
)
assert H != H2 # they should be different graphs
assert_nodes_equal(list(H), list(G))
assert_edges_equal(list(H.edges()), list(G.edges()))
os.close(fd)
os.unlink(fname)
def test_multiline_adjlist_multidigraph(self):
G = self.XDG
(fd, fname) = tempfile.mkstemp()
nx.write_multiline_adjlist(G, fname)
H = nx.read_multiline_adjlist(
fname, nodetype=int, create_using=nx.MultiDiGraph()
)
H2 = nx.read_multiline_adjlist(
fname, nodetype=int, create_using=nx.MultiDiGraph()
)
assert H != H2 # they should be different graphs
assert_nodes_equal(list(H), list(G))
assert_edges_equal(list(H.edges()), list(G.edges()))
os.close(fd)
os.unlink(fname)
def test_multiline_adjlist_delimiter(self):
fh = io.BytesIO()
G = nx.path_graph(3)
nx.write_multiline_adjlist(G, fh, delimiter=":")
fh.seek(0)
H = nx.read_multiline_adjlist(fh, nodetype=int, delimiter=":")
assert_nodes_equal(list(H), list(G))
assert_edges_equal(list(H.edges()), list(G.edges()))

View file

@ -0,0 +1,275 @@
"""
Unit tests for edgelists.
"""
import pytest
import io
import tempfile
import os
import networkx as nx
from networkx.testing import assert_edges_equal, assert_nodes_equal, assert_graphs_equal
class TestEdgelist:
@classmethod
def setup_class(cls):
cls.G = nx.Graph(name="test")
e = [("a", "b"), ("b", "c"), ("c", "d"), ("d", "e"), ("e", "f"), ("a", "f")]
cls.G.add_edges_from(e)
cls.G.add_node("g")
cls.DG = nx.DiGraph(cls.G)
cls.XG = nx.MultiGraph()
cls.XG.add_weighted_edges_from([(1, 2, 5), (1, 2, 5), (1, 2, 1), (3, 3, 42)])
cls.XDG = nx.MultiDiGraph(cls.XG)
def test_read_edgelist_1(self):
s = b"""\
# comment line
1 2
# comment line
2 3
"""
bytesIO = io.BytesIO(s)
G = nx.read_edgelist(bytesIO, nodetype=int)
assert_edges_equal(G.edges(), [(1, 2), (2, 3)])
def test_read_edgelist_2(self):
s = b"""\
# comment line
1 2 2.0
# comment line
2 3 3.0
"""
bytesIO = io.BytesIO(s)
G = nx.read_edgelist(bytesIO, nodetype=int, data=False)
assert_edges_equal(G.edges(), [(1, 2), (2, 3)])
bytesIO = io.BytesIO(s)
G = nx.read_weighted_edgelist(bytesIO, nodetype=int)
assert_edges_equal(
G.edges(data=True), [(1, 2, {"weight": 2.0}), (2, 3, {"weight": 3.0})]
)
def test_read_edgelist_3(self):
s = b"""\
# comment line
1 2 {'weight':2.0}
# comment line
2 3 {'weight':3.0}
"""
bytesIO = io.BytesIO(s)
G = nx.read_edgelist(bytesIO, nodetype=int, data=False)
assert_edges_equal(G.edges(), [(1, 2), (2, 3)])
bytesIO = io.BytesIO(s)
G = nx.read_edgelist(bytesIO, nodetype=int, data=True)
assert_edges_equal(
G.edges(data=True), [(1, 2, {"weight": 2.0}), (2, 3, {"weight": 3.0})]
)
def test_read_edgelist_4(self):
s = b"""\
# comment line
1 2 {'weight':2.0}
# comment line
2 3 {'weight':3.0}
"""
bytesIO = io.BytesIO(s)
G = nx.read_edgelist(bytesIO, nodetype=int, data=False)
assert_edges_equal(G.edges(), [(1, 2), (2, 3)])
bytesIO = io.BytesIO(s)
G = nx.read_edgelist(bytesIO, nodetype=int, data=True)
assert_edges_equal(
G.edges(data=True), [(1, 2, {"weight": 2.0}), (2, 3, {"weight": 3.0})]
)
s = """\
# comment line
1 2 {'weight':2.0}
# comment line
2 3 {'weight':3.0}
"""
StringIO = io.StringIO(s)
G = nx.read_edgelist(StringIO, nodetype=int, data=False)
assert_edges_equal(G.edges(), [(1, 2), (2, 3)])
StringIO = io.StringIO(s)
G = nx.read_edgelist(StringIO, nodetype=int, data=True)
assert_edges_equal(
G.edges(data=True), [(1, 2, {"weight": 2.0}), (2, 3, {"weight": 3.0})]
)
def test_read_edgelist_5(self):
s = b"""\
# comment line
1 2 {'weight':2.0, 'color':'green'}
# comment line
2 3 {'weight':3.0, 'color':'red'}
"""
bytesIO = io.BytesIO(s)
G = nx.read_edgelist(bytesIO, nodetype=int, data=False)
assert_edges_equal(G.edges(), [(1, 2), (2, 3)])
bytesIO = io.BytesIO(s)
G = nx.read_edgelist(bytesIO, nodetype=int, data=True)
assert_edges_equal(
G.edges(data=True),
[
(1, 2, {"weight": 2.0, "color": "green"}),
(2, 3, {"weight": 3.0, "color": "red"}),
],
)
def test_read_edgelist_6(self):
s = b"""\
# comment line
1, 2, {'weight':2.0, 'color':'green'}
# comment line
2, 3, {'weight':3.0, 'color':'red'}
"""
bytesIO = io.BytesIO(s)
G = nx.read_edgelist(bytesIO, nodetype=int, data=False, delimiter=",")
assert_edges_equal(G.edges(), [(1, 2), (2, 3)])
bytesIO = io.BytesIO(s)
G = nx.read_edgelist(bytesIO, nodetype=int, data=True, delimiter=",")
assert_edges_equal(
G.edges(data=True),
[
(1, 2, {"weight": 2.0, "color": "green"}),
(2, 3, {"weight": 3.0, "color": "red"}),
],
)
def test_write_edgelist_1(self):
fh = io.BytesIO()
G = nx.OrderedGraph()
G.add_edges_from([(1, 2), (2, 3)])
nx.write_edgelist(G, fh, data=False)
fh.seek(0)
assert fh.read() == b"1 2\n2 3\n"
def test_write_edgelist_2(self):
fh = io.BytesIO()
G = nx.OrderedGraph()
G.add_edges_from([(1, 2), (2, 3)])
nx.write_edgelist(G, fh, data=True)
fh.seek(0)
assert fh.read() == b"1 2 {}\n2 3 {}\n"
def test_write_edgelist_3(self):
fh = io.BytesIO()
G = nx.OrderedGraph()
G.add_edge(1, 2, weight=2.0)
G.add_edge(2, 3, weight=3.0)
nx.write_edgelist(G, fh, data=True)
fh.seek(0)
assert fh.read() == b"1 2 {'weight': 2.0}\n2 3 {'weight': 3.0}\n"
def test_write_edgelist_4(self):
fh = io.BytesIO()
G = nx.OrderedGraph()
G.add_edge(1, 2, weight=2.0)
G.add_edge(2, 3, weight=3.0)
nx.write_edgelist(G, fh, data=[("weight")])
fh.seek(0)
assert fh.read() == b"1 2 2.0\n2 3 3.0\n"
def test_unicode(self):
G = nx.Graph()
name1 = chr(2344) + chr(123) + chr(6543)
name2 = chr(5543) + chr(1543) + chr(324)
G.add_edge(name1, "Radiohead", **{name2: 3})
fd, fname = tempfile.mkstemp()
nx.write_edgelist(G, fname)
H = nx.read_edgelist(fname)
assert_graphs_equal(G, H)
os.close(fd)
os.unlink(fname)
def test_latin1_issue(self):
G = nx.Graph()
name1 = chr(2344) + chr(123) + chr(6543)
name2 = chr(5543) + chr(1543) + chr(324)
G.add_edge(name1, "Radiohead", **{name2: 3})
fd, fname = tempfile.mkstemp()
pytest.raises(
UnicodeEncodeError, nx.write_edgelist, G, fname, encoding="latin-1"
)
os.close(fd)
os.unlink(fname)
def test_latin1(self):
G = nx.Graph()
name1 = "Bj" + chr(246) + "rk"
name2 = chr(220) + "ber"
G.add_edge(name1, "Radiohead", **{name2: 3})
fd, fname = tempfile.mkstemp()
nx.write_edgelist(G, fname, encoding="latin-1")
H = nx.read_edgelist(fname, encoding="latin-1")
assert_graphs_equal(G, H)
os.close(fd)
os.unlink(fname)
def test_edgelist_graph(self):
G = self.G
(fd, fname) = tempfile.mkstemp()
nx.write_edgelist(G, fname)
H = nx.read_edgelist(fname)
H2 = nx.read_edgelist(fname)
assert H != H2 # they should be different graphs
G.remove_node("g") # isolated nodes are not written in edgelist
assert_nodes_equal(list(H), list(G))
assert_edges_equal(list(H.edges()), list(G.edges()))
os.close(fd)
os.unlink(fname)
def test_edgelist_digraph(self):
G = self.DG
(fd, fname) = tempfile.mkstemp()
nx.write_edgelist(G, fname)
H = nx.read_edgelist(fname, create_using=nx.DiGraph())
H2 = nx.read_edgelist(fname, create_using=nx.DiGraph())
assert H != H2 # they should be different graphs
G.remove_node("g") # isolated nodes are not written in edgelist
assert_nodes_equal(list(H), list(G))
assert_edges_equal(list(H.edges()), list(G.edges()))
os.close(fd)
os.unlink(fname)
def test_edgelist_integers(self):
G = nx.convert_node_labels_to_integers(self.G)
(fd, fname) = tempfile.mkstemp()
nx.write_edgelist(G, fname)
H = nx.read_edgelist(fname, nodetype=int)
# isolated nodes are not written in edgelist
G.remove_nodes_from(list(nx.isolates(G)))
assert_nodes_equal(list(H), list(G))
assert_edges_equal(list(H.edges()), list(G.edges()))
os.close(fd)
os.unlink(fname)
def test_edgelist_multigraph(self):
G = self.XG
(fd, fname) = tempfile.mkstemp()
nx.write_edgelist(G, fname)
H = nx.read_edgelist(fname, nodetype=int, create_using=nx.MultiGraph())
H2 = nx.read_edgelist(fname, nodetype=int, create_using=nx.MultiGraph())
assert H != H2 # they should be different graphs
assert_nodes_equal(list(H), list(G))
assert_edges_equal(list(H.edges()), list(G.edges()))
os.close(fd)
os.unlink(fname)
def test_edgelist_multidigraph(self):
G = self.XDG
(fd, fname) = tempfile.mkstemp()
nx.write_edgelist(G, fname)
H = nx.read_edgelist(fname, nodetype=int, create_using=nx.MultiDiGraph())
H2 = nx.read_edgelist(fname, nodetype=int, create_using=nx.MultiDiGraph())
assert H != H2 # they should be different graphs
assert_nodes_equal(list(H), list(G))
assert_edges_equal(list(H.edges()), list(G.edges()))
os.close(fd)
os.unlink(fname)

View file

@ -0,0 +1,658 @@
import io
import sys
import time
import pytest
import networkx as nx
class TestGEXF:
@classmethod
def setup_class(cls):
_ = pytest.importorskip("xml.etree.ElementTree")
cls.simple_directed_data = """<?xml version="1.0" encoding="UTF-8"?>
<gexf xmlns="http://www.gexf.net/1.2draft" version="1.2">
<graph mode="static" defaultedgetype="directed">
<nodes>
<node id="0" label="Hello" />
<node id="1" label="Word" />
</nodes>
<edges>
<edge id="0" source="0" target="1" />
</edges>
</graph>
</gexf>
"""
cls.simple_directed_graph = nx.DiGraph()
cls.simple_directed_graph.add_node("0", label="Hello")
cls.simple_directed_graph.add_node("1", label="World")
cls.simple_directed_graph.add_edge("0", "1", id="0")
cls.simple_directed_fh = io.BytesIO(cls.simple_directed_data.encode("UTF-8"))
cls.attribute_data = """<?xml version="1.0" encoding="UTF-8"?>\
<gexf xmlns="http://www.gexf.net/1.2draft" xmlns:xsi="http://www.w3.\
org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.gexf.net/\
1.2draft http://www.gexf.net/1.2draft/gexf.xsd" version="1.2">
<meta lastmodifieddate="2009-03-20">
<creator>Gephi.org</creator>
<description>A Web network</description>
</meta>
<graph defaultedgetype="directed">
<attributes class="node">
<attribute id="0" title="url" type="string"/>
<attribute id="1" title="indegree" type="integer"/>
<attribute id="2" title="frog" type="boolean">
<default>true</default>
</attribute>
</attributes>
<nodes>
<node id="0" label="Gephi">
<attvalues>
<attvalue for="0" value="https://gephi.org"/>
<attvalue for="1" value="1"/>
<attvalue for="2" value="false"/>
</attvalues>
</node>
<node id="1" label="Webatlas">
<attvalues>
<attvalue for="0" value="http://webatlas.fr"/>
<attvalue for="1" value="2"/>
<attvalue for="2" value="false"/>
</attvalues>
</node>
<node id="2" label="RTGI">
<attvalues>
<attvalue for="0" value="http://rtgi.fr"/>
<attvalue for="1" value="1"/>
<attvalue for="2" value="true"/>
</attvalues>
</node>
<node id="3" label="BarabasiLab">
<attvalues>
<attvalue for="0" value="http://barabasilab.com"/>
<attvalue for="1" value="1"/>
<attvalue for="2" value="true"/>
</attvalues>
</node>
</nodes>
<edges>
<edge id="0" source="0" target="1" label="foo"/>
<edge id="1" source="0" target="2"/>
<edge id="2" source="1" target="0"/>
<edge id="3" source="2" target="1"/>
<edge id="4" source="0" target="3"/>
</edges>
</graph>
</gexf>
"""
cls.attribute_graph = nx.DiGraph()
cls.attribute_graph.graph["node_default"] = {"frog": True}
cls.attribute_graph.add_node(
"0", label="Gephi", url="https://gephi.org", indegree=1, frog=False
)
cls.attribute_graph.add_node(
"1", label="Webatlas", url="http://webatlas.fr", indegree=2, frog=False
)
cls.attribute_graph.add_node(
"2", label="RTGI", url="http://rtgi.fr", indegree=1, frog=True
)
cls.attribute_graph.add_node(
"3",
label="BarabasiLab",
url="http://barabasilab.com",
indegree=1,
frog=True,
)
cls.attribute_graph.add_edge("0", "1", id="0", label="foo")
cls.attribute_graph.add_edge("0", "2", id="1")
cls.attribute_graph.add_edge("1", "0", id="2")
cls.attribute_graph.add_edge("2", "1", id="3")
cls.attribute_graph.add_edge("0", "3", id="4")
cls.attribute_fh = io.BytesIO(cls.attribute_data.encode("UTF-8"))
cls.simple_undirected_data = """<?xml version="1.0" encoding="UTF-8"?>
<gexf xmlns="http://www.gexf.net/1.2draft" version="1.2">
<graph mode="static" defaultedgetype="undirected">
<nodes>
<node id="0" label="Hello" />
<node id="1" label="Word" />
</nodes>
<edges>
<edge id="0" source="0" target="1" />
</edges>
</graph>
</gexf>
"""
cls.simple_undirected_graph = nx.Graph()
cls.simple_undirected_graph.add_node("0", label="Hello")
cls.simple_undirected_graph.add_node("1", label="World")
cls.simple_undirected_graph.add_edge("0", "1", id="0")
cls.simple_undirected_fh = io.BytesIO(
cls.simple_undirected_data.encode("UTF-8")
)
def test_read_simple_directed_graphml(self):
G = self.simple_directed_graph
H = nx.read_gexf(self.simple_directed_fh)
assert sorted(G.nodes()) == sorted(H.nodes())
assert sorted(G.edges()) == sorted(H.edges())
assert sorted(G.edges(data=True)) == sorted(H.edges(data=True))
self.simple_directed_fh.seek(0)
def test_write_read_simple_directed_graphml(self):
G = self.simple_directed_graph
fh = io.BytesIO()
nx.write_gexf(G, fh)
fh.seek(0)
H = nx.read_gexf(fh)
assert sorted(G.nodes()) == sorted(H.nodes())
assert sorted(G.edges()) == sorted(H.edges())
assert sorted(G.edges(data=True)) == sorted(H.edges(data=True))
self.simple_directed_fh.seek(0)
def test_read_simple_undirected_graphml(self):
G = self.simple_undirected_graph
H = nx.read_gexf(self.simple_undirected_fh)
assert sorted(G.nodes()) == sorted(H.nodes())
assert sorted(sorted(e) for e in G.edges()) == sorted(
sorted(e) for e in H.edges()
)
self.simple_undirected_fh.seek(0)
def test_read_attribute_graphml(self):
G = self.attribute_graph
H = nx.read_gexf(self.attribute_fh)
assert sorted(G.nodes(True)) == sorted(H.nodes(data=True))
ge = sorted(G.edges(data=True))
he = sorted(H.edges(data=True))
for a, b in zip(ge, he):
assert a == b
self.attribute_fh.seek(0)
def test_directed_edge_in_undirected(self):
s = """<?xml version="1.0" encoding="UTF-8"?>
<gexf xmlns="http://www.gexf.net/1.2draft" version='1.2'>
<graph mode="static" defaultedgetype="undirected" name="">
<nodes>
<node id="0" label="Hello" />
<node id="1" label="Word" />
</nodes>
<edges>
<edge id="0" source="0" target="1" type="directed"/>
</edges>
</graph>
</gexf>
"""
fh = io.BytesIO(s.encode("UTF-8"))
pytest.raises(nx.NetworkXError, nx.read_gexf, fh)
def test_undirected_edge_in_directed(self):
s = """<?xml version="1.0" encoding="UTF-8"?>
<gexf xmlns="http://www.gexf.net/1.2draft" version='1.2'>
<graph mode="static" defaultedgetype="directed" name="">
<nodes>
<node id="0" label="Hello" />
<node id="1" label="Word" />
</nodes>
<edges>
<edge id="0" source="0" target="1" type="undirected"/>
</edges>
</graph>
</gexf>
"""
fh = io.BytesIO(s.encode("UTF-8"))
pytest.raises(nx.NetworkXError, nx.read_gexf, fh)
def test_key_raises(self):
s = """<?xml version="1.0" encoding="UTF-8"?>
<gexf xmlns="http://www.gexf.net/1.2draft" version='1.2'>
<graph mode="static" defaultedgetype="directed" name="">
<nodes>
<node id="0" label="Hello">
<attvalues>
<attvalue for='0' value='1'/>
</attvalues>
</node>
<node id="1" label="Word" />
</nodes>
<edges>
<edge id="0" source="0" target="1" type="undirected"/>
</edges>
</graph>
</gexf>
"""
fh = io.BytesIO(s.encode("UTF-8"))
pytest.raises(nx.NetworkXError, nx.read_gexf, fh)
def test_relabel(self):
s = """<?xml version="1.0" encoding="UTF-8"?>
<gexf xmlns="http://www.gexf.net/1.2draft" version='1.2'>
<graph mode="static" defaultedgetype="directed" name="">
<nodes>
<node id="0" label="Hello" />
<node id="1" label="Word" />
</nodes>
<edges>
<edge id="0" source="0" target="1"/>
</edges>
</graph>
</gexf>
"""
fh = io.BytesIO(s.encode("UTF-8"))
G = nx.read_gexf(fh, relabel=True)
assert sorted(G.nodes()) == ["Hello", "Word"]
def test_default_attribute(self):
G = nx.Graph()
G.add_node(1, label="1", color="green")
nx.add_path(G, [0, 1, 2, 3])
G.add_edge(1, 2, foo=3)
G.graph["node_default"] = {"color": "yellow"}
G.graph["edge_default"] = {"foo": 7}
fh = io.BytesIO()
nx.write_gexf(G, fh)
fh.seek(0)
H = nx.read_gexf(fh, node_type=int)
assert sorted(G.nodes()) == sorted(H.nodes())
assert sorted(sorted(e) for e in G.edges()) == sorted(
sorted(e) for e in H.edges()
)
# Reading a gexf graph always sets mode attribute to either
# 'static' or 'dynamic'. Remove the mode attribute from the
# read graph for the sake of comparing remaining attributes.
del H.graph["mode"]
assert G.graph == H.graph
def test_serialize_ints_to_strings(self):
G = nx.Graph()
G.add_node(1, id=7, label=77)
fh = io.BytesIO()
nx.write_gexf(G, fh)
fh.seek(0)
H = nx.read_gexf(fh, node_type=int)
assert list(H) == [7]
assert H.nodes[7]["label"] == "77"
# FIXME: We should test xml without caring about their order This is causing a
# problem b/c of a change in Python 3.8
#
# "Prior to Python 3.8, the serialisation order of the XML attributes of
# elements was artificially made predictable by sorting the attributes by their
# name. Based on the now guaranteed ordering of dicts, this arbitrary
# reordering was removed in Python 3.8 to preserve the order in which
# attributes were originally parsed or created by user code."
#
# https://docs.python.org/3.8/library/xml.etree.elementtree.html
# https://bugs.python.org/issue34160
def test_write_with_node_attributes(self):
# Addresses #673.
G = nx.OrderedGraph()
G.add_edges_from([(0, 1), (1, 2), (2, 3)])
for i in range(4):
G.nodes[i]["id"] = i
G.nodes[i]["label"] = i
G.nodes[i]["pid"] = i
G.nodes[i]["start"] = i
G.nodes[i]["end"] = i + 1
if sys.version_info < (3, 8):
expected = f"""<gexf version="1.2" xmlns="http://www.gexf.net/1.2\
draft" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:\
schemaLocation="http://www.gexf.net/1.2draft http://www.gexf.net/1.2draft/\
gexf.xsd">
<meta lastmodifieddate="{time.strftime('%Y-%m-%d')}">
<creator>NetworkX {nx.__version__}</creator>
</meta>
<graph defaultedgetype="undirected" mode="dynamic" name="" timeformat="long">
<nodes>
<node end="1" id="0" label="0" pid="0" start="0" />
<node end="2" id="1" label="1" pid="1" start="1" />
<node end="3" id="2" label="2" pid="2" start="2" />
<node end="4" id="3" label="3" pid="3" start="3" />
</nodes>
<edges>
<edge id="0" source="0" target="1" />
<edge id="1" source="1" target="2" />
<edge id="2" source="2" target="3" />
</edges>
</graph>
</gexf>"""
else:
expected = f"""<gexf xmlns="http://www.gexf.net/1.2draft" xmlns:xsi\
="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=\
"http://www.gexf.net/1.2draft http://www.gexf.net/1.2draft/\
gexf.xsd" version="1.2">
<meta lastmodifieddate="{time.strftime('%Y-%m-%d')}">
<creator>NetworkX {nx.__version__}</creator>
</meta>
<graph defaultedgetype="undirected" mode="dynamic" name="" timeformat="long">
<nodes>
<node id="0" label="0" pid="0" start="0" end="1" />
<node id="1" label="1" pid="1" start="1" end="2" />
<node id="2" label="2" pid="2" start="2" end="3" />
<node id="3" label="3" pid="3" start="3" end="4" />
</nodes>
<edges>
<edge source="0" target="1" id="0" />
<edge source="1" target="2" id="1" />
<edge source="2" target="3" id="2" />
</edges>
</graph>
</gexf>"""
obtained = "\n".join(nx.generate_gexf(G))
assert expected == obtained
def test_edge_id_construct(self):
G = nx.Graph()
G.add_edges_from([(0, 1, {"id": 0}), (1, 2, {"id": 2}), (2, 3)])
if sys.version_info < (3, 8):
expected = f"""<gexf version="1.2" xmlns="http://www.gexf.net/\
1.2draft" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:\
schemaLocation="http://www.gexf.net/1.2draft http://www.gexf.net/1.2draft/\
gexf.xsd">
<meta lastmodifieddate="{time.strftime('%Y-%m-%d')}">
<creator>NetworkX {nx.__version__}</creator>
</meta>
<graph defaultedgetype="undirected" mode="static" name="">
<nodes>
<node id="0" label="0" />
<node id="1" label="1" />
<node id="2" label="2" />
<node id="3" label="3" />
</nodes>
<edges>
<edge id="0" source="0" target="1" />
<edge id="2" source="1" target="2" />
<edge id="1" source="2" target="3" />
</edges>
</graph>
</gexf>"""
else:
expected = f"""<gexf xmlns="http://www.gexf.net/1.2draft" xmlns:xsi\
="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.\
gexf.net/1.2draft http://www.gexf.net/1.2draft/gexf.xsd" version="1.2">
<meta lastmodifieddate="{time.strftime('%Y-%m-%d')}">
<creator>NetworkX {nx.__version__}</creator>
</meta>
<graph defaultedgetype="undirected" mode="static" name="">
<nodes>
<node id="0" label="0" />
<node id="1" label="1" />
<node id="2" label="2" />
<node id="3" label="3" />
</nodes>
<edges>
<edge source="0" target="1" id="0" />
<edge source="1" target="2" id="2" />
<edge source="2" target="3" id="1" />
</edges>
</graph>
</gexf>"""
obtained = "\n".join(nx.generate_gexf(G))
assert expected == obtained
def test_numpy_type(self):
G = nx.path_graph(4)
try:
import numpy
except ImportError:
return
nx.set_node_attributes(G, {n: n for n in numpy.arange(4)}, "number")
G[0][1]["edge-number"] = numpy.float64(1.1)
if sys.version_info < (3, 8):
expected = f"""<gexf version="1.2" xmlns="http://www.gexf.net/1.2draft"\
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation\
="http://www.gexf.net/1.2draft http://www.gexf.net/1.2draft/gexf.xsd">
<meta lastmodifieddate="{time.strftime('%Y-%m-%d')}">
<creator>NetworkX {nx.__version__}</creator>
</meta>
<graph defaultedgetype="undirected" mode="static" name="">
<attributes class="edge" mode="static">
<attribute id="1" title="edge-number" type="float" />
</attributes>
<attributes class="node" mode="static">
<attribute id="0" title="number" type="int" />
</attributes>
<nodes>
<node id="0" label="0">
<attvalues>
<attvalue for="0" value="0" />
</attvalues>
</node>
<node id="1" label="1">
<attvalues>
<attvalue for="0" value="1" />
</attvalues>
</node>
<node id="2" label="2">
<attvalues>
<attvalue for="0" value="2" />
</attvalues>
</node>
<node id="3" label="3">
<attvalues>
<attvalue for="0" value="3" />
</attvalues>
</node>
</nodes>
<edges>
<edge id="0" source="0" target="1">
<attvalues>
<attvalue for="1" value="1.1" />
</attvalues>
</edge>
<edge id="1" source="1" target="2" />
<edge id="2" source="2" target="3" />
</edges>
</graph>
</gexf>"""
else:
expected = f"""<gexf xmlns="http://www.gexf.net/1.2draft"\
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation\
="http://www.gexf.net/1.2draft http://www.gexf.net/1.2draft/gexf.xsd"\
version="1.2">
<meta lastmodifieddate="{time.strftime('%Y-%m-%d')}">
<creator>NetworkX {nx.__version__}</creator>
</meta>
<graph defaultedgetype="undirected" mode="static" name="">
<attributes mode="static" class="edge">
<attribute id="1" title="edge-number" type="float" />
</attributes>
<attributes mode="static" class="node">
<attribute id="0" title="number" type="int" />
</attributes>
<nodes>
<node id="0" label="0">
<attvalues>
<attvalue for="0" value="0" />
</attvalues>
</node>
<node id="1" label="1">
<attvalues>
<attvalue for="0" value="1" />
</attvalues>
</node>
<node id="2" label="2">
<attvalues>
<attvalue for="0" value="2" />
</attvalues>
</node>
<node id="3" label="3">
<attvalues>
<attvalue for="0" value="3" />
</attvalues>
</node>
</nodes>
<edges>
<edge source="0" target="1" id="0">
<attvalues>
<attvalue for="1" value="1.1" />
</attvalues>
</edge>
<edge source="1" target="2" id="1" />
<edge source="2" target="3" id="2" />
</edges>
</graph>
</gexf>"""
obtained = "\n".join(nx.generate_gexf(G))
assert expected == obtained
def test_bool(self):
G = nx.Graph()
G.add_node(1, testattr=True)
fh = io.BytesIO()
nx.write_gexf(G, fh)
fh.seek(0)
H = nx.read_gexf(fh, node_type=int)
assert H.nodes[1]["testattr"]
# Test for NaN, INF and -INF
def test_specials(self):
from math import isnan
inf, nan = float("inf"), float("nan")
G = nx.Graph()
G.add_node(1, testattr=inf, strdata="inf", key="a")
G.add_node(2, testattr=nan, strdata="nan", key="b")
G.add_node(3, testattr=-inf, strdata="-inf", key="c")
fh = io.BytesIO()
nx.write_gexf(G, fh)
fh.seek(0)
filetext = fh.read()
fh.seek(0)
H = nx.read_gexf(fh, node_type=int)
assert b"INF" in filetext
assert b"NaN" in filetext
assert b"-INF" in filetext
assert H.nodes[1]["testattr"] == inf
assert isnan(H.nodes[2]["testattr"])
assert H.nodes[3]["testattr"] == -inf
assert H.nodes[1]["strdata"] == "inf"
assert H.nodes[2]["strdata"] == "nan"
assert H.nodes[3]["strdata"] == "-inf"
assert H.nodes[1]["networkx_key"] == "a"
assert H.nodes[2]["networkx_key"] == "b"
assert H.nodes[3]["networkx_key"] == "c"
def test_simple_list(self):
G = nx.Graph()
list_value = [(1, 2, 3), (9, 1, 2)]
G.add_node(1, key=list_value)
fh = io.BytesIO()
nx.write_gexf(G, fh)
fh.seek(0)
H = nx.read_gexf(fh, node_type=int)
assert H.nodes[1]["networkx_key"] == list_value
def test_dynamic_mode(self):
G = nx.Graph()
G.add_node(1, label="1", color="green")
G.graph["mode"] = "dynamic"
fh = io.BytesIO()
nx.write_gexf(G, fh)
fh.seek(0)
H = nx.read_gexf(fh, node_type=int)
assert sorted(G.nodes()) == sorted(H.nodes())
assert sorted(sorted(e) for e in G.edges()) == sorted(
sorted(e) for e in H.edges()
)
def test_multigraph_with_missing_attributes(self):
G = nx.MultiGraph()
G.add_node(0, label="1", color="green")
G.add_node(1, label="2", color="green")
G.add_edge(0, 1, id="0", wight=3, type="undirected", start=0, end=1)
G.add_edge(0, 1, id="1", label="foo", start=0, end=1)
G.add_edge(0, 1)
fh = io.BytesIO()
nx.write_gexf(G, fh)
fh.seek(0)
H = nx.read_gexf(fh, node_type=int)
assert sorted(G.nodes()) == sorted(H.nodes())
assert sorted(sorted(e) for e in G.edges()) == sorted(
sorted(e) for e in H.edges()
)
def test_missing_viz_attributes(self):
G = nx.Graph()
G.add_node(0, label="1", color="green")
G.nodes[0]["viz"] = {"size": 54}
G.nodes[0]["viz"]["position"] = {"x": 0, "y": 1, "z": 0}
G.nodes[0]["viz"]["color"] = {"r": 0, "g": 0, "b": 256}
G.nodes[0]["viz"]["shape"] = "http://random.url"
G.nodes[0]["viz"]["thickness"] = 2
fh = io.BytesIO()
nx.write_gexf(G, fh, version="1.1draft")
fh.seek(0)
H = nx.read_gexf(fh, node_type=int)
assert sorted(G.nodes()) == sorted(H.nodes())
assert sorted(sorted(e) for e in G.edges()) == sorted(
sorted(e) for e in H.edges()
)
# Second graph for the other branch
G = nx.Graph()
G.add_node(0, label="1", color="green")
G.nodes[0]["viz"] = {"size": 54}
G.nodes[0]["viz"]["position"] = {"x": 0, "y": 1, "z": 0}
G.nodes[0]["viz"]["color"] = {"r": 0, "g": 0, "b": 256, "a": 0.5}
G.nodes[0]["viz"]["shape"] = "ftp://random.url"
G.nodes[0]["viz"]["thickness"] = 2
fh = io.BytesIO()
nx.write_gexf(G, fh)
fh.seek(0)
H = nx.read_gexf(fh, node_type=int)
assert sorted(G.nodes()) == sorted(H.nodes())
assert sorted(sorted(e) for e in G.edges()) == sorted(
sorted(e) for e in H.edges()
)
def test_slice_and_spell(self):
# Test spell first, so version = 1.2
G = nx.Graph()
G.add_node(0, label="1", color="green")
G.nodes[0]["spells"] = [(1, 2)]
fh = io.BytesIO()
nx.write_gexf(G, fh)
fh.seek(0)
H = nx.read_gexf(fh, node_type=int)
assert sorted(G.nodes()) == sorted(H.nodes())
assert sorted(sorted(e) for e in G.edges()) == sorted(
sorted(e) for e in H.edges()
)
G = nx.Graph()
G.add_node(0, label="1", color="green")
G.nodes[0]["slices"] = [(1, 2)]
fh = io.BytesIO()
nx.write_gexf(G, fh, version="1.1draft")
fh.seek(0)
H = nx.read_gexf(fh, node_type=int)
assert sorted(G.nodes()) == sorted(H.nodes())
assert sorted(sorted(e) for e in G.edges()) == sorted(
sorted(e) for e in H.edges()
)
def test_add_parent(self):
G = nx.Graph()
G.add_node(0, label="1", color="green", parents=[1, 2])
fh = io.BytesIO()
nx.write_gexf(G, fh)
fh.seek(0)
H = nx.read_gexf(fh, node_type=int)
assert sorted(G.nodes()) == sorted(H.nodes())
assert sorted(sorted(e) for e in G.edges()) == sorted(
sorted(e) for e in H.edges()
)

View file

@ -0,0 +1,612 @@
from ast import literal_eval
import codecs
from contextlib import contextmanager
import io
import pytest
import networkx as nx
from networkx.readwrite.gml import literal_stringizer, literal_destringizer
import os
import tempfile
from textwrap import dedent
class TestGraph:
@classmethod
def setup_class(cls):
cls.simple_data = """Creator "me"
Version "xx"
graph [
comment "This is a sample graph"
directed 1
IsPlanar 1
pos [ x 0 y 1 ]
node [
id 1
label "Node 1"
pos [ x 1 y 1 ]
]
node [
id 2
pos [ x 1 y 2 ]
label "Node 2"
]
node [
id 3
label "Node 3"
pos [ x 1 y 3 ]
]
edge [
source 1
target 2
label "Edge from node 1 to node 2"
color [line "blue" thickness 3]
]
edge [
source 2
target 3
label "Edge from node 2 to node 3"
]
edge [
source 3
target 1
label "Edge from node 3 to node 1"
]
]
"""
def test_parse_gml_cytoscape_bug(self):
# example from issue #321, originally #324 in trac
cytoscape_example = """
Creator "Cytoscape"
Version 1.0
graph [
node [
root_index -3
id -3
graphics [
x -96.0
y -67.0
w 40.0
h 40.0
fill "#ff9999"
type "ellipse"
outline "#666666"
outline_width 1.5
]
label "node2"
]
node [
root_index -2
id -2
graphics [
x 63.0
y 37.0
w 40.0
h 40.0
fill "#ff9999"
type "ellipse"
outline "#666666"
outline_width 1.5
]
label "node1"
]
node [
root_index -1
id -1
graphics [
x -31.0
y -17.0
w 40.0
h 40.0
fill "#ff9999"
type "ellipse"
outline "#666666"
outline_width 1.5
]
label "node0"
]
edge [
root_index -2
target -2
source -1
graphics [
width 1.5
fill "#0000ff"
type "line"
Line [
]
source_arrow 0
target_arrow 3
]
label "DirectedEdge"
]
edge [
root_index -1
target -1
source -3
graphics [
width 1.5
fill "#0000ff"
type "line"
Line [
]
source_arrow 0
target_arrow 3
]
label "DirectedEdge"
]
]
"""
nx.parse_gml(cytoscape_example)
def test_parse_gml(self):
G = nx.parse_gml(self.simple_data, label="label")
assert sorted(G.nodes()) == ["Node 1", "Node 2", "Node 3"]
assert [e for e in sorted(G.edges())] == [
("Node 1", "Node 2"),
("Node 2", "Node 3"),
("Node 3", "Node 1"),
]
assert [e for e in sorted(G.edges(data=True))] == [
(
"Node 1",
"Node 2",
{
"color": {"line": "blue", "thickness": 3},
"label": "Edge from node 1 to node 2",
},
),
("Node 2", "Node 3", {"label": "Edge from node 2 to node 3"}),
("Node 3", "Node 1", {"label": "Edge from node 3 to node 1"}),
]
def test_read_gml(self):
(fd, fname) = tempfile.mkstemp()
fh = open(fname, "w")
fh.write(self.simple_data)
fh.close()
Gin = nx.read_gml(fname, label="label")
G = nx.parse_gml(self.simple_data, label="label")
assert sorted(G.nodes(data=True)) == sorted(Gin.nodes(data=True))
assert sorted(G.edges(data=True)) == sorted(Gin.edges(data=True))
os.close(fd)
os.unlink(fname)
def test_labels_are_strings(self):
# GML requires labels to be strings (i.e., in quotes)
answer = """graph [
node [
id 0
label "1203"
]
]"""
G = nx.Graph()
G.add_node(1203)
data = "\n".join(nx.generate_gml(G, stringizer=literal_stringizer))
assert data == answer
def test_relabel_duplicate(self):
data = """
graph
[
label ""
directed 1
node
[
id 0
label "same"
]
node
[
id 1
label "same"
]
]
"""
fh = io.BytesIO(data.encode("UTF-8"))
fh.seek(0)
pytest.raises(nx.NetworkXError, nx.read_gml, fh, label="label")
def test_tuplelabels(self):
# https://github.com/networkx/networkx/pull/1048
# Writing tuple labels to GML failed.
G = nx.OrderedGraph()
G.add_edge((0, 1), (1, 0))
data = "\n".join(nx.generate_gml(G, stringizer=literal_stringizer))
answer = """graph [
node [
id 0
label "(0,1)"
]
node [
id 1
label "(1,0)"
]
edge [
source 0
target 1
]
]"""
assert data == answer
def test_quotes(self):
# https://github.com/networkx/networkx/issues/1061
# Encoding quotes as HTML entities.
G = nx.path_graph(1)
G.name = "path_graph(1)"
attr = 'This is "quoted" and this is a copyright: ' + chr(169)
G.nodes[0]["demo"] = attr
fobj = tempfile.NamedTemporaryFile()
nx.write_gml(G, fobj)
fobj.seek(0)
# Should be bytes in 2.x and 3.x
data = fobj.read().strip().decode("ascii")
answer = """graph [
name "path_graph(1)"
node [
id 0
label "0"
demo "This is &#34;quoted&#34; and this is a copyright: &#169;"
]
]"""
assert data == answer
def test_unicode_node(self):
node = "node" + chr(169)
G = nx.Graph()
G.add_node(node)
fobj = tempfile.NamedTemporaryFile()
nx.write_gml(G, fobj)
fobj.seek(0)
# Should be bytes in 2.x and 3.x
data = fobj.read().strip().decode("ascii")
answer = """graph [
node [
id 0
label "node&#169;"
]
]"""
assert data == answer
def test_float_label(self):
node = 1.0
G = nx.Graph()
G.add_node(node)
fobj = tempfile.NamedTemporaryFile()
nx.write_gml(G, fobj)
fobj.seek(0)
# Should be bytes in 2.x and 3.x
data = fobj.read().strip().decode("ascii")
answer = """graph [
node [
id 0
label "1.0"
]
]"""
assert data == answer
def test_name(self):
G = nx.parse_gml('graph [ name "x" node [ id 0 label "x" ] ]')
assert "x" == G.graph["name"]
G = nx.parse_gml('graph [ node [ id 0 label "x" ] ]')
assert "" == G.name
assert "name" not in G.graph
def test_graph_types(self):
for directed in [None, False, True]:
for multigraph in [None, False, True]:
gml = "graph ["
if directed is not None:
gml += " directed " + str(int(directed))
if multigraph is not None:
gml += " multigraph " + str(int(multigraph))
gml += ' node [ id 0 label "0" ]'
gml += " edge [ source 0 target 0 ]"
gml += " ]"
G = nx.parse_gml(gml)
assert bool(directed) == G.is_directed()
assert bool(multigraph) == G.is_multigraph()
gml = "graph [\n"
if directed is True:
gml += " directed 1\n"
if multigraph is True:
gml += " multigraph 1\n"
gml += """ node [
id 0
label "0"
]
edge [
source 0
target 0
"""
if multigraph:
gml += " key 0\n"
gml += " ]\n]"
assert gml == "\n".join(nx.generate_gml(G))
def test_data_types(self):
data = [
True,
False,
10 ** 20,
-2e33,
"'",
'"&&amp;&&#34;"',
[{(b"\xfd",): "\x7f", chr(0x4444): (1, 2)}, (2, "3")],
]
try: # fails under IronPython
data.append(chr(0x14444))
except ValueError:
data.append(chr(0x1444))
data.append(literal_eval("{2.3j, 1 - 2.3j, ()}"))
G = nx.Graph()
G.name = data
G.graph["data"] = data
G.add_node(0, int=-1, data=dict(data=data))
G.add_edge(0, 0, float=-2.5, data=data)
gml = "\n".join(nx.generate_gml(G, stringizer=literal_stringizer))
G = nx.parse_gml(gml, destringizer=literal_destringizer)
assert data == G.name
assert {"name": data, "data": data} == G.graph
assert list(G.nodes(data=True)) == [(0, dict(int=-1, data=dict(data=data)))]
assert list(G.edges(data=True)) == [(0, 0, dict(float=-2.5, data=data))]
G = nx.Graph()
G.graph["data"] = "frozenset([1, 2, 3])"
G = nx.parse_gml(nx.generate_gml(G), destringizer=literal_eval)
assert G.graph["data"] == "frozenset([1, 2, 3])"
def test_escape_unescape(self):
gml = """graph [
name "&amp;&#34;&#xf;&#x4444;&#1234567890;&#x1234567890abcdef;&unknown;"
]"""
G = nx.parse_gml(gml)
assert (
'&"\x0f' + chr(0x4444) + "&#1234567890;&#x1234567890abcdef;&unknown;"
== G.name
)
gml = "\n".join(nx.generate_gml(G))
alnu = "#1234567890;&#38;#x1234567890abcdef"
answer = (
"""graph [
name "&#38;&#34;&#15;&#17476;&#38;"""
+ alnu
+ """;&#38;unknown;"
]"""
)
assert answer == gml
def test_exceptions(self):
pytest.raises(ValueError, literal_destringizer, "(")
pytest.raises(ValueError, literal_destringizer, "frozenset([1, 2, 3])")
pytest.raises(ValueError, literal_destringizer, literal_destringizer)
pytest.raises(ValueError, literal_stringizer, frozenset([1, 2, 3]))
pytest.raises(ValueError, literal_stringizer, literal_stringizer)
with tempfile.TemporaryFile() as f:
f.write(codecs.BOM_UTF8 + b"graph[]")
f.seek(0)
pytest.raises(nx.NetworkXError, nx.read_gml, f)
def assert_parse_error(gml):
pytest.raises(nx.NetworkXError, nx.parse_gml, gml)
assert_parse_error(["graph [\n\n", "]"])
assert_parse_error("")
assert_parse_error('Creator ""')
assert_parse_error("0")
assert_parse_error("graph ]")
assert_parse_error("graph [ 1 ]")
assert_parse_error("graph [ 1.E+2 ]")
assert_parse_error('graph [ "A" ]')
assert_parse_error("graph [ ] graph ]")
assert_parse_error("graph [ ] graph [ ]")
assert_parse_error("graph [ data [1, 2, 3] ]")
assert_parse_error("graph [ node [ ] ]")
assert_parse_error("graph [ node [ id 0 ] ]")
nx.parse_gml('graph [ node [ id "a" ] ]', label="id")
assert_parse_error("graph [ node [ id 0 label 0 ] node [ id 0 label 1 ] ]")
assert_parse_error("graph [ node [ id 0 label 0 ] node [ id 1 label 0 ] ]")
assert_parse_error("graph [ node [ id 0 label 0 ] edge [ ] ]")
assert_parse_error("graph [ node [ id 0 label 0 ] edge [ source 0 ] ]")
nx.parse_gml("graph [edge [ source 0 target 0 ] node [ id 0 label 0 ] ]")
assert_parse_error("graph [ node [ id 0 label 0 ] edge [ source 1 target 0 ] ]")
assert_parse_error("graph [ node [ id 0 label 0 ] edge [ source 0 target 1 ] ]")
assert_parse_error(
"graph [ node [ id 0 label 0 ] node [ id 1 label 1 ] "
"edge [ source 0 target 1 ] edge [ source 1 target 0 ] ]"
)
nx.parse_gml(
"graph [ node [ id 0 label 0 ] node [ id 1 label 1 ] "
"edge [ source 0 target 1 ] edge [ source 1 target 0 ] "
"directed 1 ]"
)
nx.parse_gml(
"graph [ node [ id 0 label 0 ] node [ id 1 label 1 ] "
"edge [ source 0 target 1 ] edge [ source 0 target 1 ]"
"multigraph 1 ]"
)
nx.parse_gml(
"graph [ node [ id 0 label 0 ] node [ id 1 label 1 ] "
"edge [ source 0 target 1 key 0 ] edge [ source 0 target 1 ]"
"multigraph 1 ]"
)
assert_parse_error(
"graph [ node [ id 0 label 0 ] node [ id 1 label 1 ] "
"edge [ source 0 target 1 key 0 ] edge [ source 0 target 1 key 0 ]"
"multigraph 1 ]"
)
nx.parse_gml(
"graph [ node [ id 0 label 0 ] node [ id 1 label 1 ] "
"edge [ source 0 target 1 key 0 ] edge [ source 1 target 0 key 0 ]"
"directed 1 multigraph 1 ]"
)
# Tests for string convertable alphanumeric id and label values
nx.parse_gml("graph [edge [ source a target a ] node [ id a label b ] ]")
nx.parse_gml(
"graph [ node [ id n42 label 0 ] node [ id x43 label 1 ]"
"edge [ source n42 target x43 key 0 ]"
"edge [ source x43 target n42 key 0 ]"
"directed 1 multigraph 1 ]"
)
assert_parse_error(
"graph [edge [ source u'u\4200' target u'u\4200' ] "
+ "node [ id u'u\4200' label b ] ]"
)
def assert_generate_error(*args, **kwargs):
pytest.raises(
nx.NetworkXError, lambda: list(nx.generate_gml(*args, **kwargs))
)
G = nx.Graph()
G.graph[3] = 3
assert_generate_error(G)
G = nx.Graph()
G.graph["3"] = 3
assert_generate_error(G)
G = nx.Graph()
G.graph["data"] = frozenset([1, 2, 3])
assert_generate_error(G, stringizer=literal_stringizer)
G = nx.Graph()
G.graph["data"] = []
assert_generate_error(G)
assert_generate_error(G, stringizer=len)
def test_label_kwarg(self):
G = nx.parse_gml(self.simple_data, label="id")
assert sorted(G.nodes) == [1, 2, 3]
labels = [G.nodes[n]["label"] for n in sorted(G.nodes)]
assert labels == ["Node 1", "Node 2", "Node 3"]
G = nx.parse_gml(self.simple_data, label=None)
assert sorted(G.nodes) == [1, 2, 3]
labels = [G.nodes[n]["label"] for n in sorted(G.nodes)]
assert labels == ["Node 1", "Node 2", "Node 3"]
def test_outofrange_integers(self):
# GML restricts integers to 32 signed bits.
# Check that we honor this restriction on export
G = nx.Graph()
# Test export for numbers that barely fit or don't fit into 32 bits,
# and 3 numbers in the middle
numbers = {
"toosmall": (-(2 ** 31)) - 1,
"small": -(2 ** 31),
"med1": -4,
"med2": 0,
"med3": 17,
"big": (2 ** 31) - 1,
"toobig": 2 ** 31,
}
G.add_node("Node", **numbers)
fd, fname = tempfile.mkstemp()
try:
nx.write_gml(G, fname)
# Check that the export wrote the nonfitting numbers as strings
G2 = nx.read_gml(fname)
for attr, value in G2.nodes["Node"].items():
if attr == "toosmall" or attr == "toobig":
assert type(value) == str
else:
assert type(value) == int
finally:
os.close(fd)
os.unlink(fname)
@contextmanager
def byte_file():
_file_handle = io.BytesIO()
yield _file_handle
_file_handle.seek(0)
class TestPropertyLists:
def test_writing_graph_with_multi_element_property_list(self):
g = nx.Graph()
g.add_node("n1", properties=["element", 0, 1, 2.5, True, False])
with byte_file() as f:
nx.write_gml(g, f)
result = f.read().decode()
assert result == dedent(
"""\
graph [
node [
id 0
label "n1"
properties "element"
properties 0
properties 1
properties 2.5
properties 1
properties 0
]
]
"""
)
def test_writing_graph_with_one_element_property_list(self):
g = nx.Graph()
g.add_node("n1", properties=["element"])
with byte_file() as f:
nx.write_gml(g, f)
result = f.read().decode()
assert result == dedent(
"""\
graph [
node [
id 0
label "n1"
properties "_networkx_list_start"
properties "element"
]
]
"""
)
def test_reading_graph_with_list_property(self):
with byte_file() as f:
f.write(
dedent(
"""
graph [
node [
id 0
label "n1"
properties "element"
properties 0
properties 1
properties 2.5
]
]
"""
).encode("ascii")
)
f.seek(0)
graph = nx.read_gml(f)
assert graph.nodes(data=True)["n1"] == {"properties": ["element", 0, 1, 2.5]}
def test_reading_graph_with_single_element_list_property(self):
with byte_file() as f:
f.write(
dedent(
"""
graph [
node [
id 0
label "n1"
properties "_networkx_list_start"
properties "element"
]
]
"""
).encode("ascii")
)
f.seek(0)
graph = nx.read_gml(f)
assert graph.nodes(data=True)["n1"] == {"properties": ["element"]}

View file

@ -0,0 +1,79 @@
import os
import tempfile
import networkx as nx
from networkx.testing.utils import (
assert_graphs_equal,
assert_edges_equal,
assert_nodes_equal,
)
class TestGpickle:
@classmethod
def setup_class(cls):
G = nx.Graph(name="test")
e = [("a", "b"), ("b", "c"), ("c", "d"), ("d", "e"), ("e", "f"), ("a", "f")]
G.add_edges_from(e, width=10)
G.add_node("g", color="green")
G.graph["number"] = 1
DG = nx.DiGraph(G)
MG = nx.MultiGraph(G)
MG.add_edge("a", "a")
MDG = nx.MultiDiGraph(G)
MDG.add_edge("a", "a")
fG = G.copy()
fDG = DG.copy()
fMG = MG.copy()
fMDG = MDG.copy()
nx.freeze(fG)
nx.freeze(fDG)
nx.freeze(fMG)
nx.freeze(fMDG)
cls.G = G
cls.DG = DG
cls.MG = MG
cls.MDG = MDG
cls.fG = fG
cls.fDG = fDG
cls.fMG = fMG
cls.fMDG = fMDG
def test_gpickle(self):
for G in [
self.G,
self.DG,
self.MG,
self.MDG,
self.fG,
self.fDG,
self.fMG,
self.fMDG,
]:
(fd, fname) = tempfile.mkstemp()
nx.write_gpickle(G, fname)
Gin = nx.read_gpickle(fname)
assert_nodes_equal(list(G.nodes(data=True)), list(Gin.nodes(data=True)))
assert_edges_equal(list(G.edges(data=True)), list(Gin.edges(data=True)))
assert_graphs_equal(G, Gin)
os.close(fd)
os.unlink(fname)
def test_protocol(self):
for G in [
self.G,
self.DG,
self.MG,
self.MDG,
self.fG,
self.fDG,
self.fMG,
self.fMDG,
]:
with tempfile.TemporaryFile() as f:
nx.write_gpickle(G, f, 0)
f.seek(0)
Gin = nx.read_gpickle(f)
assert_nodes_equal(list(G.nodes(data=True)), list(Gin.nodes(data=True)))
assert_edges_equal(list(G.edges(data=True)), list(Gin.edges(data=True)))
assert_graphs_equal(G, Gin)

View file

@ -0,0 +1,118 @@
from io import BytesIO
import tempfile
import pytest
import networkx as nx
import networkx.readwrite.graph6 as g6
from networkx.testing.utils import assert_edges_equal
from networkx.testing.utils import assert_nodes_equal
class TestGraph6Utils:
def test_n_data_n_conversion(self):
for i in [0, 1, 42, 62, 63, 64, 258047, 258048, 7744773, 68719476735]:
assert g6.data_to_n(g6.n_to_data(i))[0] == i
assert g6.data_to_n(g6.n_to_data(i))[1] == []
assert g6.data_to_n(g6.n_to_data(i) + [42, 43])[1] == [42, 43]
class TestFromGraph6Bytes:
def test_from_graph6_bytes(self):
data = b"DF{"
G = nx.from_graph6_bytes(data)
assert_nodes_equal(G.nodes(), [0, 1, 2, 3, 4])
assert_edges_equal(
G.edges(), [(0, 3), (0, 4), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
)
def test_read_equals_from_bytes(self):
data = b"DF{"
G = nx.from_graph6_bytes(data)
fh = BytesIO(data)
Gin = nx.read_graph6(fh)
assert_nodes_equal(G.nodes(), Gin.nodes())
assert_edges_equal(G.edges(), Gin.edges())
class TestReadGraph6:
def test_read_many_graph6(self):
"""Test for reading many graphs from a file into a list."""
data = b"DF{\nD`{\nDqK\nD~{\n"
fh = BytesIO(data)
glist = nx.read_graph6(fh)
assert len(glist) == 4
for G in glist:
assert sorted(G) == list(range(5))
class TestWriteGraph6:
"""Unit tests for writing a graph to a file in graph6 format."""
def test_null_graph(self):
result = BytesIO()
nx.write_graph6(nx.null_graph(), result)
assert result.getvalue() == b">>graph6<<?\n"
def test_trivial_graph(self):
result = BytesIO()
nx.write_graph6(nx.trivial_graph(), result)
assert result.getvalue() == b">>graph6<<@\n"
def test_complete_graph(self):
result = BytesIO()
nx.write_graph6(nx.complete_graph(4), result)
assert result.getvalue() == b">>graph6<<C~\n"
def test_large_complete_graph(self):
result = BytesIO()
nx.write_graph6(nx.complete_graph(67), result, header=False)
assert result.getvalue() == b"~?@B" + b"~" * 368 + b"w\n"
def test_no_header(self):
result = BytesIO()
nx.write_graph6(nx.complete_graph(4), result, header=False)
assert result.getvalue() == b"C~\n"
def test_complete_bipartite_graph(self):
result = BytesIO()
G = nx.complete_bipartite_graph(6, 9)
nx.write_graph6(G, result, header=False)
# The expected encoding here was verified by Sage.
assert result.getvalue() == b"N??F~z{~Fw^_~?~?^_?\n"
def test_no_directed_graphs(self):
with pytest.raises(nx.NetworkXNotImplemented):
nx.write_graph6(nx.DiGraph(), BytesIO())
def test_length(self):
for i in list(range(13)) + [31, 47, 62, 63, 64, 72]:
g = nx.random_graphs.gnm_random_graph(i, i * i // 4, seed=i)
gstr = BytesIO()
nx.write_graph6(g, gstr, header=False)
# Strip the trailing newline.
gstr = gstr.getvalue().rstrip()
assert len(gstr) == ((i - 1) * i // 2 + 5) // 6 + (1 if i < 63 else 4)
def test_roundtrip(self):
for i in list(range(13)) + [31, 47, 62, 63, 64, 72]:
G = nx.random_graphs.gnm_random_graph(i, i * i // 4, seed=i)
f = BytesIO()
nx.write_graph6(G, f)
f.seek(0)
H = nx.read_graph6(f)
assert_nodes_equal(G.nodes(), H.nodes())
assert_edges_equal(G.edges(), H.edges())
def test_write_path(self):
with tempfile.NamedTemporaryFile() as f:
g6.write_graph6_file(nx.null_graph(), f)
f.seek(0)
assert f.read() == b">>graph6<<?\n"
def test_relabeling(self):
G = nx.Graph([(0, 1)])
assert g6.to_graph6_bytes(G) == b">>graph6<<A_\n"
G = nx.Graph([(1, 2)])
assert g6.to_graph6_bytes(G) == b">>graph6<<A_\n"
G = nx.Graph([(1, 42)])
assert g6.to_graph6_bytes(G) == b">>graph6<<A_\n"

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,29 @@
import networkx as nx
import io
class TestLEDA:
def test_parse_leda(self):
data = """#header section \nLEDA.GRAPH \nstring\nint\n-1\n#nodes section\n5 \n|{v1}| \n|{v2}| \n|{v3}| \n|{v4}| \n|{v5}| \n\n#edges section\n7 \n1 2 0 |{4}| \n1 3 0 |{3}| \n2 3 0 |{2}| \n3 4 0 |{3}| \n3 5 0 |{7}| \n4 5 0 |{6}| \n5 1 0 |{foo}|"""
G = nx.parse_leda(data)
G = nx.parse_leda(data.split("\n"))
assert sorted(G.nodes()) == ["v1", "v2", "v3", "v4", "v5"]
assert sorted(G.edges(data=True)) == [
("v1", "v2", {"label": "4"}),
("v1", "v3", {"label": "3"}),
("v2", "v3", {"label": "2"}),
("v3", "v4", {"label": "3"}),
("v3", "v5", {"label": "7"}),
("v4", "v5", {"label": "6"}),
("v5", "v1", {"label": "foo"}),
]
def test_read_LEDA(self):
fh = io.BytesIO()
data = """#header section \nLEDA.GRAPH \nstring\nint\n-1\n#nodes section\n5 \n|{v1}| \n|{v2}| \n|{v3}| \n|{v4}| \n|{v5}| \n\n#edges section\n7 \n1 2 0 |{4}| \n1 3 0 |{3}| \n2 3 0 |{2}| \n3 4 0 |{3}| \n3 5 0 |{7}| \n4 5 0 |{6}| \n5 1 0 |{foo}|"""
G = nx.parse_leda(data)
fh.write(data.encode("UTF-8"))
fh.seek(0)
Gin = nx.read_leda(fh)
assert sorted(G.nodes()) == sorted(Gin.nodes())
assert sorted(G.edges()) == sorted(Gin.edges())

View file

@ -0,0 +1,61 @@
import networkx as nx
import io
from networkx.readwrite.p2g import read_p2g, write_p2g
from networkx.testing import assert_edges_equal
class TestP2G:
@classmethod
def setup_class(cls):
cls.G = nx.Graph(name="test")
e = [("a", "b"), ("b", "c"), ("c", "d"), ("d", "e"), ("e", "f"), ("a", "f")]
cls.G.add_edges_from(e)
cls.G.add_node("g")
cls.DG = nx.DiGraph(cls.G)
def test_read_p2g(self):
s = b"""\
name
3 4
a
1 2
b
c
0 2
"""
bytesIO = io.BytesIO(s)
G = read_p2g(bytesIO)
assert G.name == "name"
assert sorted(G) == ["a", "b", "c"]
edges = [(str(u), str(v)) for u, v in G.edges()]
assert_edges_equal(G.edges(), [("a", "c"), ("a", "b"), ("c", "a"), ("c", "c")])
def test_write_p2g(self):
s = b"""foo
3 2
1
1
2
2
3
"""
fh = io.BytesIO()
G = nx.OrderedDiGraph()
G.name = "foo"
G.add_edges_from([(1, 2), (2, 3)])
write_p2g(G, fh)
fh.seek(0)
r = fh.read()
assert r == s
def test_write_read_p2g(self):
fh = io.BytesIO()
G = nx.DiGraph()
G.name = "foo"
G.add_edges_from([("a", "b"), ("b", "c")])
write_p2g(G, fh)
fh.seek(0)
H = read_p2g(fh)
assert_edges_equal(G.edges(), H.edges())

View file

@ -0,0 +1,129 @@
"""
Pajek tests
"""
import networkx as nx
import os
import tempfile
from networkx.testing import assert_edges_equal, assert_nodes_equal
class TestPajek:
@classmethod
def setup_class(cls):
cls.data = """*network Tralala\n*vertices 4\n 1 "A1" 0.0938 0.0896 ellipse x_fact 1 y_fact 1\n 2 "Bb" 0.8188 0.2458 ellipse x_fact 1 y_fact 1\n 3 "C" 0.3688 0.7792 ellipse x_fact 1\n 4 "D2" 0.9583 0.8563 ellipse x_fact 1\n*arcs\n1 1 1 h2 0 w 3 c Blue s 3 a1 -130 k1 0.6 a2 -130 k2 0.6 ap 0.5 l "Bezier loop" lc BlueViolet fos 20 lr 58 lp 0.3 la 360\n2 1 1 h2 0 a1 120 k1 1.3 a2 -120 k2 0.3 ap 25 l "Bezier arc" lphi 270 la 180 lr 19 lp 0.5\n1 2 1 h2 0 a1 40 k1 2.8 a2 30 k2 0.8 ap 25 l "Bezier arc" lphi 90 la 0 lp 0.65\n4 2 -1 h2 0 w 1 k1 -2 k2 250 ap 25 l "Circular arc" c Red lc OrangeRed\n3 4 1 p Dashed h2 0 w 2 c OliveGreen ap 25 l "Straight arc" lc PineGreen\n1 3 1 p Dashed h2 0 w 5 k1 -1 k2 -20 ap 25 l "Oval arc" c Brown lc Black\n3 3 -1 h1 6 w 1 h2 12 k1 -2 k2 -15 ap 0.5 l "Circular loop" c Red lc OrangeRed lphi 270 la 180"""
cls.G = nx.MultiDiGraph()
cls.G.add_nodes_from(["A1", "Bb", "C", "D2"])
cls.G.add_edges_from(
[
("A1", "A1"),
("A1", "Bb"),
("A1", "C"),
("Bb", "A1"),
("C", "C"),
("C", "D2"),
("D2", "Bb"),
]
)
cls.G.graph["name"] = "Tralala"
(fd, cls.fname) = tempfile.mkstemp()
with os.fdopen(fd, "wb") as fh:
fh.write(cls.data.encode("UTF-8"))
@classmethod
def teardown_class(cls):
os.unlink(cls.fname)
def test_parse_pajek_simple(self):
# Example without node positions or shape
data = """*Vertices 2\n1 "1"\n2 "2"\n*Edges\n1 2\n2 1"""
G = nx.parse_pajek(data)
assert sorted(G.nodes()) == ["1", "2"]
assert_edges_equal(G.edges(), [("1", "2"), ("1", "2")])
def test_parse_pajek(self):
G = nx.parse_pajek(self.data)
assert sorted(G.nodes()) == ["A1", "Bb", "C", "D2"]
assert_edges_equal(
G.edges(),
[
("A1", "A1"),
("A1", "Bb"),
("A1", "C"),
("Bb", "A1"),
("C", "C"),
("C", "D2"),
("D2", "Bb"),
],
)
def test_parse_pajet_mat(self):
data = """*Vertices 3\n1 "one"\n2 "two"\n3 "three"\n*Matrix\n1 1 0\n0 1 0\n0 1 0\n"""
G = nx.parse_pajek(data)
assert set(G.nodes()) == {"one", "two", "three"}
assert G.nodes["two"] == {"id": "2"}
assert_edges_equal(
set(G.edges()),
{("one", "one"), ("two", "one"), ("two", "two"), ("two", "three")},
)
def test_read_pajek(self):
G = nx.parse_pajek(self.data)
Gin = nx.read_pajek(self.fname)
assert sorted(G.nodes()) == sorted(Gin.nodes())
assert_edges_equal(G.edges(), Gin.edges())
assert self.G.graph == Gin.graph
for n in G:
assert G.nodes[n] == Gin.nodes[n]
def test_write_pajek(self):
import io
G = nx.parse_pajek(self.data)
fh = io.BytesIO()
nx.write_pajek(G, fh)
fh.seek(0)
H = nx.read_pajek(fh)
assert_nodes_equal(list(G), list(H))
assert_edges_equal(list(G.edges()), list(H.edges()))
# Graph name is left out for now, therefore it is not tested.
# assert_equal(G.graph, H.graph)
def test_ignored_attribute(self):
import io
G = nx.Graph()
fh = io.BytesIO()
G.add_node(1, int_attr=1)
G.add_node(2, empty_attr=" ")
G.add_edge(1, 2, int_attr=2)
G.add_edge(2, 3, empty_attr=" ")
import warnings
with warnings.catch_warnings(record=True) as w:
nx.write_pajek(G, fh)
assert len(w) == 4
def test_noname(self):
# Make sure we can parse a line such as: *network
# Issue #952
line = "*network\n"
other_lines = self.data.split("\n")[1:]
data = line + "\n".join(other_lines)
G = nx.parse_pajek(data)
def test_unicode(self):
import io
G = nx.Graph()
name1 = chr(2344) + chr(123) + chr(6543)
name2 = chr(5543) + chr(1543) + chr(324)
G.add_edge(name1, "Radiohead", foo=name2)
fh = io.BytesIO()
nx.write_pajek(G, fh)
fh.seek(0)
H = nx.read_pajek(fh)
assert_nodes_equal(list(G), list(H))
assert_edges_equal(list(G.edges()), list(H.edges()))
assert G.graph == H.graph

View file

@ -0,0 +1,287 @@
"""Unit tests for shp.
"""
import os
import tempfile
import pytest
ogr = pytest.importorskip("osgeo.ogr")
import networkx as nx
class TestShp:
def setup_method(self):
def createlayer(driver, layerType=ogr.wkbLineString):
lyr = driver.CreateLayer("edges", None, layerType)
namedef = ogr.FieldDefn("Name", ogr.OFTString)
namedef.SetWidth(32)
lyr.CreateField(namedef)
return lyr
drv = ogr.GetDriverByName("ESRI Shapefile")
testdir = os.path.join(tempfile.gettempdir(), "shpdir")
shppath = os.path.join(tempfile.gettempdir(), "tmpshp.shp")
multi_shppath = os.path.join(tempfile.gettempdir(), "tmp_mshp.shp")
self.deletetmp(drv, testdir, shppath, multi_shppath)
os.mkdir(testdir)
self.names = ["a", "b", "c", "c"] # edgenames
self.paths = (
[(1.0, 1.0), (2.0, 2.0)],
[(2.0, 2.0), (3.0, 3.0)],
[(0.9, 0.9), (4.0, 0.9), (4.0, 2.0)],
)
self.simplified_names = ["a", "b", "c"] # edgenames
self.simplified_paths = (
[(1.0, 1.0), (2.0, 2.0)],
[(2.0, 2.0), (3.0, 3.0)],
[(0.9, 0.9), (4.0, 2.0)],
)
self.multi_names = ["a", "a", "a", "a"] # edgenames
shp = drv.CreateDataSource(shppath)
lyr = createlayer(shp)
for path, name in zip(self.paths, self.names):
feat = ogr.Feature(lyr.GetLayerDefn())
g = ogr.Geometry(ogr.wkbLineString)
for p in path:
g.AddPoint_2D(*p)
feat.SetGeometry(g)
feat.SetField("Name", name)
lyr.CreateFeature(feat)
# create single record multiline shapefile for testing
multi_shp = drv.CreateDataSource(multi_shppath)
multi_lyr = createlayer(multi_shp, ogr.wkbMultiLineString)
multi_g = ogr.Geometry(ogr.wkbMultiLineString)
for path in self.paths:
g = ogr.Geometry(ogr.wkbLineString)
for p in path:
g.AddPoint_2D(*p)
multi_g.AddGeometry(g)
multi_feat = ogr.Feature(multi_lyr.GetLayerDefn())
multi_feat.SetGeometry(multi_g)
multi_feat.SetField("Name", "a")
multi_lyr.CreateFeature(multi_feat)
self.shppath = shppath
self.multi_shppath = multi_shppath
self.testdir = testdir
self.drv = drv
def deletetmp(self, drv, *paths):
for p in paths:
if os.path.exists(p):
drv.DeleteDataSource(p)
def testload(self):
def compare_graph_paths_names(g, paths, names):
expected = nx.DiGraph()
for p in paths:
nx.add_path(expected, p)
assert sorted(expected.nodes) == sorted(g.nodes)
assert sorted(expected.edges()) == sorted(g.edges())
g_names = [g.get_edge_data(s, e)["Name"] for s, e in g.edges()]
assert names == sorted(g_names)
# simplified
G = nx.read_shp(self.shppath)
compare_graph_paths_names(G, self.simplified_paths, self.simplified_names)
# unsimplified
G = nx.read_shp(self.shppath, simplify=False)
compare_graph_paths_names(G, self.paths, self.names)
# multiline unsimplified
G = nx.read_shp(self.multi_shppath, simplify=False)
compare_graph_paths_names(G, self.paths, self.multi_names)
def checkgeom(self, lyr, expected):
feature = lyr.GetNextFeature()
actualwkt = []
while feature:
actualwkt.append(feature.GetGeometryRef().ExportToWkt())
feature = lyr.GetNextFeature()
assert sorted(expected) == sorted(actualwkt)
def test_geometryexport(self):
expectedpoints_simple = (
"POINT (1 1)",
"POINT (2 2)",
"POINT (3 3)",
"POINT (0.9 0.9)",
"POINT (4 2)",
)
expectedlines_simple = (
"LINESTRING (1 1,2 2)",
"LINESTRING (2 2,3 3)",
"LINESTRING (0.9 0.9,4.0 0.9,4 2)",
)
expectedpoints = (
"POINT (1 1)",
"POINT (2 2)",
"POINT (3 3)",
"POINT (0.9 0.9)",
"POINT (4.0 0.9)",
"POINT (4 2)",
)
expectedlines = (
"LINESTRING (1 1,2 2)",
"LINESTRING (2 2,3 3)",
"LINESTRING (0.9 0.9,4.0 0.9)",
"LINESTRING (4.0 0.9,4 2)",
)
tpath = os.path.join(tempfile.gettempdir(), "shpdir")
G = nx.read_shp(self.shppath)
nx.write_shp(G, tpath)
shpdir = ogr.Open(tpath)
self.checkgeom(shpdir.GetLayerByName("nodes"), expectedpoints_simple)
self.checkgeom(shpdir.GetLayerByName("edges"), expectedlines_simple)
# Test unsimplified
# Nodes should have additional point,
# edges should be 'flattened'
G = nx.read_shp(self.shppath, simplify=False)
nx.write_shp(G, tpath)
shpdir = ogr.Open(tpath)
self.checkgeom(shpdir.GetLayerByName("nodes"), expectedpoints)
self.checkgeom(shpdir.GetLayerByName("edges"), expectedlines)
def test_attributeexport(self):
def testattributes(lyr, graph):
feature = lyr.GetNextFeature()
while feature:
coords = []
ref = feature.GetGeometryRef()
last = ref.GetPointCount() - 1
edge_nodes = (ref.GetPoint_2D(0), ref.GetPoint_2D(last))
name = feature.GetFieldAsString("Name")
assert graph.get_edge_data(*edge_nodes)["Name"] == name
feature = lyr.GetNextFeature()
tpath = os.path.join(tempfile.gettempdir(), "shpdir")
G = nx.read_shp(self.shppath)
nx.write_shp(G, tpath)
shpdir = ogr.Open(tpath)
edges = shpdir.GetLayerByName("edges")
testattributes(edges, G)
# Test export of node attributes in nx.write_shp (#2778)
def test_nodeattributeexport(self):
tpath = os.path.join(tempfile.gettempdir(), "shpdir")
G = nx.DiGraph()
A = (0, 0)
B = (1, 1)
C = (2, 2)
G.add_edge(A, B)
G.add_edge(A, C)
label = "node_label"
for n, d in G.nodes(data=True):
d["label"] = label
nx.write_shp(G, tpath)
H = nx.read_shp(tpath)
for n, d in H.nodes(data=True):
assert d["label"] == label
def test_wkt_export(self):
G = nx.DiGraph()
tpath = os.path.join(tempfile.gettempdir(), "shpdir")
points = ("POINT (0.9 0.9)", "POINT (4 2)")
line = ("LINESTRING (0.9 0.9,4 2)",)
G.add_node(1, Wkt=points[0])
G.add_node(2, Wkt=points[1])
G.add_edge(1, 2, Wkt=line[0])
try:
nx.write_shp(G, tpath)
except Exception as e:
assert False, e
shpdir = ogr.Open(tpath)
self.checkgeom(shpdir.GetLayerByName("nodes"), points)
self.checkgeom(shpdir.GetLayerByName("edges"), line)
def teardown_method(self):
self.deletetmp(self.drv, self.testdir, self.shppath)
def test_read_shp_nofile():
with pytest.raises(RuntimeError):
G = nx.read_shp("hopefully_this_file_will_not_be_available")
class TestMissingGeometry:
def setup_method(self):
self.setup_path()
self.delete_shapedir()
self.create_shapedir()
def teardown_method(self):
self.delete_shapedir()
def setup_path(self):
self.path = os.path.join(tempfile.gettempdir(), "missing_geometry")
def create_shapedir(self):
drv = ogr.GetDriverByName("ESRI Shapefile")
shp = drv.CreateDataSource(self.path)
lyr = shp.CreateLayer("nodes", None, ogr.wkbPoint)
feature = ogr.Feature(lyr.GetLayerDefn())
feature.SetGeometry(None)
lyr.CreateFeature(feature)
feature.Destroy()
def delete_shapedir(self):
drv = ogr.GetDriverByName("ESRI Shapefile")
if os.path.exists(self.path):
drv.DeleteDataSource(self.path)
def test_missing_geometry(self):
with pytest.raises(nx.NetworkXError):
G = nx.read_shp(self.path)
class TestMissingAttrWrite:
def setup_method(self):
self.setup_path()
self.delete_shapedir()
def teardown_method(self):
self.delete_shapedir()
def setup_path(self):
self.path = os.path.join(tempfile.gettempdir(), "missing_attributes")
def delete_shapedir(self):
drv = ogr.GetDriverByName("ESRI Shapefile")
if os.path.exists(self.path):
drv.DeleteDataSource(self.path)
def test_missing_attributes(self):
G = nx.DiGraph()
A = (0, 0)
B = (1, 1)
C = (2, 2)
G.add_edge(A, B, foo=100)
G.add_edge(A, C)
nx.write_shp(G, self.path)
H = nx.read_shp(self.path)
for u, v, d in H.edges(data=True):
if u == A and v == B:
assert d["foo"] == 100
if u == A and v == C:
assert d["foo"] is None

View file

@ -0,0 +1,173 @@
from io import BytesIO
import tempfile
import pytest
import networkx as nx
from networkx.testing.utils import assert_edges_equal
from networkx.testing.utils import assert_nodes_equal
class TestSparseGraph6:
def test_from_sparse6_bytes(self):
data = b":Q___eDcdFcDeFcE`GaJ`IaHbKNbLM"
G = nx.from_sparse6_bytes(data)
assert_nodes_equal(
sorted(G.nodes()),
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17],
)
assert_edges_equal(
G.edges(),
[
(0, 1),
(0, 2),
(0, 3),
(1, 12),
(1, 14),
(2, 13),
(2, 15),
(3, 16),
(3, 17),
(4, 7),
(4, 9),
(4, 11),
(5, 6),
(5, 8),
(5, 9),
(6, 10),
(6, 11),
(7, 8),
(7, 10),
(8, 12),
(9, 15),
(10, 14),
(11, 13),
(12, 16),
(13, 17),
(14, 17),
(15, 16),
],
)
def test_from_bytes_multigraph_graph(self):
graph_data = b":An"
G = nx.from_sparse6_bytes(graph_data)
assert type(G) == nx.Graph
multigraph_data = b":Ab"
M = nx.from_sparse6_bytes(multigraph_data)
assert type(M) == nx.MultiGraph
def test_read_sparse6(self):
data = b":Q___eDcdFcDeFcE`GaJ`IaHbKNbLM"
G = nx.from_sparse6_bytes(data)
fh = BytesIO(data)
Gin = nx.read_sparse6(fh)
assert_nodes_equal(G.nodes(), Gin.nodes())
assert_edges_equal(G.edges(), Gin.edges())
def test_read_many_graph6(self):
# Read many graphs into list
data = b":Q___eDcdFcDeFcE`GaJ`IaHbKNbLM\n" b":Q___dCfDEdcEgcbEGbFIaJ`JaHN`IM"
fh = BytesIO(data)
glist = nx.read_sparse6(fh)
assert len(glist) == 2
for G in glist:
assert_nodes_equal(
G.nodes(),
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17],
)
class TestWriteSparse6:
"""Unit tests for writing graphs in the sparse6 format.
Most of the test cases were checked against the sparse6 encoder in Sage.
"""
def test_null_graph(self):
G = nx.null_graph()
result = BytesIO()
nx.write_sparse6(G, result)
assert result.getvalue() == b">>sparse6<<:?\n"
def test_trivial_graph(self):
G = nx.trivial_graph()
result = BytesIO()
nx.write_sparse6(G, result)
assert result.getvalue() == b">>sparse6<<:@\n"
def test_empty_graph(self):
G = nx.empty_graph(5)
result = BytesIO()
nx.write_sparse6(G, result)
assert result.getvalue() == b">>sparse6<<:D\n"
def test_large_empty_graph(self):
G = nx.empty_graph(68)
result = BytesIO()
nx.write_sparse6(G, result)
assert result.getvalue() == b">>sparse6<<:~?@C\n"
def test_very_large_empty_graph(self):
G = nx.empty_graph(258049)
result = BytesIO()
nx.write_sparse6(G, result)
assert result.getvalue() == b">>sparse6<<:~~???~?@\n"
def test_complete_graph(self):
G = nx.complete_graph(4)
result = BytesIO()
nx.write_sparse6(G, result)
assert result.getvalue() == b">>sparse6<<:CcKI\n"
def test_no_header(self):
G = nx.complete_graph(4)
result = BytesIO()
nx.write_sparse6(G, result, header=False)
assert result.getvalue() == b":CcKI\n"
def test_padding(self):
codes = (b":Cdv", b":DaYn", b":EaYnN", b":FaYnL", b":GaYnLz")
for n, code in enumerate(codes, start=4):
G = nx.path_graph(n)
result = BytesIO()
nx.write_sparse6(G, result, header=False)
assert result.getvalue() == code + b"\n"
def test_complete_bipartite(self):
G = nx.complete_bipartite_graph(6, 9)
result = BytesIO()
nx.write_sparse6(G, result)
# Compared with sage
expected = b">>sparse6<<:Nk" + b"?G`cJ" * 9 + b"\n"
assert result.getvalue() == expected
def test_read_write_inverse(self):
for i in list(range(13)) + [31, 47, 62, 63, 64, 72]:
m = min(2 * i, i * i // 2)
g = nx.random_graphs.gnm_random_graph(i, m, seed=i)
gstr = BytesIO()
nx.write_sparse6(g, gstr, header=False)
# Strip the trailing newline.
gstr = gstr.getvalue().rstrip()
g2 = nx.from_sparse6_bytes(gstr)
assert g2.order() == g.order()
assert_edges_equal(g2.edges(), g.edges())
def test_no_directed_graphs(self):
with pytest.raises(nx.NetworkXNotImplemented):
nx.write_sparse6(nx.DiGraph(), BytesIO())
def test_write_path(self):
# On Windows, we can't reopen a file that is open
# So, for test we get a valid name from tempfile but close it.
with tempfile.NamedTemporaryFile() as f:
fullfilename = f.name
# file should be closed now, so write_sparse6 can open it
nx.write_sparse6(nx.null_graph(), fullfilename)
fh = open(fullfilename, mode="rb")
assert fh.read() == b">>sparse6<<:?\n"
fh.close()
import os
os.remove(fullfilename)

View file

@ -0,0 +1,50 @@
"""
Unit tests for yaml.
"""
import os
import tempfile
import pytest
yaml = pytest.importorskip("yaml")
import networkx as nx
from networkx.testing import assert_edges_equal, assert_nodes_equal
class TestYaml:
@classmethod
def setup_class(cls):
cls.build_graphs()
@classmethod
def build_graphs(cls):
cls.G = nx.Graph(name="test")
e = [("a", "b"), ("b", "c"), ("c", "d"), ("d", "e"), ("e", "f"), ("a", "f")]
cls.G.add_edges_from(e)
cls.G.add_node("g")
cls.DG = nx.DiGraph(cls.G)
cls.MG = nx.MultiGraph()
cls.MG.add_weighted_edges_from([(1, 2, 5), (1, 2, 5), (1, 2, 1), (3, 3, 42)])
def assert_equal(self, G, data=False):
(fd, fname) = tempfile.mkstemp()
nx.write_yaml(G, fname)
Gin = nx.read_yaml(fname)
assert_nodes_equal(list(G), list(Gin))
assert_edges_equal(G.edges(data=data), Gin.edges(data=data))
os.close(fd)
os.unlink(fname)
def testUndirected(self):
self.assert_equal(self.G, data=False)
def testDirected(self):
self.assert_equal(self.DG, data=False)
def testMultiGraph(self):
self.assert_equal(self.MG, data=True)