jonaschn: @dschult What do you think?
dschult: This looks like a good approach to me. Can you add a test to make sure we don't mess it up with future changes? Perhaps the example you show above?  Thanks!
diff --git a/networkx/classes/multigraph.py b/networkx/classes/multigraph.py
index d3685b14c..fd939f559 100644
--- a/networkx/classes/multigraph.py
+++ b/networkx/classes/multigraph.py
@@ -520,10 +520,10 @@ class MultiGraph(Graph):
             ddd.update(attr)
             try:
                 ddd.update(dd)
-            except:
+            except (TypeError, ValueError):
                 if ne != 3:
                     raise
-                key = dd
+                key = dd  # ne == 3 with 3rd value not dict, must be a key
             key = self.add_edge(u, v, key)
             self[u][v][key].update(ddd)
             keylist.append(key)
diff --git a/networkx/readwrite/gexf.py b/networkx/readwrite/gexf.py
index 3f5d5ed1c..b69c4ae72 100644
--- a/networkx/readwrite/gexf.py
+++ b/networkx/readwrite/gexf.py
@@ -400,6 +400,11 @@ class GEXFWriter(GEXF):
         edges_element = Element("edges")
         for u, v, key, edge_data in edge_key_data(G):
             kw = {"id": str(key)}
+            try:
+                edge_label = edge_data.pop("label")
+                kw["label"] = str(edge_label)
+            except KeyError:
+                pass
             try:
                 edge_weight = edge_data.pop("weight")
                 kw["weight"] = str(edge_weight)
diff --git a/networkx/readwrite/graphml.py b/networkx/readwrite/graphml.py
index df4982c44..47b8d46d3 100644
--- a/networkx/readwrite/graphml.py
+++ b/networkx/readwrite/graphml.py
@@ -196,7 +196,7 @@ def generate_graphml(G, encoding="utf-8", prettyprint=True, named_key_ids=False)
 
 
 @open_file(0, mode="rb")
-def read_graphml(path, node_type=str, edge_key_type=int):
+def read_graphml(path, node_type=str, edge_key_type=int, force_multigraph=False):
     """Read graph in GraphML format from path.
 
     Parameters
@@ -209,14 +209,19 @@ def read_graphml(path, node_type=str, edge_key_type=int):
        Convert node ids to this type
 
     edge_key_type: Python type (default: int)
-       Convert graphml edge ids to this type as key of multi-edges
+       Convert graphml edge ids to this type. Multigraphs use id as edge key.
+       Non-multigraphs add to edge attribute dict with name "id".
 
+    force_multigraph : bool (default: False)
+       If True, return a multigraph with edge keys. If False (the default)
+       return a multigraph when multiedges are in the graph.
 
     Returns
     -------
     graph: NetworkX graph
-        If no parallel edges are found a Graph or DiGraph is returned.
-        Otherwise a MultiGraph or MultiDiGraph is returned.
+        If parallel edges are present or `force_multigraph == True```then
+        a MultiGraph or MultiDiGraph is returned. Otherwise a Graph/DiGraph.
+        The returned graph is directed if the file indicates it should be.
 
     Notes
     -----
@@ -248,7 +253,7 @@ def read_graphml(path, node_type=str, edge_key_type=int):
     the file to "file.graphml.gz".
 
     """
-    reader = GraphMLReader(node_type=node_type, edge_key_type=edge_key_type)
+    reader = GraphMLReader(node_type, edge_key_type, force_multigraph)
     # need to check for multiple graphs
     glist = list(reader(path=path))
     if len(glist) == 0:
@@ -263,7 +268,9 @@ def read_graphml(path, node_type=str, edge_key_type=int):
     return glist[0]
 
 
-def parse_graphml(graphml_string, node_type=str):
+def parse_graphml(
+    graphml_string, node_type=str, edge_key_type=int, force_multigraph=False
+):
     """Read graph in GraphML format from string.
 
     Parameters
@@ -275,6 +282,15 @@ def parse_graphml(graphml_string, node_type=str):
     node_type: Python type (default: str)
        Convert node ids to this type
 
+    edge_key_type: Python type (default: int)
+       Convert graphml edge ids to this type. Multigraphs use id as edge key.
+       Non-multigraphs add to edge attribute dict with name "id".
+
+    force_multigraph : bool (default: False)
+       If True, return a multigraph with edge keys. If False (the default)
+       return a multigraph when multiedges are in the graph.
+
+
     Returns
     -------
     graph: NetworkX graph
@@ -312,7 +328,7 @@ def parse_graphml(graphml_string, node_type=str):
     will be provided.
 
     """
-    reader = GraphMLReader(node_type=node_type)
+    reader = GraphMLReader(node_type, edge_key_type, force_multigraph)
     # need to check for multiple graphs
     glist = list(reader(string=graphml_string))
     if len(glist) == 0:
@@ -743,11 +759,11 @@ else:
 class GraphMLReader(GraphML):
     """Read a GraphML document.  Produces NetworkX graph objects."""
 
-    def __init__(self, node_type=str, edge_key_type=int):
+    def __init__(self, node_type=str, edge_key_type=int, force_multigraph=False):
         self.node_type = node_type
         self.edge_key_type = edge_key_type
-        self.multigraph = False  # assume multigraph and test for multiedges
-        self.edge_ids = {}  # dict mapping (u,v) tuples to id edge attributes
+        self.multigraph = force_multigraph  # If False, test for multiedges
+        self.edge_ids = {}  # dict mapping (u,v) tuples to edge id attributes
 
     def __call__(self, path=None, string=None):
         if path is not None:
@@ -793,14 +809,13 @@ class GraphMLReader(GraphML):
         data = self.decode_data_elements(graphml_keys, graph_xml)
         G.graph.update(data)
 
-        # switch to Graph or DiGraph if no parallel edges were found.
-        if not self.multigraph:
-            if G.is_directed():
-                G = nx.DiGraph(G)
-            else:
-                G = nx.Graph(G)
-            nx.set_edge_attributes(G, values=self.edge_ids, name="id")
+        # switch to Graph or DiGraph if no parallel edges were found
+        if self.multigraph:
+            return G
 
+        G = nx.DiGraph(G) if G.is_directed() else nx.Graph(G)
+        # add explicit edge "id" from file as attribute in NX graph.
+        nx.set_edge_attributes(G, values=self.edge_ids, name="id")
         return G
 
     def add_node(self, G, node_xml, graphml_keys, defaults):
@@ -859,6 +874,7 @@ class GraphMLReader(GraphML):
             self.multigraph = True
 
         # Use add_edges_from to avoid error with add_edge when `'key' in data`
+        # Note there is only one edge here...
         G.add_edges_from([(source, target, edge_id, data)])
 
     def decode_data_elements(self, graphml_keys, obj_xml):
diff --git a/requirements/doc.txt b/requirements/doc.txt
index cfe9e90d6..54a77b1f2 100644
--- a/requirements/doc.txt
+++ b/requirements/doc.txt
@@ -1,4 +1,4 @@
-sphinx==3.1.2
+sphinx==3.2.1
 sphinx_rtd_theme==0.5.0
 sphinx-gallery==0.7.0
 pillow>=7.2.0

Missing edge label attribute in GEXFWriter
According to the [GEXF specification ](https://gephi.org/gexf/1.2draft/gexf-12draft-primer.pdf):

> Each edge can have a optional XML-attribute label, which is a string.

The [specification 1.2draft](https://github.com/gephi/gexf/blob/81ba4e7ccdc25631f836fc5caa4ed64ba5300379/specs/1.2draft/data.xsd#L73) defines this attribute as:
`<xs:attribute name="label" type="xs:token"/>`

The GEXF writer doesn't recognize this attribute correctly.
Instead it creates a new data attribute like:
```
		<attributes class="edge" mode="static">
			<attribute id="0" title="label" type="string"/>
		</attributes>
``` 
diff --git a/networkx/readwrite/tests/test_gexf.py b/networkx/readwrite/tests/test_gexf.py
index 4a2663218..9b43794b1 100644
--- a/networkx/readwrite/tests/test_gexf.py
+++ b/networkx/readwrite/tests/test_gexf.py
@@ -78,7 +78,7 @@ org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.gexf.net/\
       </node>
     </nodes>
     <edges>
-      <edge id="0" source="0" target="1"/>
+      <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"/>
@@ -105,7 +105,7 @@ org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.gexf.net/\
             indegree=1,
             frog=True,
         )
-        cls.attribute_graph.add_edge("0", "1", id="0")
+        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")
@@ -573,7 +573,8 @@ gexf.net/1.2draft http://www.gexf.net/1.2draft/gexf.xsd" version="1.2">
         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", weight=3, type="undirected", start=0, end=1)
+        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)
diff --git a/networkx/readwrite/tests/test_graphml.py b/networkx/readwrite/tests/test_graphml.py
index f59f2bd53..39ea907d1 100644
--- a/networkx/readwrite/tests/test_graphml.py
+++ b/networkx/readwrite/tests/test_graphml.py
@@ -44,6 +44,7 @@ class BaseGraphML:
         cls.simple_directed_graph = nx.DiGraph()
         cls.simple_directed_graph.add_node("n10")
         cls.simple_directed_graph.add_edge("n0", "n2", id="foo")
+        cls.simple_directed_graph.add_edge("n0", "n2")
         cls.simple_directed_graph.add_edges_from(
             [
                 ("n1", "n2"),
@@ -207,6 +208,75 @@ class BaseGraphML:
         fh = io.BytesIO(cls.simple_undirected_data.encode("UTF-8"))
         cls.simple_undirected_fh = fh
 
+        cls.undirected_multigraph_data = """<?xml version="1.0" encoding="UTF-8"?>
+<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
+         http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
+  <graph id="G">
+    <node id="n0"/>
+    <node id="n1"/>
+    <node id="n2"/>
+    <node id="n10"/>
+    <edge id="e0" source="n0" target="n2"/>
+    <edge id="e1" source="n1" target="n2"/>
+    <edge id="e2" source="n2" target="n1"/>
+  </graph>
+</graphml>"""
+        cls.undirected_multigraph = nx.MultiGraph()
+        cls.undirected_multigraph.add_node("n10")
+        cls.undirected_multigraph.add_edge("n0", "n2", id="e0")
+        cls.undirected_multigraph.add_edge("n1", "n2", id="e1")
+        cls.undirected_multigraph.add_edge("n2", "n1", id="e2")
+        fh = io.BytesIO(cls.undirected_multigraph_data.encode("UTF-8"))
+        cls.undirected_multigraph_fh = fh
+
+        cls.undirected_multigraph_no_multiedge_data = """<?xml version="1.0" encoding="UTF-8"?>
+<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
+         http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
+  <graph id="G">
+    <node id="n0"/>
+    <node id="n1"/>
+    <node id="n2"/>
+    <node id="n10"/>
+    <edge id="e0" source="n0" target="n2"/>
+    <edge id="e1" source="n1" target="n2"/>
+    <edge id="e2" source="n2" target="n3"/>
+  </graph>
+</graphml>"""
+        cls.undirected_multigraph_no_multiedge = nx.MultiGraph()
+        cls.undirected_multigraph_no_multiedge.add_node("n10")
+        cls.undirected_multigraph_no_multiedge.add_edge("n0", "n2", id="e0")
+        cls.undirected_multigraph_no_multiedge.add_edge("n1", "n2", id="e1")
+        cls.undirected_multigraph_no_multiedge.add_edge("n2", "n3", id="e2")
+        fh = io.BytesIO(cls.undirected_multigraph_no_multiedge_data.encode("UTF-8"))
+        cls.undirected_multigraph_no_multiedge_fh = fh
+
+        cls.multigraph_only_ids_for_multiedges_data = """<?xml version="1.0" encoding="UTF-8"?>
+<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
+         http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
+  <graph id="G">
+    <node id="n0"/>
+    <node id="n1"/>
+    <node id="n2"/>
+    <node id="n10"/>
+    <edge source="n0" target="n2"/>
+    <edge id="e1" source="n1" target="n2"/>
+    <edge id="e2" source="n2" target="n1"/>
+  </graph>
+</graphml>"""
+        cls.multigraph_only_ids_for_multiedges = nx.MultiGraph()
+        cls.multigraph_only_ids_for_multiedges.add_node("n10")
+        cls.multigraph_only_ids_for_multiedges.add_edge("n0", "n2")
+        cls.multigraph_only_ids_for_multiedges.add_edge("n1", "n2", id="e1")
+        cls.multigraph_only_ids_for_multiedges.add_edge("n2", "n1", id="e2")
+        fh = io.BytesIO(cls.multigraph_only_ids_for_multiedges_data.encode("UTF-8"))
+        cls.multigraph_only_ids_for_multiedges_fh = fh
+
 
 class TestReadGraphML(BaseGraphML):
     def test_read_simple_directed_graphml(self):
@@ -217,10 +287,10 @@ class TestReadGraphML(BaseGraphML):
         assert sorted(G.edges(data=True)) == sorted(H.edges(data=True))
         self.simple_directed_fh.seek(0)
 
-        I = nx.parse_graphml(self.simple_directed_data)
-        assert sorted(G.nodes()) == sorted(I.nodes())
-        assert sorted(G.edges()) == sorted(I.edges())
-        assert sorted(G.edges(data=True)) == sorted(I.edges(data=True))
+        PG = nx.parse_graphml(self.simple_directed_data)
+        assert sorted(G.nodes()) == sorted(PG.nodes())
+        assert sorted(G.edges()) == sorted(PG.edges())
+        assert sorted(G.edges(data=True)) == sorted(PG.edges(data=True))
 
     def test_read_simple_undirected_graphml(self):
         G = self.simple_undirected_graph
@@ -229,9 +299,42 @@ class TestReadGraphML(BaseGraphML):
         assert_edges_equal(G.edges(), H.edges())
         self.simple_undirected_fh.seek(0)
 
-        I = nx.parse_graphml(self.simple_undirected_data)
-        assert_nodes_equal(G.nodes(), I.nodes())
-        assert_edges_equal(G.edges(), I.edges())
+        PG = nx.parse_graphml(self.simple_undirected_data)
+        assert_nodes_equal(G.nodes(), PG.nodes())
+        assert_edges_equal(G.edges(), PG.edges())
+
+    def test_read_undirected_multigraph_graphml(self):
+        G = self.undirected_multigraph
+        H = nx.read_graphml(self.undirected_multigraph_fh)
+        assert_nodes_equal(G.nodes(), H.nodes())
+        assert_edges_equal(G.edges(), H.edges())
+        self.undirected_multigraph_fh.seek(0)
+
+        PG = nx.parse_graphml(self.undirected_multigraph_data)
+        assert_nodes_equal(G.nodes(), PG.nodes())
+        assert_edges_equal(G.edges(), PG.edges())
+
+    def test_read_undirected_multigraph_no_multiedge_graphml(self):
+        G = self.undirected_multigraph_no_multiedge
+        H = nx.read_graphml(self.undirected_multigraph_no_multiedge_fh)
+        assert_nodes_equal(G.nodes(), H.nodes())
+        assert_edges_equal(G.edges(), H.edges())
+        self.undirected_multigraph_no_multiedge_fh.seek(0)
+
+        PG = nx.parse_graphml(self.undirected_multigraph_no_multiedge_data)
+        assert_nodes_equal(G.nodes(), PG.nodes())
+        assert_edges_equal(G.edges(), PG.edges())
+
+    def test_read_undirected_multigraph_only_ids_for_multiedges_graphml(self):
+        G = self.multigraph_only_ids_for_multiedges
+        H = nx.read_graphml(self.multigraph_only_ids_for_multiedges_fh)
+        assert_nodes_equal(G.nodes(), H.nodes())
+        assert_edges_equal(G.edges(), H.edges())
+        self.multigraph_only_ids_for_multiedges_fh.seek(0)
+
+        PG = nx.parse_graphml(self.multigraph_only_ids_for_multiedges_data)
+        assert_nodes_equal(G.nodes(), PG.nodes())
+        assert_edges_equal(G.edges(), PG.edges())
 
     def test_read_attribute_graphml(self):
         G = self.attribute_graph
@@ -243,10 +346,10 @@ class TestReadGraphML(BaseGraphML):
             assert a == b
         self.attribute_fh.seek(0)
 
-        I = nx.parse_graphml(self.attribute_data)
-        assert sorted(G.nodes(True)) == sorted(I.nodes(data=True))
+        PG = nx.parse_graphml(self.attribute_data)
+        assert sorted(G.nodes(True)) == sorted(PG.nodes(data=True))
         ge = sorted(G.edges(data=True))
-        he = sorted(I.edges(data=True))
+        he = sorted(PG.edges(data=True))
         for a, b in zip(ge, he):
             assert a == b
 
@@ -396,6 +499,22 @@ class TestReadGraphML(BaseGraphML):
         assert_edges_equal(G.edges(data=True, keys=True), H.edges(data=True, keys=True))
         assert G._adj == H._adj
 
+        Gadj = {
+            str(node): {
+                str(nbr): {str(ekey): dd for ekey, dd in key_dict.items()}
+                for nbr, key_dict in nbr_dict.items()
+            }
+            for node, nbr_dict in G._adj.items()
+        }
+        fh.seek(0)
+        HH = nx.read_graphml(fh, node_type=str, edge_key_type=str)
+        assert Gadj == HH._adj
+
+        fh.seek(0)
+        string_fh = fh.read()
+        HH = nx.parse_graphml(string_fh, node_type=str, edge_key_type=str)
+        assert Gadj == HH._adj
+
     def test_yfiles_extension(self):
         data = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
@@ -465,12 +584,24 @@ class TestReadGraphML(BaseGraphML):
 </graphml>
 """
         fh = io.BytesIO(data.encode("UTF-8"))
+        G = nx.read_graphml(fh, force_multigraph=True)
+        assert list(G.edges()) == [("n0", "n1")]
+        assert G.has_edge("n0", "n1", key="e0")
+        assert G.nodes["n0"]["label"] == "1"
+        assert G.nodes["n1"]["label"] == "2"
+        fh.seek(0)
         G = nx.read_graphml(fh)
         assert list(G.edges()) == [("n0", "n1")]
         assert G["n0"]["n1"]["id"] == "e0"
         assert G.nodes["n0"]["label"] == "1"
         assert G.nodes["n1"]["label"] == "2"
 
+        H = nx.parse_graphml(data, force_multigraph=True)
+        assert list(H.edges()) == [("n0", "n1")]
+        assert H.has_edge("n0", "n1", key="e0")
+        assert H.nodes["n0"]["label"] == "1"
+        assert H.nodes["n1"]["label"] == "2"
+
         H = nx.parse_graphml(data)
         assert list(H.edges()) == [("n0", "n1")]
         assert H["n0"]["n1"]["id"] == "e0"
@@ -1010,6 +1141,17 @@ class TestWriteGraphML(BaseGraphML):
         assert not H.edges["n0", "n1", 0]["special"]
         assert H.edges["n0", "n1", 1]["special"] == 0
 
+    def test_numpy_float(self):
+        np = pytest.importorskip("numpy")
+        wt = np.float(3.4)
+        G = nx.Graph([(1, 2, {"weight": wt})])
+        fd, fname = tempfile.mkstemp()
+        self.writer(G, fname)
+        H = nx.read_graphml(fname, node_type=int)
+        assert G._adj == H._adj
+        os.close(fd)
+        os.unlink(fname)
+
     def test_multigraph_to_graph(self):
         # test converting multigraph to graph if no parallel edges found
         G = nx.MultiGraph()
@@ -1018,17 +1160,19 @@ class TestWriteGraphML(BaseGraphML):
         self.writer(G, fname)
         H = nx.read_graphml(fname)
         assert not H.is_multigraph()
+        H = nx.read_graphml(fname, force_multigraph=True)
+        assert H.is_multigraph()
         os.close(fd)
         os.unlink(fname)
 
-    def test_numpy_float(self):
-        np = pytest.importorskip("numpy")
-        wt = np.float(3.4)
-        G = nx.Graph([(1, 2, {"weight": wt})])
+        # add a multiedge
+        G.add_edge("a", "b", "e-id")
         fd, fname = tempfile.mkstemp()
         self.writer(G, fname)
-        H = nx.read_graphml(fname, node_type=int)
-        assert G._adj == H._adj
+        H = nx.read_graphml(fname)
+        assert H.is_multigraph()
+        H = nx.read_graphml(fname, force_multigraph=True)
+        assert H.is_multigraph()
         os.close(fd)
         os.unlink(fname)
 

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest cython distro pytest-cov pytest-xdist pytest-mock pytest-asyncio pytest-bdd pytest-benchmark pytest-randomly responses mock hypothesis freezegun trustme requests-mock requests tomlkit
apt-get update apt-get install -y gcc
3.9
requirements/default.txt requirements/test.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==25.3.0
certifi==2025.1.31
cffi==1.17.1
charset-normalizer==3.4.1
codecov==2.1.13
coverage==7.8.0
cryptography==44.0.2
Cython==3.0.12
decorator==5.2.1
distro==1.9.0
exceptiongroup==1.2.2
execnet==2.1.1
freezegun==1.5.1
gherkin-official==29.0.0
hypothesis==6.130.5
idna==3.10
importlib_metadata==8.6.1
iniconfig==2.1.0
Mako==1.3.9
MarkupSafe==3.0.2
mock==5.2.0
-e git+https://github.com/networkx/networkx.git@19cd86c254ebf4a889fddc171ba166187fb72890#egg=networkx
packaging==24.2
parse==1.20.2
parse_type==0.6.4
pluggy==1.5.0
py-cpuinfo==9.0.0
pycparser==2.22
pytest==8.3.5
pytest-asyncio==0.26.0
pytest-bdd==8.1.0
pytest-benchmark==5.1.0
pytest-cov==6.0.0
pytest-mock==3.14.0
pytest-randomly==3.16.0
pytest-xdist==3.6.1
python-dateutil==2.9.0.post0
PyYAML==6.0.2
requests==2.32.3
requests-mock==1.12.1
responses==0.25.7
six==1.17.0
sortedcontainers==2.4.0
tomli==2.2.1
tomlkit==0.13.2
trustme==1.2.1
typing_extensions==4.13.0
urllib3==2.3.0
zipp==3.21.0

name: networkx
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==25.3.0
      - certifi==2025.1.31
      - cffi==1.17.1
      - charset-normalizer==3.4.1
      - codecov==2.1.13
      - coverage==7.8.0
      - cryptography==44.0.2
      - cython==3.0.12
      - decorator==5.2.1
      - distro==1.9.0
      - exceptiongroup==1.2.2
      - execnet==2.1.1
      - freezegun==1.5.1
      - gherkin-official==29.0.0
      - hypothesis==6.130.5
      - idna==3.10
      - importlib-metadata==8.6.1
      - iniconfig==2.1.0
      - mako==1.3.9
      - markupsafe==3.0.2
      - mock==5.2.0
      - packaging==24.2
      - parse==1.20.2
      - parse-type==0.6.4
      - pluggy==1.5.0
      - py-cpuinfo==9.0.0
      - pycparser==2.22
      - pytest==8.3.5
      - pytest-asyncio==0.26.0
      - pytest-bdd==8.1.0
      - pytest-benchmark==5.1.0
      - pytest-cov==6.0.0
      - pytest-mock==3.14.0
      - pytest-randomly==3.16.0
      - pytest-xdist==3.6.1
      - python-dateutil==2.9.0.post0
      - pyyaml==6.0.2
      - requests==2.32.3
      - requests-mock==1.12.1
      - responses==0.25.7
      - six==1.17.0
      - sortedcontainers==2.4.0
      - tomli==2.2.1
      - tomlkit==0.13.2
      - trustme==1.2.1
      - typing-extensions==4.13.0
      - urllib3==2.3.0
      - zipp==3.21.0
prefix: /opt/conda/envs/networkx

networkx/readwrite/tests/test_graphml.py::TestReadGraphML::test_preserve_multi_edge_data networkx/readwrite/tests/test_graphml.py::TestReadGraphML::test_yfiles_extension
networkx/readwrite/tests/test_gexf.py::TestGEXF::test_read_attribute_graphml networkx/readwrite/tests/test_gexf.py::TestGEXF::test_write_with_node_attributes networkx/readwrite/tests/test_gexf.py::TestGEXF::test_directed_edge_in_undirected networkx/readwrite/tests/test_gexf.py::TestGEXF::test_numpy_type networkx/readwrite/tests/test_gexf.py::TestGEXF::test_default_attribute networkx/readwrite/tests/test_gexf.py::TestGEXF::test_bool networkx/readwrite/tests/test_gexf.py::TestGEXF::test_missing_viz_attributes networkx/readwrite/tests/test_gexf.py::TestGEXF::test_edge_id_construct networkx/readwrite/tests/test_gexf.py::TestGEXF::test_slice_and_spell networkx/readwrite/tests/test_gexf.py::TestGEXF::test_multigraph_with_missing_attributes networkx/readwrite/tests/test_gexf.py::TestGEXF::test_key_raises networkx/readwrite/tests/test_gexf.py::TestGEXF::test_add_parent networkx/readwrite/tests/test_gexf.py::TestGEXF::test_specials networkx/readwrite/tests/test_gexf.py::TestGEXF::test_serialize_ints_to_strings networkx/readwrite/tests/test_gexf.py::TestGEXF::test_write_read_simple_directed_graphml networkx/readwrite/tests/test_gexf.py::TestGEXF::test_relabel networkx/readwrite/tests/test_gexf.py::TestGEXF::test_undirected_edge_in_directed networkx/readwrite/tests/test_gexf.py::TestGEXF::test_read_simple_undirected_graphml networkx/readwrite/tests/test_gexf.py::TestGEXF::test_dynamic_mode networkx/readwrite/tests/test_gexf.py::TestGEXF::test_read_simple_directed_graphml networkx/readwrite/tests/test_gexf.py::TestGEXF::test_simple_list networkx/readwrite/tests/test_graphml.py::TestReadGraphML::test_read_undirected_multigraph_only_ids_for_multiedges_graphml networkx/readwrite/tests/test_graphml.py::TestReadGraphML::test_key_raise networkx/readwrite/tests/test_graphml.py::TestReadGraphML::test_graphml_header_line networkx/readwrite/tests/test_graphml.py::TestReadGraphML::test_read_undirected_multigraph_no_multiedge_graphml networkx/readwrite/tests/test_graphml.py::TestReadGraphML::test_read_attribute_graphml networkx/readwrite/tests/test_graphml.py::TestReadGraphML::test_bool networkx/readwrite/tests/test_graphml.py::TestReadGraphML::test_hyperedge_raise networkx/readwrite/tests/test_graphml.py::TestReadGraphML::test_multigraph_keys networkx/readwrite/tests/test_graphml.py::TestReadGraphML::test_read_simple_directed_graphml networkx/readwrite/tests/test_graphml.py::TestReadGraphML::test_undirected_edge_in_directed networkx/readwrite/tests/test_graphml.py::TestReadGraphML::test_read_simple_undirected_graphml networkx/readwrite/tests/test_graphml.py::TestReadGraphML::test_read_undirected_multigraph_graphml networkx/readwrite/tests/test_graphml.py::TestReadGraphML::test_read_attributes_with_groups networkx/readwrite/tests/test_graphml.py::TestReadGraphML::test_directed_edge_in_undirected
networkx/readwrite/gexf.py requirements/doc.txt networkx/classes/multigraph.py networkx/readwrite/graphml.py
networkx/readwrite/gexf.py requirements/doc.txt networkx/classes/multigraph.py networkx/readwrite/graphml.py