Repository URL to install this package:
|
Version:
2.1 ▾
|
#!/usr/bin/env python
# encoding: utf-8
from ast import literal_eval
import codecs
import io
from nose.tools import *
from nose import SkipTest
import networkx as nx
from networkx.readwrite.gml import literal_stringizer, literal_destringizer
import os
import tempfile
try:
unicode
except NameError:
unicode = str
try:
unichr
except NameError:
unichr = chr
class TestGraph(object):
def setUp(self):
self.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_equals(sorted(G.nodes()),
['Node 1', 'Node 2', 'Node 3'])
assert_equals([e for e in sorted(G.edges())],
[('Node 1', 'Node 2'),
('Node 2', 'Node 3'),
('Node 3', 'Node 1')])
assert_equals([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_equals(sorted(G.nodes(data=True)), sorted(Gin.nodes(data=True)))
assert_equals(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_equal(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)
assert_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_equal(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: ' + unichr(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 "quoted" and this is a copyright: ©"
]
]"""
assert_equal(data, answer)
def test_unicode_node(self):
node = 'node' + unichr(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©"
]
]"""
assert_equal(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_equal(data, answer)
def test_name(self):
G = nx.parse_gml('graph [ name "x" node [ id 0 label "x" ] ]')
assert_equal('x', G.graph['name'])
G = nx.parse_gml('graph [ node [ id 0 label "x" ] ]')
assert_equal('', G.name)
assert_not_in('name', 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_equal(bool(directed), G.is_directed())
assert_equal(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_equal(gml, '\n'.join(nx.generate_gml(G)))
def test_data_types(self):
data = [True, False, 10 ** 20, -2e33, "'", '"&&&""',
[{(b'\xfd',): '\x7f', unichr(0x4444): (1, 2)}, (2, "3")]]
try:
data.append(unichr(0x14444)) # fails under IronPython
except ValueError:
data.append(unichr(0x1444))
try:
data.append(literal_eval('{2.3j, 1 - 2.3j, ()}')) # fails under Python 2.7
except ValueError:
data.append([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_equal(data, G.name)
assert_equal({'name': data, unicode('data'): data}, G.graph)
assert_equal(list(G.nodes(data=True)),
[(0, dict(int=-1, data=dict(data=data)))])
assert_equal(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_equal(G.graph['data'], 'frozenset([1, 2, 3])')
def test_escape_unescape(self):
gml = """graph [
name "&"䑄��&unknown;"
]"""
G = nx.parse_gml(gml)
assert_equal(
'&"\x0f' + unichr(0x4444) + '��&unknown;',
G.name)
gml = '\n'.join(nx.generate_gml(G))
assert_equal("""graph [
name "&"䑄��&unknown;"
]""", gml)
def test_exceptions(self):
assert_raises(ValueError, literal_destringizer, '(')
assert_raises(ValueError, literal_destringizer, 'frozenset([1, 2, 3])')
assert_raises(ValueError, literal_destringizer, literal_destringizer)
assert_raises(ValueError, literal_stringizer, frozenset([1, 2, 3]))
assert_raises(ValueError, literal_stringizer, literal_stringizer)
with tempfile.TemporaryFile() as f:
f.write(codecs.BOM_UTF8 + 'graph[]'.encode('ascii'))
f.seek(0)
assert_raises(nx.NetworkXError, nx.read_gml, f)
def assert_parse_error(gml):
assert_raises(nx.NetworkXError, nx.parse_gml, gml)
assert_parse_error(['graph [\n\n', unicode(']')])
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 ]')
def assert_generate_error(*args, **kwargs):
assert_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)