Repository: networkx/networkx

Issue:
Executing other's people version.py when importing
When I import networkx inside my project it imports my local `version.py` (from `release.py` ).

For example, if I put in my root a `version.py` that looks like
```python
raise RuntimeError('ahhhh!!!')
```

I will get the following stack trace

```
Traceback (most recent call last):
  File "<censured>/venv/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3417, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-2-719b05231e1b>", line 1, in <module>
    import networkx
  File "<censured>/pycharm-2020.1/plugins/python/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 21, in do_import
    module = self._system_import(name, *args, **kwargs)
  File "<censured>/venv/lib/python3.8/site-packages/networkx/__init__.py", line 19, in <module>
    from networkx import release
  File "/<censured>/pycharm-2020.1/plugins/python/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 21, in do_import
    module = self._system_import(name, *args, **kwargs)
  File "<censured>/venv/lib/python3.8/site-packages/networkx/release.py", line 224, in <module>
    date, date_info, version, version_info, vcs_info = get_info()
  File "<censured>/venv/lib/python3.8/site-packages/networkx/release.py", line 151, in get_info
    from version import date, date_info, version, version_info, vcs_info
  File "<censured>/pycharm-2020.1/plugins/python/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 21, in do_import
    module = self._system_import(name, *args, **kwargs)
  File "<censured>/git/storepick-dataset-creation/version.py", line 1, in <module>
    raise RuntimeError('ahhhh!!!')
RuntimeError: ahhhh!!!
```

Discussion:
rossbar: Oops - I missed the linked issue. This fix might not actually work though as the `release` module is also used to populate the `setup.py` info prior to install.
Nao83: My thinking is that it would still work when running `setup.py`. I am not sure now, I'll have to try it tomorrow.

If you have an idea on how to avoid calling this from __init__ that would be better.
jarrodmillman: I think this should work as well, but I would like to look into it more.  @Nao83 it would be great if you could let's us know what you find out.



Patch:
diff --git a/README.rst b/README.rst
index 1cd369686..114cf7265 100644
--- a/README.rst
+++ b/README.rst
@@ -7,8 +7,8 @@ NetworkX
 .. image:: https://img.shields.io/pypi/pyversions/networkx.svg
    :target: https://pypi.org/project/networkx/
 
-.. image:: https://travis-ci.org/networkx/networkx.svg?branch=master
-   :target: https://travis-ci.org/networkx/networkx
+.. image:: https://travis-ci.com/networkx/networkx.svg?branch=master
+   :target: https://travis-ci.com/networkx/networkx
 
 .. image:: https://github.com/networkx/networkx/workflows/macOS%20tests/badge.svg?branch=master
   :target: https://github.com/networkx/networkx/actions?query=workflow%3A%22macOS+tests%22
diff --git a/doc/developer/deprecations.rst b/doc/developer/deprecations.rst
index 146044c8d..6b07c130f 100644
--- a/doc/developer/deprecations.rst
+++ b/doc/developer/deprecations.rst
@@ -58,3 +58,5 @@ Version 3.0
 * In ``algorithms/community_modularity_max.py`` remove old name ``_naive_greedy_modularity_communities``.
 * In ``linalg/algebraicconnectivity.py`` remove ``_CholeskySolver`` and related code.
 * In ``convert_matrix.py`` remove ``to_numpy_matrix`` and ``from_numpy_matrix``.
+* Remove ``networkx/readwrite/nx_yaml.py`` and related tests.
+* Remove ``networkx/readwrite/gpickle.py`` and related tests. 
diff --git a/doc/release/release_dev.rst b/doc/release/release_dev.rst
index b24561fce..903588cae 100644
--- a/doc/release/release_dev.rst
+++ b/doc/release/release_dev.rst
@@ -37,13 +37,17 @@ Deprecations
 ------------
 
 - [`#4238 <https://github.com/networkx/networkx/pull/4238>`_]
-  Deprecate `to_numpy_matrix` and `from_numpy_matrix`.
+  Deprecate ``to_numpy_matrix`` and ``from_numpy_matrix``.
 - [`#4279 <https://github.com/networkx/networkx/pull/4279>`_]
   Deprecate ``networkx.utils.misc.is_iterator``.
   Use ``isinstance(obj, collections.abc.Iterator)`` instead.
 - [`#4280 <https://github.com/networkx/networkx/pull/4280>`_]
   Deprecate ``networkx.utils.misc.is_list_of_ints`` as it is no longer used.
   See ``networkx.utils.misc.make_list_of_ints`` for related functionality.
+- [`#4281 <https://github.com/networkx/networkx/pull/4281>`_]
+  Deprecate ``read_yaml`` and ``write_yaml``.
+- [`#4282 <https://github.com/networkx/networkx/pull/4282>`_]
+  Deprecate ``read_gpickle`` and ``write_gpickle``.
 
 Contributors to this release
 ----------------------------
diff --git a/examples/basic/plot_simple_graph.py b/examples/basic/plot_simple_graph.py
new file mode 100644
index 000000000..fcd7caf6b
--- /dev/null
+++ b/examples/basic/plot_simple_graph.py
@@ -0,0 +1,60 @@
+"""
+============
+Simple graph
+============
+
+Draw simple graph with manual layout.
+"""
+
+import networkx as nx
+import matplotlib.pyplot as plt
+
+G = nx.Graph()
+G.add_edge(1, 2)
+G.add_edge(1, 3)
+G.add_edge(1, 5)
+G.add_edge(2, 3)
+G.add_edge(3, 4)
+G.add_edge(4, 5)
+
+# explicitly set positions
+pos = {1: (0, 0), 2: (-1, 0.3), 3: (2, 0.17), 4: (4, 0.255), 5: (5, 0.03)}
+
+options = {
+    "font_size": 36,
+    "node_size": 3000,
+    "node_color": "white",
+    "edgecolors": "black",
+    "linewidths": 5,
+    "width": 5,
+}
+nx.draw_networkx(G, pos, **options)
+
+# Set margins for the axes so that nodes aren't clipped
+ax = plt.gca()
+ax.margins(0.20)
+plt.axis("off")
+plt.show()
+
+# %%
+# A directed graph
+
+G = nx.DiGraph([(0, 3), (1, 3), (2, 4), (3, 5), (3, 6), (4, 6), (5, 6)])
+
+# group nodes by column
+left_nodes = [0, 1, 2]
+middle_nodes = [3, 4]
+right_nodes = [5, 6]
+
+# set the position according to column (x-coord)
+pos = {n: (0, i) for i, n in enumerate(left_nodes)}
+pos.update({n: (1, i + 0.5) for i, n in enumerate(middle_nodes)})
+pos.update({n: (2, i + 0.5) for i, n in enumerate(right_nodes)})
+
+nx.draw_networkx(G, pos, **options)
+
+# Set margins for the axes so that nodes aren't clipped
+ax = plt.gca()
+ax.margins(0.20)
+plt.axis("off")
+plt.show()
diff --git a/networkx/algorithms/dag.py b/networkx/algorithms/dag.py
index 0d4c68f41..c33837d06 100644
--- a/networkx/algorithms/dag.py
+++ b/networkx/algorithms/dag.py
@@ -110,9 +110,10 @@ def is_directed_acyclic_graph(G):
 def topological_sort(G):
     """Returns a generator of nodes in topologically sorted order.
 
-    A topological sort is a nonunique permutation of the nodes such that an
-    edge from u to v implies that u appears before v in the topological sort
-    order.
+    A topological sort is a nonunique permutation of the nodes of a
+    directed graph such that an edge from u to v implies that u
+    appears before v in the topological sort order. This ordering is
+    valid only if the graph has no directed cycles.
 
     Parameters
     ----------
diff --git a/networkx/classes/reportviews.py b/networkx/classes/reportviews.py
index 3d77d92a0..c03093567 100644
--- a/networkx/classes/reportviews.py
+++ b/networkx/classes/reportviews.py
@@ -83,6 +83,7 @@ EdgeDataView
     The argument `nbunch` restricts edges to those incident to nodes in nbunch.
 """
 from collections.abc import Mapping, Set
+import networkx as nx
 
 __all__ = [
     "NodeView",
@@ -184,6 +185,10 @@ class NodeView(Mapping, Set):
         return iter(self._nodes)
 
     def __getitem__(self, n):
+        if isinstance(n, slice):
+            raise nx.NetworkXError(
+                f"NodeView does not support slicing, try list(G.nodes)[{n.start}:{n.stop}]"
+            )
         return self._nodes[n]
 
     # Set methods
@@ -284,6 +289,10 @@ class NodeDataView(Set):
         return n in self._nodes and self[n] == d
 
     def __getitem__(self, n):
+        if isinstance(n, slice):
+            raise nx.NetworkXError(
+                f"NodeDataView does not support slicing, try list(G.nodes.data())[{n.start}:{n.stop}]"
+            )
         ddict = self._nodes[n]
         data = self._data
         if data is False or data is True:
@@ -1012,6 +1021,10 @@ class OutEdgeView(Set, Mapping):
 
     # Mapping Methods
     def __getitem__(self, e):
+        if isinstance(e, slice):
+            raise nx.NetworkXError(
+                f"EdgeView does not support slicing, try list(G.edges)[{e.start}:{e.stop}]"
+            )
         u, v = e
         return self._adjdict[u][v]
 
@@ -1197,6 +1210,10 @@ class OutMultiEdgeView(OutEdgeView):
             return False
 
     def __getitem__(self, e):
+        if isinstance(e, slice):
+            raise nx.NetworkXError(
+                f"OutMultiEdgeView does not support slicing, try list(G.nodes)[{e.start}:{e.stop}]"
+            )
         u, v, k = e
         return self._adjdict[u][v][k]
 
diff --git a/networkx/readwrite/gpickle.py b/networkx/readwrite/gpickle.py
index 9f8cd1d51..cee8b273b 100644
--- a/networkx/readwrite/gpickle.py
+++ b/networkx/readwrite/gpickle.py
@@ -26,6 +26,7 @@ __all__ = ["read_gpickle", "write_gpickle"]
 from networkx.utils import open_file
 
 import pickle
+import warnings
 
 
 @open_file(1, mode="wb")
@@ -55,7 +56,14 @@ def write_gpickle(G, path, protocol=pickle.HIGHEST_PROTOCOL):
     References
     ----------
     .. [1] https://docs.python.org/3/library/pickle.html
+
+    .. deprecated:: 2.6
     """
+    msg = (
+        "write_gpickle is deprecated and will be removed in 3.0."
+        "Use ``pickle.dump(G, path, protocol)``"
+    )
+    warnings.warn(msg, DeprecationWarning, stacklevel=2)
     pickle.dump(G, path, protocol)
 
 
@@ -86,5 +94,12 @@ def read_gpickle(path):
     References
     ----------
     .. [1] https://docs.python.org/3/library/pickle.html
+
+    .. deprecated:: 2.6
     """
+    msg = (
+        "read_gpickle is deprecated and will be removed in 3.0."
+        "Use ``pickle.load(path)``"
+    )
+    warnings.warn(msg, DeprecationWarning, stacklevel=2)
     return pickle.load(path)
diff --git a/networkx/readwrite/nx_yaml.py b/networkx/readwrite/nx_yaml.py
index a8b763800..294922eaa 100644
--- a/networkx/readwrite/nx_yaml.py
+++ b/networkx/readwrite/nx_yaml.py
@@ -16,6 +16,7 @@ http://pyyaml.org/wiki/PyYAML
 
 __all__ = ["read_yaml", "write_yaml"]
 
+import warnings
 from networkx.utils import open_file
 
 
@@ -47,7 +48,14 @@ def write_yaml(G_to_be_yaml, path_for_yaml_output, **kwds):
     References
     ----------
     .. [1] http://www.yaml.org
+
+    .. deprecated:: 2.6
     """
+    msg = (
+        "write_yaml is deprecated and will be removed in 3.0."
+        "Use ``yaml.dump(G_to_be_yaml, path_for_yaml_output, **kwds)``"
+    )
+    warnings.warn(msg, DeprecationWarning, stacklevel=2)
     try:
         import yaml
     except ImportError as e:
@@ -82,7 +90,13 @@ def read_yaml(path):
     ----------
     .. [1] http://www.yaml.org
 
+    .. deprecated:: 2.6
     """
+    msg = (
+        "read_yaml is deprecated and will be removed in 3.0."
+        "Use ``yaml.load(path, Loader=yaml.FullLoader)``"
+    )
+    warnings.warn(msg, DeprecationWarning, stacklevel=2)
     try:
         import yaml
     except ImportError as e:
diff --git a/networkx/relabel.py b/networkx/relabel.py
index 424a8289d..068b1653e 100644
--- a/networkx/relabel.py
+++ b/networkx/relabel.py
@@ -4,7 +4,7 @@ __all__ = ["convert_node_labels_to_integers", "relabel_nodes"]
 
 
 def relabel_nodes(G, mapping, copy=True):
-    """Relabel the nodes of the graph G.
+    """Relabel the nodes of the graph G according to a given mapping.
 
     Parameters
     ----------
diff --git a/networkx/release.py b/networkx/release.py
index 9794716da..17dc97714 100644
--- a/networkx/release.py
+++ b/networkx/release.py
@@ -148,7 +148,13 @@ def get_info(dynamic=True):
         # no vcs information will be provided.
         # sys.path.insert(0, basedir)
         try:
-            from version import date, date_info, version, version_info, vcs_info
+            from networkx.version import (
+                date,
+                date_info,
+                version,
+                version_info,
+                vcs_info,
+            )
         except ImportError:
             import_failed = True
             vcs_info = (None, (None, None))


Test patch:
diff --git a/networkx/classes/tests/test_reportviews.py b/networkx/classes/tests/test_reportviews.py
index 704e43ab6..678a99f2c 100644
--- a/networkx/classes/tests/test_reportviews.py
+++ b/networkx/classes/tests/test_reportviews.py
@@ -41,6 +41,9 @@ class TestNodeView:
         G.nodes[3]["foo"] = "bar"
         assert nv[7] == {}
         assert nv[3] == {"foo": "bar"}
+        # slicing
+        with pytest.raises(nx.NetworkXError):
+            G.nodes[0:5]
 
     def test_iter(self):
         nv = self.nv
@@ -128,6 +131,9 @@ class TestNodeDataView:
         nwv_def = G.nodes(data="foo", default="biz")
         assert nwv_def[7], "biz"
         assert nwv_def[3] == "bar"
+        # slicing
+        with pytest.raises(nx.NetworkXError):
+            G.nodes.data()[0:5]
 
     def test_iter(self):
         G = self.G.copy()
@@ -579,6 +585,16 @@ class TestEdgeView:
         )
         assert repr(ev) == rep
 
+    def test_getitem(self):
+        G = self.G.copy()
+        ev = G.edges
+        G.edges[0, 1]["foo"] = "bar"
+        assert ev[0, 1] == {"foo": "bar"}
+
+        # slicing
+        with pytest.raises(nx.NetworkXError):
+            G.edges[0:5]
+
     def test_call(self):
         ev = self.eview(self.G)
         assert id(ev) == id(ev())
@@ -761,6 +777,16 @@ class TestMultiEdgeView(TestEdgeView):
         rep = str(replist)
         assert str(ev) == rep
 
+    def test_getitem(self):
+        G = self.G.copy()
+        ev = G.edges
+        G.edges[0, 1, 0]["foo"] = "bar"
+        assert ev[0, 1, 0] == {"foo": "bar"}
+
+        # slicing
+        with pytest.raises(nx.NetworkXError):
+            G.edges[0:5]
+
     def test_repr(self):
         ev = self.eview(self.G)
         rep = (
diff --git a/networkx/tests/test_convert_numpy.py b/networkx/tests/test_convert_numpy.py
index 8e8d1ee06..48269085a 100644
--- a/networkx/tests/test_convert_numpy.py
+++ b/networkx/tests/test_convert_numpy.py
@@ -1,7 +1,7 @@
 import pytest
 
 np = pytest.importorskip("numpy")
-np_assert_equal = np.testing.assert_equal
+npt = np.testing
 
 import networkx as nx
 from networkx.generators.classic import barbell_graph, cycle_graph, path_graph
@@ -121,9 +121,9 @@ class TestConvertNumpyMatrix:
         WP4.add_edges_from((n, n + 1, dict(weight=0.5, other=0.3)) for n in range(3))
         P4 = path_graph(4)
         A = nx.to_numpy_matrix(P4)
-        np_assert_equal(A, nx.to_numpy_matrix(WP4, weight=None))
-        np_assert_equal(0.5 * A, nx.to_numpy_matrix(WP4))
-        np_assert_equal(0.3 * A, nx.to_numpy_matrix(WP4, weight="other"))
+        npt.assert_equal(A, nx.to_numpy_matrix(WP4, weight=None))
+        npt.assert_equal(0.5 * A, nx.to_numpy_matrix(WP4))
+        npt.assert_equal(0.3 * A, nx.to_numpy_matrix(WP4, weight="other"))
 
     def test_from_numpy_matrix_type(self):
         A = np.matrix([[1]])
@@ -323,9 +323,9 @@ class TestConvertNumpyArray:
         WP4.add_edges_from((n, n + 1, dict(weight=0.5, other=0.3)) for n in range(3))
         P4 = path_graph(4)
         A = nx.to_numpy_array(P4)
-        np_assert_equal(A, nx.to_numpy_array(WP4, weight=None))
-        np_assert_equal(0.5 * A, nx.to_numpy_array(WP4))
-        np_assert_equal(0.3 * A, nx.to_numpy_array(WP4, weight="other"))
+        npt.assert_equal(A, nx.to_numpy_array(WP4, weight=None))
+        npt.assert_equal(0.5 * A, nx.to_numpy_array(WP4))
+        npt.assert_equal(0.3 * A, nx.to_numpy_array(WP4, weight="other"))
 
     def test_from_numpy_array_type(self):
         A = np.array([[1]])
@@ -360,27 +360,6 @@ class TestConvertNumpyArray:
         assert G[0][0]["cost"] == 2
         assert G[0][0]["weight"] == 1.0
 
-    def test_to_numpy_recarray(self):
-        G = nx.Graph()
-        G.add_edge(1, 2, weight=7.0, cost=5)
-        A = nx.to_numpy_recarray(G, dtype=[("weight", float), ("cost", int)])
-        assert sorted(A.dtype.names) == ["cost", "weight"]
-        assert A.weight[0, 1] == 7.0
-        assert A.weight[0, 0] == 0.0
-        assert A.cost[0, 1] == 5
-        assert A.cost[0, 0] == 0
-
-    def test_numpy_multigraph(self):
-        G = nx.MultiGraph()
-        G.add_edge(1, 2, weight=7)
-        G.add_edge(1, 2, weight=70)
-        A = nx.to_numpy_array(G)
-        assert A[1, 0] == 77
-        A = nx.to_numpy_array(G, multigraph_weight=min)
-        assert A[1, 0] == 7
-        A = nx.to_numpy_array(G, multigraph_weight=max)
-        assert A[1, 0] == 70
-
     def test_from_numpy_array_parallel_edges(self):
         """Tests that the :func:`networkx.from_numpy_array` function
         interprets integer weights as the number of parallel edges when
@@ -447,3 +426,114 @@ class TestConvertNumpyArray:
         G = nx.MultiGraph(nx.complete_graph(3))
         A = nx.to_numpy_array(G, dtype=int)
         assert A.dtype == int
+
+
+@pytest.fixture
+def recarray_test_graph():
+    G = nx.Graph()
+    G.add_edge(1, 2, weight=7.0, cost=5)
+    return G
+
+
+def test_to_numpy_recarray(recarray_test_graph):
+    A = nx.to_numpy_recarray(
+        recarray_test_graph, dtype=[("weight", float), ("cost", int)]
+    )
+    assert sorted(A.dtype.names) == ["cost", "weight"]
+    assert A.weight[0, 1] == 7.0
+    assert A.weight[0, 0] == 0.0
+    assert A.cost[0, 1] == 5
+    assert A.cost[0, 0] == 0
+    with pytest.raises(AttributeError, match="has no attribute"):
+        A.color[0, 1]
+
+
+def test_to_numpy_recarray_default_dtype(recarray_test_graph):
+    A = nx.to_numpy_recarray(recarray_test_graph)
+    assert A.dtype.names == ("weight",)
+    assert A.weight[0, 0] == 0
+    assert A.weight[0, 1] == 7
+    with pytest.raises(AttributeError, match="has no attribute"):
+        A.cost[0, 1]
+
+
+def test_to_numpy_recarray_directed(recarray_test_graph):
+    G = recarray_test_graph.to_directed()
+    G.remove_edge(2, 1)
+    A = nx.to_numpy_recarray(G, dtype=[("weight", float), ("cost", int)])
+    npt.assert_array_equal(A.weight, np.array([[0, 7.0], [0, 0]]))
+    npt.assert_array_equal(A.cost, np.array([[0, 5], [0, 0]]))
+
+
+def test_to_numpy_recarray_default_dtype_no_weight():
+    G = nx.Graph()
+    G.add_edge(0, 1, color="red")
+    with pytest.raises(KeyError):
+        A = nx.to_numpy_recarray(G)
+    A = nx.to_numpy_recarray(G, dtype=[("color", "U8")])
+    assert A.color[0, 1] == "red"
+
+
+@pytest.fixture
+def recarray_nodelist_test_graph():
+    G = nx.Graph()
+    G.add_edges_from(
+        [
+            (0, 1, {"weight": 1.0}),
+            (0, 2, {"weight": 2.0}),
+            (1, 2, {"weight": 0.5}),
+        ]
+    )
+    return G
+
+
+def test_to_numpy_recarray_nodelist(recarray_nodelist_test_graph):
+    A = nx.to_numpy_recarray(recarray_nodelist_test_graph, nodelist=[0, 1])
+    npt.assert_array_equal(A.weight, np.array([[0, 1], [1, 0]]))
+
+
+@pytest.mark.parametrize(
+    ("nodelist", "errmsg"),
+    (
+        ([2, 3], "in nodelist is not in G"),
+        ([1, 1], "nodelist contains duplicates"),
+    ),
+)
+def test_to_numpy_recarray_bad_nodelist(recarray_nodelist_test_graph, nodelist, errmsg):
+    with pytest.raises(nx.NetworkXError, match=errmsg):
+        A = nx.to_numpy_recarray(recarray_nodelist_test_graph, nodelist=nodelist)
+
+
+def test_to_numpy_array_multigraph_weight():
+    G = nx.MultiGraph()
+    with pytest.raises(ValueError, match="must be sum, min, or max"):
+        nx.to_numpy_array(G, multigraph_weight=np.median)
+
+
+@pytest.fixture
+def multigraph_test_graph():
+    G = nx.MultiGraph()
+    G.add_edge(1, 2, weight=7)
+    G.add_edge(1, 2, weight=70)
+    return G
+
+
+@pytest.mark.parametrize(
+    ("operator", "expected"),
+    (
+        (sum, 77),
+        (min, 7),
+        (max, 70),
+    ),
+)
+def test_numpy_multigraph(multigraph_test_graph, operator, expected):
+    A = nx.to_numpy_array(multigraph_test_graph, multigraph_weight=operator)
+    assert A[1, 0] == expected
+
+
+def test_to_numpy_array_multigraph_nodelist(multigraph_test_graph):
+    G = multigraph_test_graph
+    G.add_edge(0, 1, weight=3)
+    A = nx.to_numpy_array(G, nodelist=[1, 2])
+    assert A.shape == (2, 2)
+    assert A[1, 0] == 77
diff --git a/networkx/tests/test_convert_pandas.py b/networkx/tests/test_convert_pandas.py
index 22a5e2c27..9920fbc79 100644
--- a/networkx/tests/test_convert_pandas.py
+++ b/networkx/tests/test_convert_pandas.py
@@ -284,3 +284,23 @@ class TestConvertPandas:
                 edge_attr=True,
                 create_using=nx.MultiGraph(),
             )
+
+
+def test_to_pandas_adjacency_with_nodelist():
+    G = nx.complete_graph(5)
+    nodelist = [1, 4]
+    expected = pd.DataFrame(
+        [[0, 1], [1, 0]], dtype=int, index=nodelist, columns=nodelist
+    )
+    pd.testing.assert_frame_equal(
+        expected, nx.to_pandas_adjacency(G, nodelist, dtype=int)
+    )
+
+
+def test_to_pandas_edgelist_with_nodelist():
+    G = nx.Graph()
+    G.add_edges_from([(0, 1), (1, 2), (1, 3)], weight=2.0)
+    G.add_edge(0, 5, weight=100)
+    df = nx.to_pandas_edgelist(G, nodelist=[1, 2])
+    assert 0 not in df["source"].to_numpy()
+    assert 100 not in df["weight"].to_numpy()
diff --git a/networkx/tests/test_convert_scipy.py b/networkx/tests/test_convert_scipy.py
index 0720ca411..2f2463ca6 100644
--- a/networkx/tests/test_convert_scipy.py
+++ b/networkx/tests/test_convert_scipy.py
@@ -1,19 +1,16 @@
 import pytest
 
+np = pytest.importorskip("numpy")
+sp = pytest.importorskip("scipy")
+sparse = sp.sparse
+npt = np.testing
+
 import networkx as nx
 from networkx.testing import assert_graphs_equal
 from networkx.generators.classic import barbell_graph, cycle_graph, path_graph
 
 
-class TestConvertNumpy:
-    @classmethod
-    def setup_class(cls):
-        global np, sp, sparse, np_assert_equal
-        np = pytest.importorskip("numpy")
-        sp = pytest.importorskip("scipy")
-        sparse = sp.sparse
-        np_assert_equal = np.testing.assert_equal
-
+class TestConvertScipy:
     def setup_method(self):
         self.G1 = barbell_graph(10, 3)
         self.G2 = cycle_graph(10, create_using=nx.DiGraph)
@@ -118,11 +115,11 @@ class TestConvertNumpy:
         WP4.add_edges_from((n, n + 1, dict(weight=0.5, other=0.3)) for n in range(3))
         P4 = path_graph(4)
         A = nx.to_scipy_sparse_matrix(P4)
-        np_assert_equal(
+        npt.assert_equal(
             A.todense(), nx.to_scipy_sparse_matrix(WP4, weight=None).todense()
         )
-        np_assert_equal(0.5 * A.todense(), nx.to_scipy_sparse_matrix(WP4).todense())
-        np_assert_equal(
+        npt.assert_equal(0.5 * A.todense(), nx.to_scipy_sparse_matrix(WP4).todense())
+        npt.assert_equal(
             0.3 * A.todense(), nx.to_scipy_sparse_matrix(WP4, weight="other").todense()
         )
 
@@ -131,37 +128,37 @@ class TestConvertNumpy:
         WP4.add_edges_from((n, n + 1, dict(weight=0.5, other=0.3)) for n in range(3))
         P4 = path_graph(4)
         A = nx.to_scipy_sparse_matrix(P4, format="csr")
-        np_assert_equal(
+        npt.assert_equal(
             A.todense(), nx.to_scipy_sparse_matrix(WP4, weight=None).todense()
         )
 
         A = nx.to_scipy_sparse_matrix(P4, format="csc")
-        np_assert_equal(
+        npt.assert_equal(
             A.todense(), nx.to_scipy_sparse_matrix(WP4, weight=None).todense()
         )
 
         A = nx.to_scipy_sparse_matrix(P4, format="coo")
-        np_assert_equal(
+        npt.assert_equal(
             A.todense(), nx.to_scipy_sparse_matrix(WP4, weight=None).todense()
         )
 
         A = nx.to_scipy_sparse_matrix(P4, format="bsr")
-        np_assert_equal(
+        npt.assert_equal(
             A.todense(), nx.to_scipy_sparse_matrix(WP4, weight=None).todense()
         )
 
         A = nx.to_scipy_sparse_matrix(P4, format="lil")
-        np_assert_equal(
+        npt.assert_equal(
             A.todense(), nx.to_scipy_sparse_matrix(WP4, weight=None).todense()
         )
 
         A = nx.to_scipy_sparse_matrix(P4, format="dia")
-        np_assert_equal(
+        npt.assert_equal(
             A.todense(), nx.to_scipy_sparse_matrix(WP4, weight=None).todense()
         )
 
         A = nx.to_scipy_sparse_matrix(P4, format="dok")
-        np_assert_equal(
+        npt.assert_equal(
             A.todense(), nx.to_scipy_sparse_matrix(WP4, weight=None).todense()
         )
 
@@ -182,7 +179,7 @@ class TestConvertNumpy:
         G = nx.Graph()
         G.add_node(1)
         M = nx.to_scipy_sparse_matrix(G)
-        np_assert_equal(M.todense(), np.matrix([[0]]))
+        npt.assert_equal(M.todense(), np.matrix([[0]]))
 
     def test_ordering(self):
         G = nx.DiGraph()
@@ -190,25 +187,25 @@ class TestConvertNumpy:
         G.add_edge(2, 3)
         G.add_edge(3, 1)
         M = nx.to_scipy_sparse_matrix(G, nodelist=[3, 2, 1])
-        np_assert_equal(M.todense(), np.matrix([[0, 0, 1], [1, 0, 0], [0, 1, 0]]))
+        npt.assert_equal(M.todense(), np.matrix([[0, 0, 1], [1, 0, 0], [0, 1, 0]]))
 
     def test_selfloop_graph(self):
         G = nx.Graph([(1, 1)])
         M = nx.to_scipy_sparse_matrix(G)
-        np_assert_equal(M.todense(), np.matrix([[1]]))
+        npt.assert_equal(M.todense(), np.matrix([[1]]))
 
         G.add_edges_from([(2, 3), (3, 4)])
         M = nx.to_scipy_sparse_matrix(G, nodelist=[2, 3, 4])
-        np_assert_equal(M.todense(), np.matrix([[0, 1, 0], [1, 0, 1], [0, 1, 0]]))
+        npt.assert_equal(M.todense(), np.matrix([[0, 1, 0], [1, 0, 1], [0, 1, 0]]))
 
     def test_selfloop_digraph(self):
         G = nx.DiGraph([(1, 1)])
         M = nx.to_scipy_sparse_matrix(G)
-        np_assert_equal(M.todense(), np.matrix([[1]]))
+        npt.assert_equal(M.todense(), np.matrix([[1]]))
 
         G.add_edges_from([(2, 3), (3, 4)])
         M = nx.to_scipy_sparse_matrix(G, nodelist=[2, 3, 4])
-        np_assert_equal(M.todense(), np.matrix([[0, 1, 0], [0, 0, 1], [0, 0, 0]]))
+        npt.assert_equal(M.todense(), np.matrix([[0, 1, 0], [0, 0, 1], [0, 0, 0]]))
 
     def test_from_scipy_sparse_matrix_parallel_edges(self):
         """Tests that the :func:`networkx.from_scipy_sparse_matrix` function
@@ -261,3 +258,22 @@ class TestConvertNumpy:
         expected = nx.MultiGraph()
         expected.add_edge(0, 1, weight=1)
         assert_graphs_equal(G, expected)
+
+
+@pytest.mark.parametrize("sparse_format", ("csr", "csc", "dok"))
+def test_from_scipy_sparse_matrix_formats(sparse_format):
+    """Test all formats supported by _generate_weighted_edges."""
+    # trinode complete graph with non-uniform edge weights
+    expected = nx.Graph()
+    expected.add_edges_from(
+        [
+            (0, 1, {"weight": 3}),
+            (0, 2, {"weight": 2}),
+            (1, 0, {"weight": 3}),
+            (1, 2, {"weight": 1}),
+            (2, 0, {"weight": 2}),
+            (2, 1, {"weight": 1}),
+        ]
+    )
+    A = sparse.coo_matrix([[0, 3, 2], [3, 0, 1], [2, 1, 0]]).asformat(sparse_format)
+    assert_graphs_equal(expected, nx.from_scipy_sparse_matrix(A))
diff --git a/networkx/tests/test_relabel.py b/networkx/tests/test_relabel.py
index 1dc9ff480..ad6730a78 100644
--- a/networkx/tests/test_relabel.py
+++ b/networkx/tests/test_relabel.py
@@ -287,3 +287,10 @@ class TestRelabel:
                 assert 0 in G[0][4]
                 assert "I" in G[0][4]
                 assert "II" in G[0][4]
+
+    def test_relabel_circular(self):
+        G = nx.path_graph(3)
+        mapping = {0: 1, 1: 0}
+        H = nx.relabel_nodes(G, mapping, copy=True)
+        with pytest.raises(nx.NetworkXUnfeasible):
+            H = nx.relabel_nodes(G, mapping, copy=False)