From e1582cfede521e7c222b4ca2fa8b43245acde56c Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Fri, 19 Jan 2024 09:57:50 -0500 Subject: [PATCH] Finalize type signatures and enforce for all future functions This commit adds the last few missing type hints (primarily the generators module) and switches the CI configuration over to enforce that the library is completely type hinted. This makes it a CI error if a function or method is added that doesn't include type hints. This is all built on the hard work of @IvanIsCoding who built up all the type hinting infrastructure and stub files for the majority of rustworkx. This is just the last piece to enforce the library is fully typed moving forward. Co-authored-by: Ivan Carvalho --- rustworkx/__init__.pyi | 1 + rustworkx/dag_algo.pyi | 8 ++- rustworkx/generators.pyi | 135 ++++++++++++++++++++++++++++++++++++ rustworkx/py.typed | 1 - rustworkx/shortest_path.pyi | 17 +++++ tox.ini | 2 +- 6 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 rustworkx/generators.pyi diff --git a/rustworkx/__init__.pyi b/rustworkx/__init__.pyi index e41baef086..823193eae2 100644 --- a/rustworkx/__init__.pyi +++ b/rustworkx/__init__.pyi @@ -11,6 +11,7 @@ import numpy as np import rustworkx.visit as visit +import rustworkx.generators as generators from .rustworkx import * from typing import Generic, TypeVar, Any, Callable, Iterator, overload diff --git a/rustworkx/dag_algo.pyi b/rustworkx/dag_algo.pyi index 939b707dc0..a174c28fce 100644 --- a/rustworkx/dag_algo.pyi +++ b/rustworkx/dag_algo.pyi @@ -12,7 +12,7 @@ from .iterators import * from .digraph import PyDiGraph -from typing import TypeVar, Callable +from typing import TypeVar, Callable, final _S = TypeVar("_S") _T = TypeVar("_T") @@ -57,3 +57,9 @@ def layers( /, index_output: bool = ..., ) -> list[_S] | list[int]: ... +@final +class TopologicalSorter: + def __init__(self, dag: PyDiGraph, check_cycle: bool) -> None: ... + def is_active(self) -> bool: ... + def get_ready(self) -> list[int]: ... + def done(self, nodes: Sequence[int]) -> None: ... diff --git a/rustworkx/generators.pyi b/rustworkx/generators.pyi new file mode 100644 index 0000000000..bc05df76c0 --- /dev/null +++ b/rustworkx/generators.pyi @@ -0,0 +1,135 @@ +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +# This file contains only type annotations for PyO3 functions and classes +# For implementation details, see __init__.py and src/shortest_path/mod.rs + +import numpy as np + +from .iterators import * +from .graph import PyGraph +from .digraph import PyDiGraph + +from typing import Sequence, Any + +def cycle_graph( + num_nodes: int | None = ..., weights: Sequence[Any] | None = ..., multigraph: bool = ... +) -> PyGraph: ... +def directed_cycle_graph( + num_nodes: int | None = ..., + weights: Sequence[Any] | None = ..., + bidirectional: bool = ..., + multigraph: bool = ..., +) -> PyDiGraph: ... +def path_graph( + num_nodes: int | None = ..., weights: Sequence[Any] | None = ..., multigraph: bool = ... +) -> PyGraph: ... +def directed_path_graph( + num_nodes: int | None = ..., + weights: Sequence[Any] | None = ..., + bidirectional: bool = ..., + multigraph: bool = ..., +) -> PyDiGraph: ... +def star_graph( + num_nodes: int | None = ..., weights: Sequence[Any] | None = ..., multigraph: bool = ... +) -> PyGraph: ... +def directed_star_graph( + num_nodes: int | None = ..., + weights: Sequence[Any] | None = ..., + inward: bool = ..., + bidirectional: bool = ..., + multigraph: bool = ..., +) -> PyDiGraph: ... +def mesh_graph( + num_nodes: int | None = ..., weights: Sequence[Any] | None = ..., multigraph: bool = ... +) -> PyGraph: ... +def directed_mesh_graph( + num_nodes: int | None = ..., + weights: Sequence[Any] | None = ..., + multigraph: bool = ..., +) -> PyDiGraph: ... +def grid_graph( + rows: int | None = ..., + cols: int | None = ..., + weights: Sequence[Any] | None = ..., + multigraph: bool = ..., +) -> PyGraph: ... +def directed_grid_graph( + rows: int | None = ..., + cols: int | None = ..., + weights: Sequence[Any] | None = ..., + bidirectional: bool = ..., + multigraph: bool = ..., +) -> PyDiGraph: ... +def heavy_square_graph(d: int, multigraph: bool = ...) -> PyGraph: ... +def directed_heavy_square_graph( + d: int, + bidirectional: bool = ..., + multigraph: bool = ..., +) -> PyDiGraph: ... +def heavy_hex_graph(d: int, multigraph: bool = ...) -> PyGraph: ... +def directed_heavy_hex_graph( + d: int, + bidirectional: bool = ..., + multigraph: bool = ..., +) -> PyDiGraph: ... +def binomial_tree_graph( + order: int, weights: Sequence[Any] | None = ..., multigraph: bool = ... +) -> PyGraph: ... +def directed_binomial_tree_graph( + order: int, + weights: Sequence[Any] | None = ..., + bidirectional: bool = ..., + multigraph: bool = ..., +) -> PyDiGraph: ... +def full_rary_tree( + branching_factor: int, + num_nodes: int, + weights: Sequence[Any] | None = ..., + multigraph: bool = ..., +) -> PyGraph: ... +def hexagonal_lattice_graph(rows: int, cols: int, multigraph: bool = ...) -> PyGraph: ... +def directed_hexagonal_lattice_graph( + rows: int, + cols: int, + bidirectional: bool = ..., + multigraph: bool = ..., +) -> PyDiGraph: ... +def lollipop_graph( + num_mesh_nodes: int | None = ..., + num_path_nodes: int | None = ..., + mesh_weights: Sequence[Any] | None = ..., + path_weights: Sequence[Any] | None = ..., + multigraph: bool = ..., +) -> PyGraph: ... +def barbell_graph( + num_mesh_nodes: int | None = ..., + num_path_nodes: int | None = ..., + multigraph: bool = ..., + mesh_weights: Sequence[Any] | None = ..., + path_weights: Sequence[Any] | None = ..., +) -> PyGraph: ... +def generalized_petersen_graph( + n: int, + k: int, + multigraph: bool = ..., +) -> PyGraph: ... +def empty_graph(n: int, multigraph: bool = ...) -> PyGraph: + ..., + +def directed_empty_graph(n: int, multigraph: bool = ...) -> PyDiGraph: + ..., + +def complete_graph( + num_nodes: int | None = ..., weights: Sequence[Any] | None = ..., multigraph: bool = ... +) -> PyGraph: ... +def directed_complete_graph( + num_nodes: int | None = ..., + weights: Sequence[Any] | None = ..., + multigraph: bool = ..., +) -> PyDiGraph: ... diff --git a/rustworkx/py.typed b/rustworkx/py.typed index b648ac9233..e69de29bb2 100644 --- a/rustworkx/py.typed +++ b/rustworkx/py.typed @@ -1 +0,0 @@ -partial diff --git a/rustworkx/shortest_path.pyi b/rustworkx/shortest_path.pyi index c84b90b689..3d9e632a86 100644 --- a/rustworkx/shortest_path.pyi +++ b/rustworkx/shortest_path.pyi @@ -257,3 +257,20 @@ def negative_edge_cycle( edge_cost_fn: Callable[[_T], float], /, ) -> bool: ... +def digraph_all_shortest_paths( + graph: PyDiGraph[_S, _T], + source: int, + target: int, + /, + weight_fn: Callable[_T, float] | None = ..., + default_weight: float = ..., + as_undirected: bool = ..., +) -> list[list[int]]: ... +def graph_all_shortest_paths( + graph: PyGraph[_S, _T], + source: int, + target: int, + /, + weight_fn: Callable[_T, float] | None = ..., + default_weight: float = ..., +) -> list[list[int]]: ... diff --git a/tox.ini b/tox.ini index 977e918398..530b85adab 100644 --- a/tox.ini +++ b/tox.ini @@ -76,4 +76,4 @@ commands = black {posargs} '../rustworkx' '../tests' '../retworkx' basepython = python3 deps = mypy==1.0.1 -commands = python -m mypy.stubtest --concise --ignore-missing-stub rustworkx.rustworkx +commands = python -m mypy.stubtest --concise rustworkx.rustworkx