diff options
Diffstat (limited to 'networkx')
-rw-r--r-- | networkx/readwrite/graphml.py | 23 | ||||
-rw-r--r-- | networkx/readwrite/tests/test_graphml.py | 36 |
2 files changed, 53 insertions, 6 deletions
diff --git a/networkx/readwrite/graphml.py b/networkx/readwrite/graphml.py index bb70a0d7..589173dc 100644 --- a/networkx/readwrite/graphml.py +++ b/networkx/readwrite/graphml.py @@ -447,6 +447,17 @@ class GraphML: 1: True, } + def get_xml_type(self, key): + """Wrapper around the xml_type dict that raises a more informative + exception message when a user attempts to use data of a type not + supported by GraphML.""" + try: + return self.xml_type[key] + except KeyError as e: + raise TypeError( + f"GraphML does not support type {type(key)} as data values." + ) from e + class GraphMLWriter(GraphML): def __init__( @@ -504,7 +515,7 @@ class GraphMLWriter(GraphML): types = self.attribute_types[(name, scope)] if len(types) > 1: - types = {self.xml_type[t] for t in types} + types = {self.get_xml_type(t) for t in types} if "string" in types: return str elif "float" in types or "double" in types: @@ -551,7 +562,7 @@ class GraphMLWriter(GraphML): raise nx.NetworkXError( f"GraphML writer does not support {element_type} as data values." ) - keyid = self.get_key(name, self.xml_type[element_type], scope, default) + keyid = self.get_key(name, self.get_xml_type(element_type), scope, default) data_element = self.myElement("data", key=keyid) data_element.text = str(value) return data_element @@ -765,7 +776,7 @@ class GraphMLWriterLxml(GraphMLWriter): for k, v in graphdata.items(): self.attribute_types[(str(k), "graph")].add(type(v)) for k, v in graphdata.items(): - element_type = self.xml_type[self.attr_type(k, "graph", v)] + element_type = self.get_xml_type(self.attr_type(k, "graph", v)) self.get_key(str(k), element_type, "graph", None) # Nodes and data for node, d in G.nodes(data=True): @@ -773,7 +784,7 @@ class GraphMLWriterLxml(GraphMLWriter): self.attribute_types[(str(k), "node")].add(type(v)) for node, d in G.nodes(data=True): for k, v in d.items(): - T = self.xml_type[self.attr_type(k, "node", v)] + T = self.get_xml_type(self.attr_type(k, "node", v)) self.get_key(str(k), T, "node", node_default.get(k)) # Edges and data if G.is_multigraph(): @@ -782,7 +793,7 @@ class GraphMLWriterLxml(GraphMLWriter): self.attribute_types[(str(k), "edge")].add(type(v)) for u, v, ekey, d in G.edges(keys=True, data=True): for k, v in d.items(): - T = self.xml_type[self.attr_type(k, "edge", v)] + T = self.get_xml_type(self.attr_type(k, "edge", v)) self.get_key(str(k), T, "edge", edge_default.get(k)) else: for u, v, d in G.edges(data=True): @@ -790,7 +801,7 @@ class GraphMLWriterLxml(GraphMLWriter): self.attribute_types[(str(k), "edge")].add(type(v)) for u, v, d in G.edges(data=True): for k, v in d.items(): - T = self.xml_type[self.attr_type(k, "edge", v)] + T = self.get_xml_type(self.attr_type(k, "edge", v)) self.get_key(str(k), T, "edge", edge_default.get(k)) # Now add attribute keys to the xml file diff --git a/networkx/readwrite/tests/test_graphml.py b/networkx/readwrite/tests/test_graphml.py index 4e6064a2..c97d07cc 100644 --- a/networkx/readwrite/tests/test_graphml.py +++ b/networkx/readwrite/tests/test_graphml.py @@ -1500,3 +1500,39 @@ class TestXMLGraphML(TestWriteGraphML): @classmethod def setup_class(cls): TestWriteGraphML.setup_class() + + +def test_exception_for_unsupported_datatype_node_attr(): + """Test that a detailed exception is raised when an attribute is of a type + not supported by GraphML, e.g. a list""" + pytest.importorskip("lxml.etree") + # node attribute + G = nx.Graph() + G.add_node(0, my_list_attribute=[0, 1, 2]) + fh = io.BytesIO() + with pytest.raises(TypeError, match="GraphML does not support"): + nx.write_graphml(G, fh) + + +def test_exception_for_unsupported_datatype_edge_attr(): + """Test that a detailed exception is raised when an attribute is of a type + not supported by GraphML, e.g. a list""" + pytest.importorskip("lxml.etree") + # edge attribute + G = nx.Graph() + G.add_edge(0, 1, my_list_attribute=[0, 1, 2]) + fh = io.BytesIO() + with pytest.raises(TypeError, match="GraphML does not support"): + nx.write_graphml(G, fh) + + +def test_exception_for_unsupported_datatype_graph_attr(): + """Test that a detailed exception is raised when an attribute is of a type + not supported by GraphML, e.g. a list""" + pytest.importorskip("lxml.etree") + # graph attribute + G = nx.Graph() + G.graph["my_list_attribute"] = [0, 1, 2] + fh = io.BytesIO() + with pytest.raises(TypeError, match="GraphML does not support"): + nx.write_graphml(G, fh) |