diff options
| author | Ross Barnowski <rossbar@berkeley.edu> | 2021-11-17 21:12:56 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-11-17 21:12:56 -0800 |
| commit | 00c261f951ae6734001e0419d2bc754eef6dd1b2 (patch) | |
| tree | 54e6ce86c89f3de9f2d960f4726025487216d3c8 /networkx/algorithms | |
| parent | 4ebdb5e2ca6c6a1f9fb3bf8c2279f9b857c6d8a7 (diff) | |
| download | networkx-00c261f951ae6734001e0419d2bc754eef6dd1b2.tar.gz | |
Add Mypy type checking infrastructure (#5127)
* Add minimal mypy configuration file.
* Add mypy workflow to GH.
* Properly import sentinels from traversal.edgedfs.
* mypy doesn't like variables named \"e\".
* Rm annotations from single function.
* Fix name collisions in test suite.
Make sure all tests have unique names.
* Rm unused random seed in test setup.
* Rm redundant __all__ specification.
* Silence mypy error from sum(). Mypy bug?
* Fix tsp test instantiation nit.
* \"type: ignore\" to suppress conditional fn sigature errors.
* Remaining \"type: ignore\" to appease mypy.
* Configure mypy to ignore inheritance issues.
* Update exclude conf for CI.
- Add yaml
- Reformat regex containing reportviews
* Rm partial annotations from lukes.py.
Fixes mypy errors due to unannotated code.
* Reorg defaultdict to reduce type: ignore cruft.
* Homogenize signatures for fns defined in conditionals.
* err as varname only in exception catching.
* Fix name collision in Bellman-Ford test suite.
Diffstat (limited to 'networkx/algorithms')
| -rw-r--r-- | networkx/algorithms/approximation/kcomponents.py | 2 | ||||
| -rw-r--r-- | networkx/algorithms/approximation/tests/test_traveling_salesman.py | 162 | ||||
| -rw-r--r-- | networkx/algorithms/bipartite/edgelist.py | 10 | ||||
| -rw-r--r-- | networkx/algorithms/centrality/katz.py | 4 | ||||
| -rw-r--r-- | networkx/algorithms/community/lukes.py | 14 | ||||
| -rw-r--r-- | networkx/algorithms/connectivity/__init__.py | 15 | ||||
| -rw-r--r-- | networkx/algorithms/d_separation.py | 2 | ||||
| -rw-r--r-- | networkx/algorithms/flow/tests/test_maxflow.py | 2 | ||||
| -rw-r--r-- | networkx/algorithms/shortest_paths/tests/test_weighted.py | 2 | ||||
| -rw-r--r-- | networkx/algorithms/tests/test_cycles.py | 4 | ||||
| -rw-r--r-- | networkx/algorithms/tests/test_graph_hashing.py | 2 | ||||
| -rw-r--r-- | networkx/algorithms/tests/test_smallworld.py | 1 | ||||
| -rw-r--r-- | networkx/algorithms/traversal/tests/test_edgebfs.py | 38 | ||||
| -rw-r--r-- | networkx/algorithms/traversal/tests/test_edgedfs.py | 7 |
14 files changed, 119 insertions, 146 deletions
diff --git a/networkx/algorithms/approximation/kcomponents.py b/networkx/algorithms/approximation/kcomponents.py index 12048da1..518a0274 100644 --- a/networkx/algorithms/approximation/kcomponents.py +++ b/networkx/algorithms/approximation/kcomponents.py @@ -213,7 +213,7 @@ class _AntiGraph(nx.Graph): def single_edge_dict(self): return self.all_edge_dict - edge_attr_dict_factory = single_edge_dict + edge_attr_dict_factory = single_edge_dict # type: ignore def __getitem__(self, n): """Returns a dict of neighbors of node n in the dense graph. diff --git a/networkx/algorithms/approximation/tests/test_traveling_salesman.py b/networkx/algorithms/approximation/tests/test_traveling_salesman.py index 56574f63..50d02b6c 100644 --- a/networkx/algorithms/approximation/tests/test_traveling_salesman.py +++ b/networkx/algorithms/approximation/tests/test_traveling_salesman.py @@ -39,83 +39,84 @@ def test_christofides_ignore_selfloops(): # set up graphs for other tests -@classmethod -def _setup_class(cls): - cls.DG = nx.DiGraph() - cls.DG.add_weighted_edges_from( - { - ("A", "B", 3), - ("A", "C", 17), - ("A", "D", 14), - ("B", "A", 3), - ("B", "C", 12), - ("B", "D", 16), - ("C", "A", 13), - ("C", "B", 12), - ("C", "D", 4), - ("D", "A", 14), - ("D", "B", 15), - ("D", "C", 2), - } - ) - cls.DG_cycle = ["D", "C", "B", "A", "D"] - cls.DG_cost = 31.0 - - cls.DG2 = nx.DiGraph() - cls.DG2.add_weighted_edges_from( - { - ("A", "B", 3), - ("A", "C", 17), - ("A", "D", 14), - ("B", "A", 30), - ("B", "C", 2), - ("B", "D", 16), - ("C", "A", 33), - ("C", "B", 32), - ("C", "D", 34), - ("D", "A", 14), - ("D", "B", 15), - ("D", "C", 2), - } - ) - cls.DG2_cycle = ["D", "A", "B", "C", "D"] - cls.DG2_cost = 53.0 - - cls.unweightedUG = nx.complete_graph(5, nx.Graph()) - cls.unweightedDG = nx.complete_graph(5, nx.DiGraph()) - - cls.incompleteUG = nx.Graph() - cls.incompleteUG.add_weighted_edges_from({(0, 1, 1), (1, 2, 3)}) - cls.incompleteDG = nx.DiGraph() - cls.incompleteDG.add_weighted_edges_from({(0, 1, 1), (1, 2, 3)}) - - cls.UG = nx.Graph() - cls.UG.add_weighted_edges_from( - { - ("A", "B", 3), - ("A", "C", 17), - ("A", "D", 14), - ("B", "C", 12), - ("B", "D", 16), - ("C", "D", 4), - } - ) - cls.UG_cycle = ["D", "C", "B", "A", "D"] - cls.UG_cost = 33.0 - - cls.UG2 = nx.Graph() - cls.UG2.add_weighted_edges_from( - { - ("A", "B", 1), - ("A", "C", 15), - ("A", "D", 5), - ("B", "C", 16), - ("B", "D", 8), - ("C", "D", 3), - } - ) - cls.UG2_cycle = ["D", "C", "B", "A", "D"] - cls.UG2_cost = 25.0 +class TestBase: + @classmethod + def setup_class(cls): + cls.DG = nx.DiGraph() + cls.DG.add_weighted_edges_from( + { + ("A", "B", 3), + ("A", "C", 17), + ("A", "D", 14), + ("B", "A", 3), + ("B", "C", 12), + ("B", "D", 16), + ("C", "A", 13), + ("C", "B", 12), + ("C", "D", 4), + ("D", "A", 14), + ("D", "B", 15), + ("D", "C", 2), + } + ) + cls.DG_cycle = ["D", "C", "B", "A", "D"] + cls.DG_cost = 31.0 + + cls.DG2 = nx.DiGraph() + cls.DG2.add_weighted_edges_from( + { + ("A", "B", 3), + ("A", "C", 17), + ("A", "D", 14), + ("B", "A", 30), + ("B", "C", 2), + ("B", "D", 16), + ("C", "A", 33), + ("C", "B", 32), + ("C", "D", 34), + ("D", "A", 14), + ("D", "B", 15), + ("D", "C", 2), + } + ) + cls.DG2_cycle = ["D", "A", "B", "C", "D"] + cls.DG2_cost = 53.0 + + cls.unweightedUG = nx.complete_graph(5, nx.Graph()) + cls.unweightedDG = nx.complete_graph(5, nx.DiGraph()) + + cls.incompleteUG = nx.Graph() + cls.incompleteUG.add_weighted_edges_from({(0, 1, 1), (1, 2, 3)}) + cls.incompleteDG = nx.DiGraph() + cls.incompleteDG.add_weighted_edges_from({(0, 1, 1), (1, 2, 3)}) + + cls.UG = nx.Graph() + cls.UG.add_weighted_edges_from( + { + ("A", "B", 3), + ("A", "C", 17), + ("A", "D", 14), + ("B", "C", 12), + ("B", "D", 16), + ("C", "D", 4), + } + ) + cls.UG_cycle = ["D", "C", "B", "A", "D"] + cls.UG_cost = 33.0 + + cls.UG2 = nx.Graph() + cls.UG2.add_weighted_edges_from( + { + ("A", "B", 1), + ("A", "C", 15), + ("A", "D", 5), + ("B", "C", 16), + ("B", "D", 8), + ("C", "D", 3), + } + ) + cls.UG2_cycle = ["D", "C", "B", "A", "D"] + cls.UG2_cost = 25.0 def validate_solution(soln, cost, exp_soln, exp_cost): @@ -128,9 +129,7 @@ def validate_symmetric_solution(soln, cost, exp_soln, exp_cost): assert cost == exp_cost -class TestGreedyTSP: - setup_class = _setup_class - +class TestGreedyTSP(TestBase): def test_greedy(self): cycle = nx_app.greedy_tsp(self.DG, source="D") cost = sum(self.DG[n][nbr]["weight"] for n, nbr in pairwise(cycle)) @@ -170,8 +169,7 @@ class TestGreedyTSP: assert len(cycle) - 1 == len(G) == len(set(cycle)) -class TestSimulatedAnnealingTSP: - setup_class = _setup_class +class TestSimulatedAnnealingTSP(TestBase): tsp = staticmethod(nx_app.simulated_annealing_tsp) def test_simulated_annealing_directed(self): diff --git a/networkx/algorithms/bipartite/edgelist.py b/networkx/algorithms/bipartite/edgelist.py index 77645d20..356f4ab7 100644 --- a/networkx/algorithms/bipartite/edgelist.py +++ b/networkx/algorithms/bipartite/edgelist.py @@ -133,17 +133,17 @@ def generate_edgelist(G, delimiter=" ", data=True): raise AttributeError("Missing node attribute `bipartite`") from err if data is True or data is False: for n in part0: - for e in G.edges(n, data=data): - yield delimiter.join(map(str, e)) + for edge in G.edges(n, data=data): + yield delimiter.join(map(str, edge)) else: for n in part0: for u, v, d in G.edges(n, data=True): - e = [u, v] + edge = [u, v] try: - e.extend(d[k] for k in data) + edge.extend(d[k] for k in data) except KeyError: pass # missing data for this edge, should warn? - yield delimiter.join(map(str, e)) + yield delimiter.join(map(str, edge)) def parse_edgelist( diff --git a/networkx/algorithms/centrality/katz.py b/networkx/algorithms/centrality/katz.py index 523dce04..236f2c61 100644 --- a/networkx/algorithms/centrality/katz.py +++ b/networkx/algorithms/centrality/katz.py @@ -176,8 +176,8 @@ def katz_centrality( x[n] = alpha * x[n] + b[n] # check convergence - err = sum(abs(x[n] - xlast[n]) for n in x) - if err < nnodes * tol: + error = sum(abs(x[n] - xlast[n]) for n in x) + if error < nnodes * tol: if normalized: # normalize vector try: diff --git a/networkx/algorithms/community/lukes.py b/networkx/algorithms/community/lukes.py index 6fe1d0de..b34077a2 100644 --- a/networkx/algorithms/community/lukes.py +++ b/networkx/algorithms/community/lukes.py @@ -17,7 +17,7 @@ PKEY = "partitions" CLUSTER_EVAL_CACHE_SIZE = 2048 -def _split_n_from(n: int, min_size_of_first_part: int): +def _split_n_from(n, min_size_of_first_part): # splits j in two parts of which the first is at least # the second argument assert n >= min_size_of_first_part @@ -25,7 +25,7 @@ def _split_n_from(n: int, min_size_of_first_part: int): yield p1, n - p1 -def lukes_partitioning(G, max_size: int, node_weight=None, edge_weight=None) -> list: +def lukes_partitioning(G, max_size, node_weight=None, edge_weight=None): """Optimal partitioning of a weighted tree using the Lukes algorithm. @@ -130,23 +130,23 @@ def lukes_partitioning(G, max_size: int, node_weight=None, edge_weight=None) -> return n @lru_cache(CLUSTER_EVAL_CACHE_SIZE) - def _value_of_cluster(cluster: frozenset): + def _value_of_cluster(cluster): valid_edges = [e for e in safe_G.edges if e[0] in cluster and e[1] in cluster] return sum(safe_G.edges[e][edge_weight] for e in valid_edges) - def _value_of_partition(partition: list): + def _value_of_partition(partition): return sum(_value_of_cluster(frozenset(c)) for c in partition) @lru_cache(CLUSTER_EVAL_CACHE_SIZE) - def _weight_of_cluster(cluster: frozenset): + def _weight_of_cluster(cluster): return sum(safe_G.nodes[n][node_weight] for n in cluster) - def _pivot(partition: list, node): + def _pivot(partition, node): ccx = [c for c in partition if node in c] assert len(ccx) == 1 return ccx[0] - def _concatenate_or_merge(partition_1: list, partition_2: list, x, i, ref_weigth): + def _concatenate_or_merge(partition_1, partition_2, x, i, ref_weigth): ccx = _pivot(partition_1, x) cci = _pivot(partition_2, i) diff --git a/networkx/algorithms/connectivity/__init__.py b/networkx/algorithms/connectivity/__init__.py index 65490c00..15bc5abe 100644 --- a/networkx/algorithms/connectivity/__init__.py +++ b/networkx/algorithms/connectivity/__init__.py @@ -9,18 +9,3 @@ from .kcomponents import * from .kcutsets import * from .stoerwagner import * from .utils import * - -__all__ = sum( - [ - connectivity.__all__, - cuts.__all__, - edge_augmentation.__all__, - edge_kcomponents.__all__, - disjoint_paths.__all__, - kcomponents.__all__, - kcutsets.__all__, - stoerwagner.__all__, - utils.__all__, - ], - [], -) diff --git a/networkx/algorithms/d_separation.py b/networkx/algorithms/d_separation.py index 9d41e2d8..29f1b7cd 100644 --- a/networkx/algorithms/d_separation.py +++ b/networkx/algorithms/d_separation.py @@ -67,7 +67,7 @@ __all__ = ["d_separated"] @not_implemented_for("undirected") -def d_separated(G: nx.DiGraph, x: AbstractSet, y: AbstractSet, z: AbstractSet) -> bool: +def d_separated(G, x, y, z): """ Return whether node sets ``x`` and ``y`` are d-separated by ``z``. diff --git a/networkx/algorithms/flow/tests/test_maxflow.py b/networkx/algorithms/flow/tests/test_maxflow.py index 17b82b4d..9bb69198 100644 --- a/networkx/algorithms/flow/tests/test_maxflow.py +++ b/networkx/algorithms/flow/tests/test_maxflow.py @@ -19,7 +19,7 @@ flow_funcs = [ ] max_min_funcs = [nx.maximum_flow, nx.minimum_cut] flow_value_funcs = [nx.maximum_flow_value, nx.minimum_cut_value] -interface_funcs = sum([max_min_funcs, flow_value_funcs], []) +interface_funcs = max_min_funcs + flow_value_funcs all_funcs = sum([flow_funcs, interface_funcs], []) diff --git a/networkx/algorithms/shortest_paths/tests/test_weighted.py b/networkx/algorithms/shortest_paths/tests/test_weighted.py index 032b189d..15a219ee 100644 --- a/networkx/algorithms/shortest_paths/tests/test_weighted.py +++ b/networkx/algorithms/shortest_paths/tests/test_weighted.py @@ -838,7 +838,7 @@ class TestBellmanFordAndGoldbergRadzik(WeightedTestBase): assert pred[3] == 0 assert dist == {0: 0, 1: 1, 2: 2, 3: 1} - def test_negative_weight(self): + def test_negative_weight_bf_path(self): G = nx.DiGraph() G.add_nodes_from("abcd") G.add_edge("a", "d", weight=0) diff --git a/networkx/algorithms/tests/test_cycles.py b/networkx/algorithms/tests/test_cycles.py index d509e41c..737d29f4 100644 --- a/networkx/algorithms/tests/test_cycles.py +++ b/networkx/algorithms/tests/test_cycles.py @@ -4,9 +4,7 @@ import networkx as nx from networkx.algorithms import find_cycle from networkx.algorithms import minimum_cycle_basis - -FORWARD = nx.algorithms.edgedfs.FORWARD -REVERSE = nx.algorithms.edgedfs.REVERSE +from networkx.algorithms.traversal.edgedfs import FORWARD, REVERSE class TestCycles: diff --git a/networkx/algorithms/tests/test_graph_hashing.py b/networkx/algorithms/tests/test_graph_hashing.py index 70130b39..c76a66e1 100644 --- a/networkx/algorithms/tests/test_graph_hashing.py +++ b/networkx/algorithms/tests/test_graph_hashing.py @@ -455,7 +455,7 @@ def test_missing_node_attr_subgraph_hash(): ) -def test_isomorphic_edge_attr_and_node_attr(): +def test_isomorphic_edge_attr_and_node_attr_subgraph_hash(): """ Isomorphic graphs with differing node attributes should yield different subgraph hashes if the 'node_attr' and 'edge_attr' argument is supplied and populated in diff --git a/networkx/algorithms/tests/test_smallworld.py b/networkx/algorithms/tests/test_smallworld.py index b6219133..e56f9a6a 100644 --- a/networkx/algorithms/tests/test_smallworld.py +++ b/networkx/algorithms/tests/test_smallworld.py @@ -7,7 +7,6 @@ import random from networkx import random_reference, lattice_reference, sigma, omega import networkx as nx -rng = random.Random(0) rng = 42 diff --git a/networkx/algorithms/traversal/tests/test_edgebfs.py b/networkx/algorithms/traversal/tests/test_edgebfs.py index 170be25c..1bf3fae0 100644 --- a/networkx/algorithms/traversal/tests/test_edgebfs.py +++ b/networkx/algorithms/traversal/tests/test_edgebfs.py @@ -1,11 +1,7 @@ import pytest import networkx as nx - -edge_bfs = nx.edge_bfs - -FORWARD = nx.algorithms.edgedfs.FORWARD -REVERSE = nx.algorithms.edgedfs.REVERSE +from networkx.algorithms.traversal.edgedfs import FORWARD, REVERSE class TestEdgeBFS: @@ -16,42 +12,42 @@ class TestEdgeBFS: def test_empty(self): G = nx.Graph() - edges = list(edge_bfs(G)) + edges = list(nx.edge_bfs(G)) assert edges == [] def test_graph_single_source(self): G = nx.Graph(self.edges) G.add_edge(4, 5) - x = list(edge_bfs(G, [0])) + x = list(nx.edge_bfs(G, [0])) x_ = [(0, 1), (0, 2), (1, 2), (1, 3)] assert x == x_ def test_graph(self): G = nx.Graph(self.edges) - x = list(edge_bfs(G, self.nodes)) + x = list(nx.edge_bfs(G, self.nodes)) x_ = [(0, 1), (0, 2), (1, 2), (1, 3)] assert x == x_ def test_digraph(self): G = nx.DiGraph(self.edges) - x = list(edge_bfs(G, self.nodes)) + x = list(nx.edge_bfs(G, self.nodes)) x_ = [(0, 1), (1, 0), (2, 0), (2, 1), (3, 1)] assert x == x_ def test_digraph_orientation_invalid(self): G = nx.DiGraph(self.edges) - edge_iterator = edge_bfs(G, self.nodes, orientation="hello") + edge_iterator = nx.edge_bfs(G, self.nodes, orientation="hello") pytest.raises(nx.NetworkXError, list, edge_iterator) def test_digraph_orientation_none(self): G = nx.DiGraph(self.edges) - x = list(edge_bfs(G, self.nodes, orientation=None)) + x = list(nx.edge_bfs(G, self.nodes, orientation=None)) x_ = [(0, 1), (1, 0), (2, 0), (2, 1), (3, 1)] assert x == x_ def test_digraph_orientation_original(self): G = nx.DiGraph(self.edges) - x = list(edge_bfs(G, self.nodes, orientation="original")) + x = list(nx.edge_bfs(G, self.nodes, orientation="original")) x_ = [ (0, 1, FORWARD), (1, 0, FORWARD), @@ -64,13 +60,13 @@ class TestEdgeBFS: def test_digraph2(self): G = nx.DiGraph() nx.add_path(G, range(4)) - x = list(edge_bfs(G, [0])) + x = list(nx.edge_bfs(G, [0])) x_ = [(0, 1), (1, 2), (2, 3)] assert x == x_ def test_digraph_rev(self): G = nx.DiGraph(self.edges) - x = list(edge_bfs(G, self.nodes, orientation="reverse")) + x = list(nx.edge_bfs(G, self.nodes, orientation="reverse")) x_ = [ (1, 0, REVERSE), (2, 0, REVERSE), @@ -83,13 +79,13 @@ class TestEdgeBFS: def test_digraph_rev2(self): G = nx.DiGraph() nx.add_path(G, range(4)) - x = list(edge_bfs(G, [3], orientation="reverse")) + x = list(nx.edge_bfs(G, [3], orientation="reverse")) x_ = [(2, 3, REVERSE), (1, 2, REVERSE), (0, 1, REVERSE)] assert x == x_ def test_multigraph(self): G = nx.MultiGraph(self.edges) - x = list(edge_bfs(G, self.nodes)) + x = list(nx.edge_bfs(G, self.nodes)) x_ = [(0, 1, 0), (0, 1, 1), (0, 1, 2), (0, 2, 0), (1, 2, 0), (1, 3, 0)] # This is an example of where hash randomization can break. # There are 3! * 2 alternative outputs, such as: @@ -101,13 +97,13 @@ class TestEdgeBFS: def test_multidigraph(self): G = nx.MultiDiGraph(self.edges) - x = list(edge_bfs(G, self.nodes)) + x = list(nx.edge_bfs(G, self.nodes)) x_ = [(0, 1, 0), (1, 0, 0), (1, 0, 1), (2, 0, 0), (2, 1, 0), (3, 1, 0)] assert x == x_ def test_multidigraph_rev(self): G = nx.MultiDiGraph(self.edges) - x = list(edge_bfs(G, self.nodes, orientation="reverse")) + x = list(nx.edge_bfs(G, self.nodes, orientation="reverse")) x_ = [ (1, 0, 0, REVERSE), (1, 0, 1, REVERSE), @@ -120,7 +116,7 @@ class TestEdgeBFS: def test_digraph_ignore(self): G = nx.DiGraph(self.edges) - x = list(edge_bfs(G, self.nodes, orientation="ignore")) + x = list(nx.edge_bfs(G, self.nodes, orientation="ignore")) x_ = [ (0, 1, FORWARD), (1, 0, REVERSE), @@ -133,13 +129,13 @@ class TestEdgeBFS: def test_digraph_ignore2(self): G = nx.DiGraph() nx.add_path(G, range(4)) - x = list(edge_bfs(G, [0], orientation="ignore")) + x = list(nx.edge_bfs(G, [0], orientation="ignore")) x_ = [(0, 1, FORWARD), (1, 2, FORWARD), (2, 3, FORWARD)] assert x == x_ def test_multidigraph_ignore(self): G = nx.MultiDiGraph(self.edges) - x = list(edge_bfs(G, self.nodes, orientation="ignore")) + x = list(nx.edge_bfs(G, self.nodes, orientation="ignore")) x_ = [ (0, 1, 0, FORWARD), (1, 0, 0, REVERSE), diff --git a/networkx/algorithms/traversal/tests/test_edgedfs.py b/networkx/algorithms/traversal/tests/test_edgedfs.py index 6c12ae21..7c1967cc 100644 --- a/networkx/algorithms/traversal/tests/test_edgedfs.py +++ b/networkx/algorithms/traversal/tests/test_edgedfs.py @@ -1,11 +1,8 @@ import pytest import networkx as nx - -edge_dfs = nx.algorithms.edge_dfs - -FORWARD = nx.algorithms.edgedfs.FORWARD -REVERSE = nx.algorithms.edgedfs.REVERSE +from networkx.algorithms import edge_dfs +from networkx.algorithms.traversal.edgedfs import FORWARD, REVERSE # These tests can fail with hash randomization. The easiest and clearest way # to write these unit tests is for the edges to be output in an expected total |
