Repository: networkx/networkx

Issue:
Docstring of `nonisomorphic_trees` should use `Yields`, not `Returns`
In NetworkX 3.2.1, `nonisomorphic_trees` yields graphs or adjacency matrices, so the docstring should use a `Yields` section, but it uses `Returns`.

Discussion:

Patch:
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index b274f5c7f..a8bc0c057 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -27,7 +27,7 @@ jobs:
       - name: List contents of wheel
         run: python -m zipfile --list dist/networkx-*.whl
       - name: Upload nighlty wheel
-        uses: scientific-python/upload-nightly-action@5fb764c5bce1ac2297084c0f7161b1919f17c74f # 0.2.0
+        uses: scientific-python/upload-nightly-action@6e9304f7a3a5501c6f98351537493ec898728299 # 0.3.0
         with:
           anaconda_nightly_upload_token: ${{ secrets.ANACONDA_NIGHTLY }}
           artifacts_path: dist/
diff --git a/benchmarks/benchmarks/benchmark_neighbors.py b/benchmarks/benchmarks/benchmark_neighbors.py
new file mode 100644
index 000000000..e821f3cad
--- /dev/null
+++ b/benchmarks/benchmarks/benchmark_neighbors.py
@@ -0,0 +1,51 @@
+import networkx as nx
+
+
+# NOTE: explicit set construction in benchmarks is required for meaningful
+# comparisons due to change in return type from generator -> set. See gh-7244.
+class NonNeighbors:
+    param_names = ["num_nodes"]
+    params = [10, 100, 1000]
+
+    def setup(self, num_nodes):
+        self.star_graph = nx.star_graph(num_nodes)
+        self.complete_graph = nx.complete_graph(num_nodes)
+        self.path_graph = nx.path_graph(num_nodes)
+
+    def time_star_center(self, num_nodes):
+        set(nx.non_neighbors(self.star_graph, 0))
+
+    def time_star_rim(self, num_nodes):
+        set(nx.non_neighbors(self.star_graph, 5))
+
+    def time_complete(self, num_nodes):
+        set(nx.non_neighbors(self.complete_graph, 0))
+
+    def time_path_first(self, num_nodes):
+        set(nx.non_neighbors(self.path_graph, 0))
+
+    def time_path_last(self, num_nodes):
+        set(nx.non_neighbors(self.path_graph, num_nodes - 1))
+
+    def time_path_center(self, num_nodes):
+        set(nx.non_neighbors(self.path_graph, num_nodes // 2))
+
+
+# NOTE: explicit set construction in benchmarks is required for meaningful
+# comparisons due to change in return type from generator -> set. See gh-7244.
+class CommonNeighbors:
+    param_names = ["num_nodes"]
+    params = [10, 100, 1000]
+
+    def setup(self, num_nodes):
+        self.star_graph = nx.star_graph(num_nodes)
+        self.complete_graph = nx.complete_graph(num_nodes)
+
+    def time_star_center_rim(self, num_nodes):
+        set(nx.common_neighbors(self.star_graph, 0, num_nodes // 2))
+
+    def time_star_rim_rim(self, num_nodes):
+        set(nx.common_neighbors(self.star_graph, 4, 5))
+
+    def time_complete(self, num_nodes):
+        set(nx.common_neighbors(self.complete_graph, 0, num_nodes // 2))
diff --git a/networkx/algorithms/connectivity/edge_kcomponents.py b/networkx/algorithms/connectivity/edge_kcomponents.py
index d2ed1ac5c..9dcdf71a2 100644
--- a/networkx/algorithms/connectivity/edge_kcomponents.py
+++ b/networkx/algorithms/connectivity/edge_kcomponents.py
@@ -505,17 +505,24 @@ def _high_degree_components(G, k):
 
 @nx._dispatchable
 def general_k_edge_subgraphs(G, k):
-    """General algorithm to find all maximal k-edge-connected subgraphs in G.
+    """General algorithm to find all maximal k-edge-connected subgraphs in `G`.
 
-    Returns
-    -------
-    k_edge_subgraphs : a generator of nx.Graphs that are k-edge-subgraphs
-        Each k-edge-subgraph is a maximal set of nodes that defines a subgraph
-        of G that is k-edge-connected.
+    Parameters
+    ----------
+    G : nx.Graph
+       Graph in which all maximal k-edge-connected subgraphs will be found.
+
+    k : int
+
+    Yields
+    ------
+    k_edge_subgraphs : Graph instances that are k-edge-subgraphs
+        Each k-edge-subgraph contains a maximal set of nodes that defines a
+        subgraph of `G` that is k-edge-connected.
 
     Notes
     -----
-    Implementation of the basic algorithm from _[1].  The basic idea is to find
+    Implementation of the basic algorithm from [1]_.  The basic idea is to find
     a global minimum cut of the graph. If the cut value is at least k, then the
     graph is a k-edge-connected subgraph and can be added to the results.
     Otherwise, the cut is used to split the graph in two and the procedure is
@@ -524,7 +531,7 @@ def general_k_edge_subgraphs(G, k):
     a single node or a subgraph of G that is k-edge-connected.
 
     This implementation contains optimizations for reducing the number of calls
-    to max-flow, but there are other optimizations in _[1] that could be
+    to max-flow, but there are other optimizations in [1]_ that could be
     implemented.
 
     References
@@ -547,7 +554,7 @@ def general_k_edge_subgraphs(G, k):
     ...     (14, 101, 24),
     ... ]
     >>> G = nx.Graph(it.chain(*[pairwise(path) for path in paths]))
-    >>> sorted(map(len, k_edge_subgraphs(G, k=3)))
+    >>> sorted(len(k_sg) for k_sg in k_edge_subgraphs(G, k=3))
     [1, 1, 1, 4, 4]
     """
     if k < 1:
diff --git a/networkx/algorithms/link_prediction.py b/networkx/algorithms/link_prediction.py
index 56f7bc5c1..1fb24243a 100644
--- a/networkx/algorithms/link_prediction.py
+++ b/networkx/algorithms/link_prediction.py
@@ -169,7 +169,7 @@ def jaccard_coefficient(G, ebunch=None):
         union_size = len(set(G[u]) | set(G[v]))
         if union_size == 0:
             return 0
-        return len(list(nx.common_neighbors(G, u, v))) / union_size
+        return len(nx.common_neighbors(G, u, v)) / union_size
 
     return _apply_prediction(G, predict, ebunch)
 
@@ -329,7 +329,7 @@ def common_neighbor_centrality(G, ebunch=None, alpha=0.8):
             if u == v:
                 raise nx.NetworkXAlgorithmError("Self loops are not supported")
 
-            return sum(1 for _ in nx.common_neighbors(G, u, v))
+            return len(nx.common_neighbors(G, u, v))
 
     else:
         spl = dict(nx.shortest_path_length(G))
@@ -340,9 +340,8 @@ def common_neighbor_centrality(G, ebunch=None, alpha=0.8):
                 raise nx.NetworkXAlgorithmError("Self loops are not supported")
             path_len = spl[u].get(v, inf)
 
-            return alpha * sum(1 for _ in nx.common_neighbors(G, u, v)) + (
-                1 - alpha
-            ) * (G.number_of_nodes() / path_len)
+            n_nbrs = len(nx.common_neighbors(G, u, v))
+            return alpha * n_nbrs + (1 - alpha) * len(G) / path_len
 
     return _apply_prediction(G, predict, ebunch)
 
@@ -486,7 +485,7 @@ def cn_soundarajan_hopcroft(G, ebunch=None, community="community"):
     def predict(u, v):
         Cu = _community(G, u, community)
         Cv = _community(G, v, community)
-        cnbors = list(nx.common_neighbors(G, u, v))
+        cnbors = nx.common_neighbors(G, u, v)
         neighbors = (
             sum(_community(G, w, community) == Cu for w in cnbors) if Cu == Cv else 0
         )
@@ -670,7 +669,7 @@ def within_inter_cluster(G, ebunch=None, delta=0.001, community="community"):
         Cv = _community(G, v, community)
         if Cu != Cv:
             return 0
-        cnbors = set(nx.common_neighbors(G, u, v))
+        cnbors = nx.common_neighbors(G, u, v)
         within = {w for w in cnbors if _community(G, w, community) == Cu}
         inter = cnbors - within
         return len(within) / (len(inter) + delta)
diff --git a/networkx/algorithms/richclub.py b/networkx/algorithms/richclub.py
index f787f4254..445b27d14 100644
--- a/networkx/algorithms/richclub.py
+++ b/networkx/algorithms/richclub.py
@@ -44,6 +44,12 @@ def rich_club_coefficient(G, normalized=True, Q=100, seed=None):
     rc : dictionary
        A dictionary, keyed by degree, with rich-club coefficient values.
 
+    Raises
+    ------
+    NetworkXError
+        If `G` has fewer than four nodes and ``normalized=True``.
+        A randomly sampled graph for normalization cannot be generated in this case.
+
     Examples
     --------
     >>> G = nx.Graph([(0, 1), (0, 2), (1, 2), (1, 3), (1, 4), (4, 5)])
@@ -57,6 +63,14 @@ def rich_club_coefficient(G, normalized=True, Q=100, seed=None):
     algorithm ignores any edge weights and is not defined for directed
     graphs or graphs with parallel edges or self loops.
 
+    Normalization is done by computing the rich club coefficient for a randomly
+    sampled graph with the same degree distribution as `G` by
+    repeatedly swapping the endpoints of existing edges. For graphs with fewer than 4
+    nodes, it is not possible to generate a random graph with a prescribed
+    degree distribution, as the degree distribution fully determines the graph
+    (hence making the coefficients trivially normalized to 1).
+    This function raises an exception in this case.
+
     Estimates for appropriate values of `Q` are found in [2]_.
 
     References
@@ -108,6 +122,9 @@ def _compute_rc(G):
     # side of the list, which would have a linear time cost.
     edge_degrees = sorted((sorted(map(G.degree, e)) for e in G.edges()), reverse=True)
     ek = G.number_of_edges()
+    if ek == 0:
+        return {}
+
     k1, k2 = edge_degrees.pop()
     rc = {}
     for d, nk in enumerate(nks):
diff --git a/networkx/classes/function.py b/networkx/classes/function.py
index 2746d56d7..726b3e23b 100644
--- a/networkx/classes/function.py
+++ b/networkx/classes/function.py
@@ -156,7 +156,7 @@ def degree_histogram(G):
     (Order(number_of_edges))
     """
     counts = Counter(d for n, d in G.degree())
-    return [counts.get(i, 0) for i in range(max(counts) + 1)]
+    return [counts.get(i, 0) for i in range(max(counts) + 1 if counts else 0)]
 
 
 def is_directed(G):
@@ -809,13 +809,13 @@ def set_edge_attributes(G, values, name=None):
             if G.is_multigraph():
                 for (u, v, key), value in values.items():
                     try:
-                        G[u][v][key][name] = value
+                        G._adj[u][v][key][name] = value
                     except KeyError:
                         pass
             else:
                 for (u, v), value in values.items():
                     try:
-                        G[u][v][name] = value
+                        G._adj[u][v][name] = value
                     except KeyError:
                         pass
         except AttributeError:
@@ -827,13 +827,13 @@ def set_edge_attributes(G, values, name=None):
         if G.is_multigraph():
             for (u, v, key), d in values.items():
                 try:
-                    G[u][v][key].update(d)
+                    G._adj[u][v][key].update(d)
                 except KeyError:
                     pass
         else:
             for (u, v), d in values.items():
                 try:
-                    G[u][v].update(d)
+                    G._adj[u][v].update(d)
                 except KeyError:
                     pass
 
@@ -918,11 +918,10 @@ def non_neighbors(graph, node):
 
     Returns
     -------
-    non_neighbors : iterator
-        Iterator of nodes in the graph that are not neighbors of the node.
+    non_neighbors : set
+        Set of nodes in the graph that are not neighbors of the node.
     """
-    nbors = set(neighbors(graph, node)) | {node}
-    return (nnode for nnode in graph if nnode not in nbors)
+    return graph._adj.keys() - graph._adj[node].keys() - {node}
 
 
 def non_edges(graph):
@@ -964,8 +963,8 @@ def common_neighbors(G, u, v):
 
     Returns
     -------
-    cnbors : iterator
-        Iterator of common neighbors of u and v in the graph.
+    cnbors : set
+        Set of common neighbors of u and v in the graph.
 
     Raises
     ------
@@ -983,9 +982,7 @@ def common_neighbors(G, u, v):
     if v not in G:
         raise nx.NetworkXError("v is not in the graph.")
 
-    # Return a generator explicitly instead of yielding so that the above
-    # checks are executed eagerly.
-    return (w for w in G[u] if w in G[v] and w not in (u, v))
+    return G._adj[u].keys() & G._adj[v].keys() - {u, v}
 
 
 def is_weighted(G, edge=None, weight="weight"):
@@ -1114,7 +1111,7 @@ def is_empty(G):
     is the number of nodes in the graph.
 
     """
-    return not any(G.adj.values())
+    return not any(G._adj.values())
 
 
 def nodes_with_selfloops(G):
@@ -1141,7 +1138,7 @@ def nodes_with_selfloops(G):
     [1]
 
     """
-    return (n for n, nbrs in G.adj.items() if n in nbrs)
+    return (n for n, nbrs in G._adj.items() if n in nbrs)
 
 
 def selfloop_edges(G, data=False, keys=False, default=None):
@@ -1191,56 +1188,59 @@ def selfloop_edges(G, data=False, keys=False, default=None):
             if keys is True:
                 return (
                     (n, n, k, d)
-                    for n, nbrs in G.adj.items()
+                    for n, nbrs in G._adj.items()
                     if n in nbrs
                     for k, d in nbrs[n].items()
                 )
             else:
                 return (
                     (n, n, d)
-                    for n, nbrs in G.adj.items()
+                    for n, nbrs in G._adj.items()
                     if n in nbrs
                     for d in nbrs[n].values()
                 )
         else:
-            return ((n, n, nbrs[n]) for n, nbrs in G.adj.items() if n in nbrs)
+            return ((n, n, nbrs[n]) for n, nbrs in G._adj.items() if n in nbrs)
     elif data is not False:
         if G.is_multigraph():
             if keys is True:
                 return (
                     (n, n, k, d.get(data, default))
-                    for n, nbrs in G.adj.items()
+                    for n, nbrs in G._adj.items()
                     if n in nbrs
                     for k, d in nbrs[n].items()
                 )
             else:
                 return (
                     (n, n, d.get(data, default))
-                    for n, nbrs in G.adj.items()
+                    for n, nbrs in G._adj.items()
                     if n in nbrs
                     for d in nbrs[n].values()
                 )
         else:
             return (
                 (n, n, nbrs[n].get(data, default))
-                for n, nbrs in G.adj.items()
+                for n, nbrs in G._adj.items()
                 if n in nbrs
             )
     else:
         if G.is_multigraph():
             if keys is True:
                 return (
-                    (n, n, k) for n, nbrs in G.adj.items() if n in nbrs for k in nbrs[n]
+                    (n, n, k)
+                    for n, nbrs in G._adj.items()
+                    if n in nbrs
+                    for k in nbrs[n]
                 )
             else:
                 return (
                     (n, n)
-                    for n, nbrs in G.adj.items()
+                    for n, nbrs in G._adj.items()
                     if n in nbrs
                     for i in range(len(nbrs[n]))  # for easy edge removal (#4068)
                 )
         else:
-            return ((n, n) for n, nbrs in G.adj.items() if n in nbrs)
+            return ((n, n) for n, nbrs in G._adj.items() if n in nbrs)
 
 
 def number_of_selfloops(G):
@@ -1288,7 +1288,10 @@ def is_path(G, path):
         True if `path` is a valid path in `G`
 
     """
-    return all((node in G and nbr in G[node]) for node, nbr in nx.utils.pairwise(path))
+    try:
+        return all(nbr in G._adj[node] for node, nbr in nx.utils.pairwise(path))
+    except (KeyError, TypeError):
+        return False
 
 
 def path_weight(G, path, weight):
@@ -1323,7 +1326,7 @@ def path_weight(G, path, weight):
         raise nx.NetworkXNoPath("path does not exist")
     for node, nbr in nx.utils.pairwise(path):
         if multigraph:
-            cost += min(v[weight] for v in G[node][nbr].values())
+            cost += min(v[weight] for v in G._adj[node][nbr].values())
         else:
-            cost += G[node][nbr][weight]
+            cost += G._adj[node][nbr][weight]
     return cost
diff --git a/networkx/generators/nonisomorphic_trees.py b/networkx/generators/nonisomorphic_trees.py
index 6f5d64123..4389e810a 100644
--- a/networkx/generators/nonisomorphic_trees.py
+++ b/networkx/generators/nonisomorphic_trees.py
@@ -19,22 +19,20 @@ def nonisomorphic_trees(order, create="graph"):
     Parameters
     ----------
     order : int
-      order of the desired tree(s)
-
-    create : graph or matrix (default="Graph)
-      If graph is selected a list of trees will be returned,
-      if matrix is selected a list of adjacency matrix will
-      be returned
-
-    Returns
-    -------
-    G : List of NetworkX Graphs
-
-    M : List of Adjacency matrices
-
-    References
-    ----------
-
+       order of the desired tree(s)
+
+    create : one of {"graph", "matrix"} (default="graph")
+       If ``"graph"`` is selected a list of ``Graph`` instances will be returned,
+       if matrix is selected a list of adjacency matrices will be returned.
+
+    Yields
+    ------
+    list
+       A list of nonisomorphic trees, in one of two formats depending on the
+       value of the `create` parameter:
+       - ``create="graph"``: yields a list of `networkx.Graph` instances
+       - ``create="matrix"``: yields a list of list-of-lists representing
+         adjacency matrices
     """
 
     if order < 2:


Test patch:
diff --git a/networkx/algorithms/community/tests/test_divisive.py b/networkx/algorithms/community/tests/test_divisive.py
index f3857613d..874e8c167 100644
--- a/networkx/algorithms/community/tests/test_divisive.py
+++ b/networkx/algorithms/community/tests/test_divisive.py
@@ -52,10 +52,9 @@ def test_edge_current_flow_betweenness_partition():
 
     G = nx.barbell_graph(3, 1)
     C = nx.community.edge_current_flow_betweenness_partition(G, 2)
-    answer = [{0, 1, 2, 3}, {4, 5, 6}]
-    assert len(C) == len(answer)
-    for s in answer:
-        assert s in C
+    answers = [[{0, 1, 2, 3}, {4, 5, 6}], [{0, 1, 2}, {3, 4, 5, 6}]]
+    assert len(C) == len(answers[0])
+    assert any(all(s in answer for s in C) for answer in answers)
 
     C = nx.community.edge_current_flow_betweenness_partition(G, 3)
     answer = [{0, 1, 2}, {4, 5, 6}, {3}]
@@ -64,10 +63,9 @@ def test_edge_current_flow_betweenness_partition():
         assert s in C
 
     C = nx.community.edge_current_flow_betweenness_partition(G, 4)
-    answer = [{1, 2}, {4, 5, 6}, {3}, {0}]
-    assert len(C) == len(answer)
-    for s in answer:
-        assert s in C
+    answers = [[{1, 2}, {4, 5, 6}, {3}, {0}], [{0, 1, 2}, {5, 6}, {3}, {4}]]
+    assert len(C) == len(answers[0])
+    assert any(all(s in answer for s in C) for answer in answers)
 
     C = nx.community.edge_current_flow_betweenness_partition(G, 5)
     answer = [{1, 2}, {5, 6}, {3}, {0}, {4}]
@@ -76,10 +74,9 @@ def test_edge_current_flow_betweenness_partition():
         assert s in C
 
     C = nx.community.edge_current_flow_betweenness_partition(G, 6)
-    answer = [{2}, {5, 6}, {3}, {0}, {4}, {1}]
-    assert len(C) == len(answer)
-    for s in answer:
-        assert s in C
+    answers = [[{2}, {5, 6}, {3}, {0}, {4}, {1}], [{1, 2}, {6}, {3}, {0}, {4}, {5}]]
+    assert len(C) == len(answers[0])
+    assert any(all(s in answer for s in C) for answer in answers)
 
     C = nx.community.edge_current_flow_betweenness_partition(G, 7)
     answer = [{n} for n in G]
diff --git a/networkx/algorithms/community/tests/test_label_propagation.py b/networkx/algorithms/community/tests/test_label_propagation.py
index d86b1d7d4..4be72dbf2 100644
--- a/networkx/algorithms/community/tests/test_label_propagation.py
+++ b/networkx/algorithms/community/tests/test_label_propagation.py
@@ -193,7 +193,7 @@ class TestFastLabelPropagationCommunities:
         self._check_communities(G, truth)
 
     def test_random_graph(self):
-        G = nx.gnm_random_graph(self.N, self.N * self.K // 2)
+        G = nx.gnm_random_graph(self.N, self.N * self.K // 2, seed=42)
         truth = {frozenset(G)}
         self._check_communities(G, truth)
 
@@ -209,7 +209,7 @@ class TestFastLabelPropagationCommunities:
         self._check_communities(G, truth)
 
     def test_larger_graph(self):
-        G = nx.gnm_random_graph(100 * self.N, 50 * self.N * self.K)
+        G = nx.gnm_random_graph(100 * self.N, 50 * self.N * self.K, seed=42)
         nx.community.fast_label_propagation_communities(G)
 
     def test_graph_type(self):
diff --git a/networkx/algorithms/tests/test_richclub.py b/networkx/algorithms/tests/test_richclub.py
index 5638ddbf0..8d83abaea 100644
--- a/networkx/algorithms/tests/test_richclub.py
+++ b/networkx/algorithms/tests/test_richclub.py
@@ -91,6 +91,58 @@ def test_rich_club_selfloop():
         nx.rich_club_coefficient(G)
 
 
+def test_rich_club_leq_3_nodes_unnormalized():
+    # edgeless graphs upto 3 nodes
+    G = nx.Graph()
+    rc = nx.rich_club_coefficient(G, normalized=False)
+    assert rc == {}
+
+    for i in range(3):
+        G.add_node(i)
+        rc = nx.rich_club_coefficient(G, normalized=False)
+        assert rc == {}
+
+    # 2 nodes, single edge
+    G = nx.Graph()
+    G.add_edge(0, 1)
+    rc = nx.rich_club_coefficient(G, normalized=False)
+    assert rc == {0: 1}
+
+    # 3 nodes, single edge
+    G = nx.Graph()
+    G.add_nodes_from([0, 1, 2])
+    G.add_edge(0, 1)
+    rc = nx.rich_club_coefficient(G, normalized=False)
+    assert rc == {0: 1}
+
+    # 3 nodes, 2 edges
+    G.add_edge(1, 2)
+    rc = nx.rich_club_coefficient(G, normalized=False)
+    assert rc == {0: 2 / 3}
+
+    # 3 nodes, 3 edges
+    G.add_edge(0, 2)
+    rc = nx.rich_club_coefficient(G, normalized=False)
+    assert rc == {0: 1, 1: 1}
+
+
+def test_rich_club_leq_3_nodes_normalized():
+    G = nx.Graph()
+    with pytest.raises(
+        nx.exception.NetworkXError,
+        match="Graph has fewer than four nodes",
+    ):
+        rc = nx.rich_club_coefficient(G, normalized=True)
+
+    for i in range(3):
+        G.add_node(i)
+        with pytest.raises(
+            nx.exception.NetworkXError,
+            match="Graph has fewer than four nodes",
+        ):
+            rc = nx.rich_club_coefficient(G, normalized=True)
+
+
 # def test_richclub2_normalized():
 #    T = nx.balanced_tree(2,10)
 #    rcNorm = nx.richclub.rich_club_coefficient(T,Q=2)
diff --git a/networkx/classes/tests/test_function.py b/networkx/classes/tests/test_function.py
index 61b73c2d2..ee4cca837 100644
--- a/networkx/classes/tests/test_function.py
+++ b/networkx/classes/tests/test_function.py
@@ -6,6 +6,11 @@ import networkx as nx
 from networkx.utils import edges_equal, nodes_equal
 
 
+def test_degree_histogram_empty():
+    G = nx.Graph()
+    assert nx.degree_histogram(G) == []
+
+
 class TestFunction:
     def setup_method(self):
         self.G = nx.Graph({0: [1, 2, 3], 1: [1, 2, 0], 4: []}, name="Test")
@@ -297,13 +302,13 @@ class TestFunction:
     def test_non_neighbors(self):
         graph = nx.complete_graph(100)
         pop = random.sample(list(graph), 1)
-        nbors = list(nx.non_neighbors(graph, pop[0]))
+        nbors = nx.non_neighbors(graph, pop[0])
         # should be all the other vertices in the graph
         assert len(nbors) == 0
 
         graph = nx.path_graph(100)
         node = random.sample(list(graph), 1)[0]
-        nbors = list(nx.non_neighbors(graph, node))
+        nbors = nx.non_neighbors(graph, node)
         # should be all the other vertices in the graph
         if node != 0 and node != 99:
             assert len(nbors) == 97
@@ -312,13 +317,13 @@ class TestFunction:
 
         # create a star graph with 99 outer nodes
         graph = nx.star_graph(99)
-        nbors = list(nx.non_neighbors(graph, 0))
+        nbors = nx.non_neighbors(graph, 0)
         assert len(nbors) == 0
 
         # disconnected graph
         graph = nx.Graph()
         graph.add_nodes_from(range(10))
-        nbors = list(nx.non_neighbors(graph, 0))
+        nbors = nx.non_neighbors(graph, 0)
         assert len(nbors) == 9
 
     def test_non_edges(self):
diff --git a/networkx/generators/tests/test_small.py b/networkx/generators/tests/test_small.py
index 836cbce44..355d6d36a 100644
--- a/networkx/generators/tests/test_small.py
+++ b/networkx/generators/tests/test_small.py
@@ -34,6 +34,9 @@ class TestGeneratorsSmall:
         utility_graph = nx.complete_bipartite_graph(3, 3)
         assert is_isomorphic(G, utility_graph)
 
+        with pytest.raises(nx.NetworkXError, match="Directed Graph not supported"):
+            G = nx.LCF_graph(6, [3, -3], 3, create_using=nx.DiGraph)
+
     def test_properties_named_small_graphs(self):
         G = nx.bull_graph()
         assert sorted(G) == list(range(5))