Repository: networkx/networkx

Issue:
keys added as edge attributes when using nx.from_pandas_edgelist
Hi there,
regarding the nx.from_pandas_edgelist function, when creating multigraphs:

### Current Behavior

Following the example in the documentation, but calling "edge_attr = True" instead of "edge_attr=["weight", "color"]", the edge keys get added to the graph not only as keys, but also as edge attributes.
i.e G.edges(data=True) outputs:
`MultiEdgeDataView([(0, 2, {'my_edge_key': 'A', 'weight': 3, 'color': 'red'}), (0, 2, {'my_edge_key': 'D', 'weight': 6, 'color': 'blue'}), (2, 1, {'my_edge_key': 'B', 'weight': 4, 'color': 'blue'}), (2, 3, {'my_edge_key': 'C', 'weight': 5, 'color': 'blue'})])`
I do not think this is intended behavior, as edge keys are not edge attributes. 
In other words If we start with a multigraph and save it to a pandas edgelist using `nx.to_pandas_edgelist()`, the graph we load from that same edgelist in this way has an extra attribute (my_edge_key).

### Expected Behavior
keys should only be added as keys, as is what happens when you manually specify which columns are edge_attr.

### Steps to Reproduce

`edges = pd.DataFrame(
    {
        "source": [0, 1, 2, 0],
        "target": [2, 2, 3, 2],
        "my_edge_key": ["A", "B", "C", "D"],
        "weight": [3, 4, 5, 6],
        "color": ["red", "blue", "blue", "blue"],
    }
)`

`
G = nx.from_pandas_edgelist(
    edges,
    edge_key="my_edge_key",
    edge_attr=["weight", "color"],
    create_using=nx.MultiGraph(),
)
`

### Environment

NetworkX version: 3.2.1



Discussion:

Patch:
diff --git a/networkx/convert_matrix.py b/networkx/convert_matrix.py
index d4c924a85..12017fe26 100644
--- a/networkx/convert_matrix.py
+++ b/networkx/convert_matrix.py
@@ -348,7 +348,7 @@ def from_pandas_edgelist(
     edge_attr : str or int, iterable, True, or None
         A valid column name (str or int) or iterable of column names that are
         used to retrieve items and add them to the graph as edge attributes.
-        If `True`, all of the remaining columns will be added.
+        If `True`, all columns will be added except `source`, `target` and `edge_key`.
         If `None`, no edge attributes are added to the graph.
 
     create_using : NetworkX graph constructor, optional (default=nx.Graph)
@@ -436,6 +436,8 @@ def from_pandas_edgelist(
         return g
 
     reserved_columns = [source, target]
+    if g.is_multigraph() and edge_key is not None:
+        reserved_columns.append(edge_key)
 
     # Additional columns requested
     attr_col_headings = []
diff --git a/pyproject.toml b/pyproject.toml
index 39d760349..a7759cfed 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -77,7 +77,7 @@ doc = [
 ]
 extra = [
     'lxml>=4.6',
-    'pygraphviz>=1.12',
+    'pygraphviz>=1.13',
     'pydot>=2.0',
     'sympy>=1.10',
 ]
diff --git a/requirements/extra.txt b/requirements/extra.txt
index ad08057f4..e21b8bfce 100644
--- a/requirements/extra.txt
+++ b/requirements/extra.txt
@@ -1,6 +1,6 @@
 # Generated via tools/generate_requirements.py and pre-commit hook.
 # Do not edit this file; modify pyproject.toml instead.
 lxml>=4.6
-pygraphviz>=1.12
+pygraphviz>=1.13
 pydot>=2.0
 sympy>=1.10


Test patch:
diff --git a/networkx/tests/test_convert_pandas.py b/networkx/tests/test_convert_pandas.py
index 7076eb57a..594fcab7d 100644
--- a/networkx/tests/test_convert_pandas.py
+++ b/networkx/tests/test_convert_pandas.py
@@ -241,7 +241,8 @@ class TestConvertPandas:
         df = nx.to_pandas_adjacency(G, dtype=np.intp)
         pd.testing.assert_frame_equal(df, dftrue)
 
-    def test_edgekey_with_multigraph(self):
+    @pytest.mark.parametrize("edge_attr", [["attr2", "attr3"], True])
+    def test_edgekey_with_multigraph(self, edge_attr):
         df = pd.DataFrame(
             {
                 "source": {"A": "N1", "B": "N2", "C": "N1", "D": "N1"},
@@ -264,7 +265,7 @@ class TestConvertPandas:
             df,
             source="source",
             target="target",
-            edge_attr=["attr2", "attr3"],
+            edge_attr=edge_attr,
             edge_key="attr1",
             create_using=nx.MultiGraph(),
         )