From e1582cfede521e7c222b4ca2fa8b43245acde56c Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Fri, 19 Jan 2024 09:57:50 -0500 Subject: [PATCH 01/19] 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 From c6fba0375fc64c5e75506354e46f61d6248ea086 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Fri, 19 Jan 2024 12:08:50 -0500 Subject: [PATCH 02/19] Fix lint --- rustworkx/__init__.pyi | 2 +- rustworkx/generators.pyi | 10 ++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/rustworkx/__init__.pyi b/rustworkx/__init__.pyi index 823193eae2..23dde0b6f9 100644 --- a/rustworkx/__init__.pyi +++ b/rustworkx/__init__.pyi @@ -11,7 +11,7 @@ import numpy as np import rustworkx.visit as visit -import rustworkx.generators as generators +import rustworkx.generators as generators # noqa from .rustworkx import * from typing import Generic, TypeVar, Any, Callable, Iterator, overload diff --git a/rustworkx/generators.pyi b/rustworkx/generators.pyi index bc05df76c0..5f053a7f7c 100644 --- a/rustworkx/generators.pyi +++ b/rustworkx/generators.pyi @@ -9,8 +9,6 @@ # 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 @@ -119,12 +117,8 @@ def generalized_petersen_graph( k: int, multigraph: bool = ..., ) -> PyGraph: ... -def empty_graph(n: int, multigraph: bool = ...) -> PyGraph: - ..., - -def directed_empty_graph(n: int, multigraph: bool = ...) -> PyDiGraph: - ..., - +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: ... From 30384980617a5335c17d90c663e1e0806debed87 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Fri, 19 Jan 2024 13:27:58 -0500 Subject: [PATCH 03/19] Add missing stubs and run on full package --- rustworkx/__init__.py | 2 -- rustworkx/dag_algo.pyi | 2 +- rustworkx/digraph.pyi | 16 +++++++++--- rustworkx/generators/__init__.py | 9 +++++++ .../__init__.pyi} | 5 ++-- rustworkx/graph.pyi | 15 ++++++++--- rustworkx/rustworkx.pyi | 1 + rustworkx/shortest_path.pyi | 4 +-- rustworkx/visualization/graphviz.py | 26 ++++++++++++------- tox.ini | 2 +- 10 files changed, 57 insertions(+), 25 deletions(-) create mode 100644 rustworkx/generators/__init__.py rename rustworkx/{generators.pyi => generators/__init__.pyi} (98%) diff --git a/rustworkx/__init__.py b/rustworkx/__init__.py index ae158c6e31..fe6774bfc8 100644 --- a/rustworkx/__init__.py +++ b/rustworkx/__init__.py @@ -15,8 +15,6 @@ # flake8: noqa import rustworkx.visit -sys.modules["rustworkx.generators"] = generators - class PyDAG(PyDiGraph): """A class for creating direct acyclic graphs. diff --git a/rustworkx/dag_algo.pyi b/rustworkx/dag_algo.pyi index a174c28fce..7923939d8f 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, final +from typing import TypeVar, Callable, final, Sequence _S = TypeVar("_S") _T = TypeVar("_T") diff --git a/rustworkx/digraph.pyi b/rustworkx/digraph.pyi index ae470846f7..2a7911c1e0 100644 --- a/rustworkx/digraph.pyi +++ b/rustworkx/digraph.pyi @@ -12,7 +12,7 @@ import numpy as np from .iterators import * -from typing import Any, Callable, Generic, TypeVar, Sequence, TYPE_CHECKING +from typing import Any, Callable, Generic, TypeVar, Sequence, TYPE_CHECKING, overload if TYPE_CHECKING: from .graph import PyGraph @@ -160,14 +160,22 @@ class PyDiGraph(Generic[S, T]): ) -> NodeMap: ... def successor_indices(self, node: int, /) -> NodeIndices: ... def successors(self, node: int, /) -> list[S]: ... + @overload + def to_dot( + self, + node_attr: Callable[[S], dict[str, str]] | None = ..., + edge_attr: Callable[[T], dict[str, str]] | None = ..., + graph_attr: dict[str, str] | None = ..., + filename: str = ..., + ) -> None: ... + @overload def to_dot( self, - /, node_attr: Callable[[S], dict[str, str]] | None = ..., edge_attr: Callable[[T], dict[str, str]] | None = ..., graph_attr: dict[str, str] | None = ..., - filename: str | None = ..., - ) -> str | None: ... + filename: None = ..., + ) -> str: ... def to_undirected( self, /, diff --git a/rustworkx/generators/__init__.py b/rustworkx/generators/__init__.py new file mode 100644 index 0000000000..190a31e8f9 --- /dev/null +++ b/rustworkx/generators/__init__.py @@ -0,0 +1,9 @@ +# 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. + +from rustworkx.rustworkx.generators import * # noqa diff --git a/rustworkx/generators.pyi b/rustworkx/generators/__init__.pyi similarity index 98% rename from rustworkx/generators.pyi rename to rustworkx/generators/__init__.pyi index 5f053a7f7c..2e295478c5 100644 --- a/rustworkx/generators.pyi +++ b/rustworkx/generators/__init__.pyi @@ -9,9 +9,8 @@ # This file contains only type annotations for PyO3 functions and classes # For implementation details, see __init__.py and src/shortest_path/mod.rs -from .iterators import * -from .graph import PyGraph -from .digraph import PyDiGraph +from rustworkx import PyGraph +from rustworkx import PyDiGraph from typing import Sequence, Any diff --git a/rustworkx/graph.pyi b/rustworkx/graph.pyi index d710f6a1d8..36355ceef0 100644 --- a/rustworkx/graph.pyi +++ b/rustworkx/graph.pyi @@ -19,6 +19,7 @@ from typing import ( TypeVar, Sequence, TYPE_CHECKING, + overload, ) if TYPE_CHECKING: @@ -132,14 +133,22 @@ class PyGraph(Generic[S, T]): node_filter: Callable[[S], bool] | None = ..., edge_weight_map: Callable[[T], T] | None = ..., ) -> NodeMap: ... + @overload + def to_dot( + self, + node_attr: Callable[[S], dict[str, str]] | None = ..., + edge_attr: Callable[[T], dict[str, str]] | None = ..., + graph_attr: dict[str, str] | None = ..., + filename: str = ..., + ) -> None: ... + @overload def to_dot( self, - /, node_attr: Callable[[S], dict[str, str]] | None = ..., edge_attr: Callable[[T], dict[str, str]] | None = ..., graph_attr: dict[str, str] | None = ..., - filename: str | None = ..., - ) -> str | None: ... + filename: None = ..., + ) -> str: ... def to_directed(self) -> PyDiGraph[S, T]: ... def update_edge( self, diff --git a/rustworkx/rustworkx.pyi b/rustworkx/rustworkx.pyi index d986e6259d..ca4eea0e48 100644 --- a/rustworkx/rustworkx.pyi +++ b/rustworkx/rustworkx.pyi @@ -33,6 +33,7 @@ from .tree import * from .tensor_product import * from .token_swapper import * from .union import * +from . import generators as generators class DAGHasCycle(Exception): ... class DAGWouldCycle(Exception): ... diff --git a/rustworkx/shortest_path.pyi b/rustworkx/shortest_path.pyi index 3d9e632a86..2a6b7b243a 100644 --- a/rustworkx/shortest_path.pyi +++ b/rustworkx/shortest_path.pyi @@ -262,7 +262,7 @@ def digraph_all_shortest_paths( source: int, target: int, /, - weight_fn: Callable[_T, float] | None = ..., + weight_fn: Callable[[_T], float] | None = ..., default_weight: float = ..., as_undirected: bool = ..., ) -> list[list[int]]: ... @@ -271,6 +271,6 @@ def graph_all_shortest_paths( source: int, target: int, /, - weight_fn: Callable[_T, float] | None = ..., + weight_fn: Callable[[_T], float] | None = ..., default_weight: float = ..., ) -> list[list[int]]: ... diff --git a/rustworkx/visualization/graphviz.py b/rustworkx/visualization/graphviz.py index 4d51988144..0db04a6f9c 100644 --- a/rustworkx/visualization/graphviz.py +++ b/rustworkx/visualization/graphviz.py @@ -9,14 +9,22 @@ import subprocess import tempfile import io +from typing import TypeVar, Callable + +from rustworkx import PyDiGraph, PyGraph + try: - from PIL import Image + from PIL import Image # type: ignore HAS_PILLOW = True except ImportError: HAS_PILLOW = False +_S = TypeVar("_S") +_T = TypeVar("_T") + + __all__ = ["graphviz_draw"] METHODS = {"twopi", "neato", "circo", "fdp", "sfdp", "dot"} @@ -60,14 +68,14 @@ def graphviz_draw( - graph, - node_attr_fn=None, - edge_attr_fn=None, - graph_attr=None, - filename=None, - image_type=None, - method=None, -): + graph: "PyDiGraph[_S, _T] | PyGraph[_S, _T]", + node_attr_fn: Callable[[_S], dict[str, str]] | None = None, + edge_attr_fn: Callable[[_T], dict[str, str]] | None = None, + graph_attr: dict[str, str] | None = None, + filename: str | None = None, + image_type: str | None = None, + method: str | None = None, +) -> "Image | None": """Draw a :class:`~rustworkx.PyGraph` or :class:`~rustworkx.PyDiGraph` object using graphviz diff --git a/tox.ini b/tox.ini index 530b85adab..b16da749e4 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 rustworkx.rustworkx +commands = python -m mypy.stubtest --concise rustworkx From e9833e0cea449b87f8593071b4a8baa7c13366c4 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Fri, 19 Jan 2024 14:14:23 -0500 Subject: [PATCH 04/19] Fix to_dot() and graphviz_draw() hints --- rustworkx/digraph.pyi | 14 +++----------- rustworkx/graph.pyi | 14 +++----------- rustworkx/visualization/graphviz.py | 12 +++++++----- 3 files changed, 13 insertions(+), 27 deletions(-) diff --git a/rustworkx/digraph.pyi b/rustworkx/digraph.pyi index 2a7911c1e0..4ae5ccd383 100644 --- a/rustworkx/digraph.pyi +++ b/rustworkx/digraph.pyi @@ -160,22 +160,14 @@ class PyDiGraph(Generic[S, T]): ) -> NodeMap: ... def successor_indices(self, node: int, /) -> NodeIndices: ... def successors(self, node: int, /) -> list[S]: ... - @overload - def to_dot( - self, - node_attr: Callable[[S], dict[str, str]] | None = ..., - edge_attr: Callable[[T], dict[str, str]] | None = ..., - graph_attr: dict[str, str] | None = ..., - filename: str = ..., - ) -> None: ... - @overload def to_dot( self, + /, node_attr: Callable[[S], dict[str, str]] | None = ..., edge_attr: Callable[[T], dict[str, str]] | None = ..., graph_attr: dict[str, str] | None = ..., - filename: None = ..., - ) -> str: ... + filename: str | None = None, + ) -> str | None: ... def to_undirected( self, /, diff --git a/rustworkx/graph.pyi b/rustworkx/graph.pyi index 36355ceef0..fe503f2bf5 100644 --- a/rustworkx/graph.pyi +++ b/rustworkx/graph.pyi @@ -133,22 +133,14 @@ class PyGraph(Generic[S, T]): node_filter: Callable[[S], bool] | None = ..., edge_weight_map: Callable[[T], T] | None = ..., ) -> NodeMap: ... - @overload - def to_dot( - self, - node_attr: Callable[[S], dict[str, str]] | None = ..., - edge_attr: Callable[[T], dict[str, str]] | None = ..., - graph_attr: dict[str, str] | None = ..., - filename: str = ..., - ) -> None: ... - @overload def to_dot( self, + /, node_attr: Callable[[S], dict[str, str]] | None = ..., edge_attr: Callable[[T], dict[str, str]] | None = ..., graph_attr: dict[str, str] | None = ..., - filename: None = ..., - ) -> str: ... + filename: str | None = None, + ) -> str | None: ... def to_directed(self) -> PyDiGraph[S, T]: ... def update_edge( self, diff --git a/rustworkx/visualization/graphviz.py b/rustworkx/visualization/graphviz.py index 0db04a6f9c..bea27fbe3a 100644 --- a/rustworkx/visualization/graphviz.py +++ b/rustworkx/visualization/graphviz.py @@ -6,10 +6,12 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. +from __future__ import annotations + import subprocess import tempfile import io -from typing import TypeVar, Callable +from typing import TypeVar, Callable, Dict, cast from rustworkx import PyDiGraph, PyGraph @@ -69,9 +71,9 @@ def graphviz_draw( graph: "PyDiGraph[_S, _T] | PyGraph[_S, _T]", - node_attr_fn: Callable[[_S], dict[str, str]] | None = None, - edge_attr_fn: Callable[[_T], dict[str, str]] | None = None, - graph_attr: dict[str, str] | None = None, + node_attr_fn: Callable[[_S], Dict[str, str]] | None = None, + edge_attr_fn: Callable[[_T], Dict[str, str]] | None = None, + graph_attr: Dict[str, str] | None = None, filename: str | None = None, image_type: str | None = None, method: str | None = None, @@ -169,7 +171,7 @@ def node_attr(node): "instructions." ) - dot_str = graph.to_dot(node_attr_fn, edge_attr_fn, graph_attr) + dot_str = cast(str, graph.to_dot(node_attr_fn, edge_attr_fn, graph_attr)) if image_type is None: output_format = "png" else: From 7fb46d82afa910a7cf8ea44e364f36b86c40788f Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Fri, 19 Jan 2024 14:20:00 -0500 Subject: [PATCH 05/19] Fix lint --- rustworkx/digraph.pyi | 2 +- rustworkx/graph.pyi | 1 - rustworkx/visualization/graphviz.py | 15 +++++++++------ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/rustworkx/digraph.pyi b/rustworkx/digraph.pyi index 4ae5ccd383..a012b9b847 100644 --- a/rustworkx/digraph.pyi +++ b/rustworkx/digraph.pyi @@ -12,7 +12,7 @@ import numpy as np from .iterators import * -from typing import Any, Callable, Generic, TypeVar, Sequence, TYPE_CHECKING, overload +from typing import Any, Callable, Generic, TypeVar, Sequence, TYPE_CHECKING if TYPE_CHECKING: from .graph import PyGraph diff --git a/rustworkx/graph.pyi b/rustworkx/graph.pyi index fe503f2bf5..c4636e79f2 100644 --- a/rustworkx/graph.pyi +++ b/rustworkx/graph.pyi @@ -19,7 +19,6 @@ from typing import ( TypeVar, Sequence, TYPE_CHECKING, - overload, ) if TYPE_CHECKING: diff --git a/rustworkx/visualization/graphviz.py b/rustworkx/visualization/graphviz.py index bea27fbe3a..6d614e47d9 100644 --- a/rustworkx/visualization/graphviz.py +++ b/rustworkx/visualization/graphviz.py @@ -11,7 +11,7 @@ import subprocess import tempfile import io -from typing import TypeVar, Callable, Dict, cast +from typing import TypeVar, Callable, cast, TYPE_CHECKING from rustworkx import PyDiGraph, PyGraph @@ -23,6 +23,9 @@ except ImportError: HAS_PILLOW = False +if TYPE_CHECKING: + from PIL import Image # type: ignore + _S = TypeVar("_S") _T = TypeVar("_T") @@ -70,14 +73,14 @@ def graphviz_draw( - graph: "PyDiGraph[_S, _T] | PyGraph[_S, _T]", - node_attr_fn: Callable[[_S], Dict[str, str]] | None = None, - edge_attr_fn: Callable[[_T], Dict[str, str]] | None = None, - graph_attr: Dict[str, str] | None = None, + graph: "PyDiGraph[_S, _T] | PyGraph[_S, _T]", # noqa + node_attr_fn: Callable[[_S], dict[str, str]] | None = None, + edge_attr_fn: Callable[[_T], dict[str, str]] | None = None, + graph_attr: dict[str, str] | None = None, filename: str | None = None, image_type: str | None = None, method: str | None = None, -) -> "Image | None": +) -> Image | None: """Draw a :class:`~rustworkx.PyGraph` or :class:`~rustworkx.PyDiGraph` object using graphviz From cffeceadf60843186ff977fd56348afe03a7177a Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Fri, 19 Jan 2024 14:20:37 -0500 Subject: [PATCH 06/19] Fix search function hints --- rustworkx/__init__.pyi | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rustworkx/__init__.pyi b/rustworkx/__init__.pyi index 23dde0b6f9..00335cf35b 100644 --- a/rustworkx/__init__.pyi +++ b/rustworkx/__init__.pyi @@ -514,19 +514,19 @@ def cartesian_product( ) -> tuple[PyDiGraph, ProductNodeMap]: ... def bfs_search( graph: PyGraph | PyDiGraph, - source: int | None = ..., - visitor: _BFSVisitor | None = ..., + source: int, + visitor: _BFSVisitor, ) -> None: ... def dfs_search( graph: PyGraph | PyDiGraph, - source: int | None = ..., - visitor: _DFSVisitor | None = ..., + source: int, + visitor: _DFSVisitor, ) -> None: ... def dijkstra_search( graph: PyGraph | PyDiGraph, - source: int | None = ..., - weight_fn: Callable[[Any], float] | None = ..., - visitor: _DijkstraVisitor | None = ..., + source: int, + weight_fn: Callable[[Any], float], + visitor: _DijkstraVisitor, ) -> None: ... def bellman_ford_shortest_paths( graph: PyGraph[_S, _T] | PyDiGraph[_S, _T], From 96b756f408b37eff0da91389d8114add712772a0 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Fri, 19 Jan 2024 15:28:52 -0500 Subject: [PATCH 07/19] Fix full package stubtest This commit fixes most of the package for stubtest to work. This primarily involves having the stubfiles match the package layout. Unfortunately this means we need to put the majority of the type hints in the stubfile for `rustworkx.rustworkx`. Having the stubfiles split up as before mypy complains that the module doesn't exist. For example, having the coloring functions in `rustworkx/coloring.pyi` causes a mypy error that `rustworkx.coloring` couldn't be imported. This causes the rustworkx.pyi file to be quite large, but I couldn't find a pattern to workaround this limitation. Aside from that a bunch of stubs needed to be updated as now that they're getting included in the stubtest run issues were caught. The one exception is the generators module where the custom `text_signature` set in the function definitions were incorrect and tripping up mypy, these were fixed by removing the `text_signature` fields. --- rustworkx/__init__.py | 2 + rustworkx/__init__.pyi | 208 ----- rustworkx/cartesian_product.pyi | 25 - rustworkx/centrality.pyi | 90 -- rustworkx/coloring.pyi | 21 - rustworkx/connectivity.pyi | 106 --- rustworkx/dag_algo.pyi | 65 -- rustworkx/digraph.pyi | 199 ----- rustworkx/graph.pyi | 165 ---- rustworkx/isomorphism.pyi | 80 -- rustworkx/iterators.pyi | 147 ---- rustworkx/layout.pyi | 126 --- rustworkx/line_graph.pyi | 14 - rustworkx/link_analysis.pyi | 39 - rustworkx/matching.pyi | 36 - rustworkx/planar.pyi | 14 - rustworkx/random_graph.pyi | 59 -- rustworkx/read_write.pyi | 35 - rustworkx/rustworkx.pyi | 1363 ++++++++++++++++++++++++++++++- rustworkx/shortest_path.pyi | 276 ------- rustworkx/tensor_product.pyi | 25 - rustworkx/token_swapper.pyi | 22 - rustworkx/transitivity.pyi | 16 - rustworkx/traversal.pyi | 62 -- rustworkx/tree.pyi | 40 - rustworkx/union.pyi | 33 - rustworkx/visit.pyi | 6 +- src/generators.rs | 25 - 28 files changed, 1343 insertions(+), 1956 deletions(-) delete mode 100644 rustworkx/cartesian_product.pyi delete mode 100644 rustworkx/centrality.pyi delete mode 100644 rustworkx/coloring.pyi delete mode 100644 rustworkx/connectivity.pyi delete mode 100644 rustworkx/dag_algo.pyi delete mode 100644 rustworkx/digraph.pyi delete mode 100644 rustworkx/graph.pyi delete mode 100644 rustworkx/isomorphism.pyi delete mode 100644 rustworkx/iterators.pyi delete mode 100644 rustworkx/layout.pyi delete mode 100644 rustworkx/line_graph.pyi delete mode 100644 rustworkx/link_analysis.pyi delete mode 100644 rustworkx/matching.pyi delete mode 100644 rustworkx/planar.pyi delete mode 100644 rustworkx/random_graph.pyi delete mode 100644 rustworkx/read_write.pyi delete mode 100644 rustworkx/shortest_path.pyi delete mode 100644 rustworkx/tensor_product.pyi delete mode 100644 rustworkx/token_swapper.pyi delete mode 100644 rustworkx/transitivity.pyi delete mode 100644 rustworkx/traversal.pyi delete mode 100644 rustworkx/tree.pyi delete mode 100644 rustworkx/union.pyi diff --git a/rustworkx/__init__.py b/rustworkx/__init__.py index fe6774bfc8..ae158c6e31 100644 --- a/rustworkx/__init__.py +++ b/rustworkx/__init__.py @@ -15,6 +15,8 @@ # flake8: noqa import rustworkx.visit +sys.modules["rustworkx.generators"] = generators + class PyDAG(PyDiGraph): """A class for creating direct acyclic graphs. diff --git a/rustworkx/__init__.pyi b/rustworkx/__init__.pyi index 00335cf35b..ec90282b3c 100644 --- a/rustworkx/__init__.pyi +++ b/rustworkx/__init__.pyi @@ -11,218 +11,10 @@ import numpy as np import rustworkx.visit as visit -import rustworkx.generators as generators # noqa from .rustworkx import * from typing import Generic, TypeVar, Any, Callable, Iterator, overload -from .graph import PyGraph as PyGraph -from .digraph import PyDiGraph as PyDiGraph - -from .cartesian_product import digraph_cartesian_product as digraph_cartesian_product -from .cartesian_product import graph_cartesian_product as graph_cartesian_product - -from .centrality import digraph_eigenvector_centrality as digraph_eigenvector_centrality -from .centrality import graph_eigenvector_centrality as graph_eigenvector_centrality -from .centrality import digraph_betweenness_centrality as digraph_betweenness_centrality -from .centrality import graph_betweenness_centrality as graph_betweenness_centrality -from .centrality import digraph_edge_betweenness_centrality as digraph_edge_betweenness_centrality -from .centrality import graph_edge_betweenness_centrality as graph_edge_betweenness_centrality -from .centrality import digraph_closeness_centrality as digraph_closeness_centrality -from .centrality import graph_closeness_centrality as graph_closeness_centrality -from .centrality import digraph_katz_centrality as digraph_katz_centrality -from .centrality import graph_katz_centrality as graph_katz_centrality - -from .coloring import graph_greedy_color as graph_greedy_color -from .coloring import graph_greedy_edge_color as graph_greedy_edge_color -from .coloring import graph_is_bipartite as graph_is_bipartite -from .coloring import digraph_is_bipartite as digraph_is_bipartite -from .coloring import graph_two_color as graph_two_color -from .coloring import digraph_two_color as digraph_two_color - -from .connectivity import connected_components as connected_components -from .connectivity import is_connected as is_connected -from .connectivity import is_weakly_connected as is_weakly_connected -from .connectivity import number_connected_components as number_connected_components -from .connectivity import number_weakly_connected_components as number_weakly_connected_components -from .connectivity import node_connected_component as node_connected_component -from .connectivity import strongly_connected_components as strongly_connected_components -from .connectivity import weakly_connected_components as weakly_connected_components -from .connectivity import digraph_adjacency_matrix as digraph_adjacency_matrix -from .connectivity import graph_adjacency_matrix as graph_adjacency_matrix -from .connectivity import cycle_basis as cycle_basis -from .connectivity import articulation_points as articulation_points -from .connectivity import biconnected_components as biconnected_components -from .connectivity import chain_decomposition as chain_decomposition -from .connectivity import digraph_find_cycle as digraph_find_cycle -from .connectivity import digraph_complement as digraph_complement -from .connectivity import graph_complement as graph_complement -from .connectivity import digraph_all_simple_paths as digraph_all_simple_paths -from .connectivity import graph_all_simple_paths as graph_all_simple_paths -from .connectivity import digraph_all_pairs_all_simple_paths as digraph_all_pairs_all_simple_paths -from .connectivity import graph_all_pairs_all_simple_paths as graph_all_pairs_all_simple_paths -from .connectivity import digraph_longest_simple_path as digraph_longest_simple_path -from .connectivity import graph_longest_simple_path as graph_longest_simple_path -from .connectivity import digraph_core_number as digraph_core_number -from .connectivity import graph_core_number as graph_core_number -from .connectivity import stoer_wagner_min_cut as stoer_wagner_min_cut -from .connectivity import simple_cycles as simple_cycles -from .connectivity import graph_isolates as graph_isolates -from .connectivity import digraph_isolates as digraph_isolates - -from .dag_algo import collect_runs as collect_runs -from .dag_algo import collect_bicolor_runs as collect_bicolor_runs -from .dag_algo import dag_longest_path as dag_longest_path -from .dag_algo import dag_longest_path_length as dag_longest_path_length -from .dag_algo import dag_weighted_longest_path as dag_weighted_longest_path -from .dag_algo import dag_weighted_longest_path_length as dag_weighted_longest_path_length -from .dag_algo import is_directed_acyclic_graph as is_directed_acyclic_graph -from .dag_algo import topological_sort as topological_sort -from .dag_algo import lexicographical_topological_sort as lexicographical_topological_sort -from .dag_algo import transitive_reduction as transitive_reduction -from .dag_algo import layers as layers - -from .isomorphism import digraph_is_isomorphic as digraph_is_isomorphic -from .isomorphism import graph_is_isomorphic as graph_is_isomorphic -from .isomorphism import digraph_is_subgraph_isomorphic as digraph_is_subgraph_isomorphic -from .isomorphism import graph_is_subgraph_isomorphic as graph_is_subgraph_isomorphic -from .isomorphism import digraph_vf2_mapping as digraph_vf2_mapping -from .isomorphism import graph_vf2_mapping as graph_vf2_mapping - -from .layout import digraph_bipartite_layout as digraph_bipartite_layout -from .layout import graph_bipartite_layout as graph_bipartite_layout -from .layout import digraph_circular_layout as digraph_circular_layout -from .layout import graph_circular_layout as graph_circular_layout -from .layout import digraph_random_layout as digraph_random_layout -from .layout import graph_random_layout as graph_random_layout -from .layout import graph_shell_layout as graph_shell_layout -from .layout import digraph_spiral_layout as digraph_spiral_layout -from .layout import graph_spiral_layout as graph_spiral_layout -from .layout import digraph_spring_layout as digraph_spring_layout -from .layout import graph_spring_layout as graph_spring_layout - -from .line_graph import graph_line_graph as graph_line_graph - -from .link_analysis import hits as hits -from .link_analysis import pagerank as pagerank - -from .matching import max_weight_matching as max_weight_matching -from .matching import is_matching as is_matching -from .matching import is_maximal_matching as is_maximal_matching - -from .planar import is_planar as is_planar - -from .random_graph import directed_gnm_random_graph as directed_gnm_random_graph -from .random_graph import undirected_gnm_random_graph as undirected_gnm_random_graph -from .random_graph import directed_gnp_random_graph as directed_gnp_random_graph -from .random_graph import undirected_gnp_random_graph as undirected_gnp_random_graph -from .random_graph import random_geometric_graph as random_geometric_graph - -from .read_write import read_graphml as read_graphml -from .read_write import digraph_node_link_json as digraph_node_link_json -from .read_write import graph_node_link_json as graph_node_link_json - -from .shortest_path import ( - digraph_bellman_ford_shortest_paths as digraph_bellman_ford_shortest_paths, -) -from .shortest_path import graph_bellman_ford_shortest_paths as graph_bellman_ford_shortest_paths -from .shortest_path import ( - digraph_bellman_ford_shortest_path_lengths as digraph_bellman_ford_shortest_path_lengths, -) -from .shortest_path import ( - graph_bellman_ford_shortest_path_lengths as graph_bellman_ford_shortest_path_lengths, -) -from .shortest_path import digraph_dijkstra_shortest_paths as digraph_dijkstra_shortest_paths -from .shortest_path import graph_dijkstra_shortest_paths as graph_dijkstra_shortest_paths -from .shortest_path import ( - digraph_dijkstra_shortest_path_lengths as digraph_dijkstra_shortest_path_lengths, -) -from .shortest_path import ( - graph_dijkstra_shortest_path_lengths as graph_dijkstra_shortest_path_lengths, -) -from .shortest_path import ( - digraph_all_pairs_bellman_ford_path_lengths as digraph_all_pairs_bellman_ford_path_lengths, -) -from .shortest_path import ( - graph_all_pairs_bellman_ford_path_lengths as graph_all_pairs_bellman_ford_path_lengths, -) -from .shortest_path import ( - digraph_all_pairs_bellman_ford_shortest_paths as digraph_all_pairs_bellman_ford_shortest_paths, -) -from .shortest_path import ( - graph_all_pairs_bellman_ford_shortest_paths as graph_all_pairs_bellman_ford_shortest_paths, -) -from .shortest_path import ( - digraph_all_pairs_dijkstra_path_lengths as digraph_all_pairs_dijkstra_path_lengths, -) -from .shortest_path import ( - graph_all_pairs_dijkstra_path_lengths as graph_all_pairs_dijkstra_path_lengths, -) -from .shortest_path import ( - digraph_all_pairs_dijkstra_shortest_paths as digraph_all_pairs_dijkstra_shortest_paths, -) -from .shortest_path import ( - graph_all_pairs_dijkstra_shortest_paths as graph_all_pairs_dijkstra_shortest_paths, -) -from .shortest_path import digraph_astar_shortest_path as digraph_astar_shortest_path -from .shortest_path import graph_astar_shortest_path as graph_astar_shortest_path -from .shortest_path import digraph_k_shortest_path_lengths as digraph_k_shortest_path_lengths -from .shortest_path import graph_k_shortest_path_lengths as graph_k_shortest_path_lengths -from .shortest_path import digraph_has_path as digraph_has_path -from .shortest_path import graph_has_path as graph_has_path -from .shortest_path import ( - digraph_num_shortest_paths_unweighted as digraph_num_shortest_paths_unweighted, -) -from .shortest_path import ( - graph_num_shortest_paths_unweighted as graph_num_shortest_paths_unweighted, -) -from .shortest_path import ( - digraph_unweighted_average_shortest_path_length as digraph_unweighted_average_shortest_path_length, -) -from .shortest_path import digraph_distance_matrix as digraph_distance_matrix -from .shortest_path import graph_distance_matrix as graph_distance_matrix -from .shortest_path import digraph_floyd_warshall as digraph_floyd_warshall -from .shortest_path import graph_floyd_warshall as graph_floyd_warshall -from .shortest_path import digraph_floyd_warshall_numpy as digraph_floyd_warshall_numpy -from .shortest_path import graph_floyd_warshall_numpy as graph_floyd_warshall_numpy -from .shortest_path import ( - digraph_floyd_warshall_successor_and_distance as digraph_floyd_warshall_successor_and_distance, -) -from .shortest_path import ( - graph_floyd_warshall_successor_and_distance as graph_floyd_warshall_successor_and_distance, -) -from .shortest_path import find_negative_cycle as find_negative_cycle -from .shortest_path import negative_edge_cycle as negative_edge_cycle - -from .traversal import digraph_bfs_search as digraph_bfs_search -from .traversal import graph_bfs_search as graph_bfs_search -from .traversal import digraph_dfs_search as digraph_dfs_search -from .traversal import graph_dfs_search as graph_dfs_search -from .traversal import digraph_dijkstra_search as digraph_dijkstra_search -from .traversal import graph_dijkstra_search as graph_dijkstra_search -from .traversal import digraph_dfs_edges as digraph_dfs_edges -from .traversal import graph_dfs_edges as graph_dfs_edges -from .traversal import ancestors as ancestors -from .traversal import bfs_predecessors as bfs_predecessors -from .traversal import bfs_successors as bfs_successors -from .traversal import descendants as descendants - -from .transitivity import digraph_transitivity as digraph_transitivity -from .transitivity import graph_transitivity as graph_transitivity - -from .tree import minimum_spanning_edges as minimum_spanning_edges -from .tree import minimum_spanning_tree as minimum_spanning_tree -from .tree import steiner_tree as steiner_tree -from .tree import metric_closure as metric_closure - -from .tensor_product import digraph_tensor_product as digraph_tensor_product -from .tensor_product import graph_tensor_product as graph_tensor_product - -from .token_swapper import graph_token_swapper as graph_token_swapper - -from .union import digraph_union as digraph_union -from .union import graph_union as graph_union - _S = TypeVar("_S") _T = TypeVar("_T") _BFSVisitor = TypeVar("_BFSVisitor", bound=visit.BFSVisitor) diff --git a/rustworkx/cartesian_product.pyi b/rustworkx/cartesian_product.pyi deleted file mode 100644 index e453d3b435..0000000000 --- a/rustworkx/cartesian_product.pyi +++ /dev/null @@ -1,25 +0,0 @@ -# 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/cartesian_product.rs - -from .iterators import * -from .graph import PyGraph -from .digraph import PyDiGraph - -def digraph_cartesian_product( - first: PyDiGraph, - second: PyDiGraph, - /, -) -> tuple[PyDiGraph, ProductNodeMap]: ... -def graph_cartesian_product( - first: PyGraph, - second: PyGraph, - /, -) -> tuple[PyGraph, ProductNodeMap]: ... diff --git a/rustworkx/centrality.pyi b/rustworkx/centrality.pyi deleted file mode 100644 index 403ba29e5c..0000000000 --- a/rustworkx/centrality.pyi +++ /dev/null @@ -1,90 +0,0 @@ -# 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/centrality.rs - -from .iterators import * -from .graph import PyGraph -from .digraph import PyDiGraph - -from typing import TypeVar, Callable - -_S = TypeVar("_S") -_T = TypeVar("_T") - -def digraph_eigenvector_centrality( - graph: PyDiGraph[_S, _T], - /, - weight_fn: Callable[[_T], float] | None = ..., - default_weight: float = ..., - max_iter: int = ..., - tol: float = ..., -) -> CentralityMapping: ... -def graph_eigenvector_centrality( - graph: PyGraph[_S, _T], - /, - weight_fn: Callable[[_T], float] | None = ..., - default_weight: float = ..., - max_iter: int = ..., - tol: float = ..., -) -> CentralityMapping: ... -def digraph_betweenness_centrality( - graph: PyDiGraph[_S, _T], - /, - normalized: bool = ..., - endpoints: bool = ..., - parallel_threshold: int = ..., -) -> CentralityMapping: ... -def graph_betweenness_centrality( - graph: PyGraph[_S, _T], - /, - normalized: bool = ..., - endpoints: bool = ..., - parallel_threshold: int = ..., -) -> CentralityMapping: ... -def digraph_edge_betweenness_centrality( - graph: PyDiGraph[_S, _T], - /, - normalized: bool = ..., - parallel_threshold: int = ..., -) -> EdgeCentralityMapping: ... -def graph_edge_betweenness_centrality( - graph: PyGraph[_S, _T], - /, - normalized: bool = ..., - parallel_threshold: int = ..., -) -> EdgeCentralityMapping: ... -def digraph_closeness_centrality( - graph: PyDiGraph[_S, _T], - wf_improved: bool = ..., -) -> CentralityMapping: ... -def graph_closeness_centrality( - graph: PyGraph[_S, _T], - wf_improved: bool = ..., -) -> CentralityMapping: ... -def digraph_katz_centrality( - graph: PyDiGraph[_S, _T], - /, - alpha: float | None = ..., - beta: float | None = ..., - weight_fn: Callable[[_T], float] | None = ..., - default_weight: float | None = ..., - max_iter: int | None = ..., - tol: float | None = ..., -) -> CentralityMapping: ... -def graph_katz_centrality( - graph: PyGraph[_S, _T], - /, - alpha: float | None = ..., - beta: float | None = ..., - weight_fn: Callable[[_T], float] | None = ..., - default_weight: float | None = ..., - max_iter: int | None = ..., - tol: float | None = ..., -) -> CentralityMapping: ... diff --git a/rustworkx/coloring.pyi b/rustworkx/coloring.pyi deleted file mode 100644 index 7517544fc0..0000000000 --- a/rustworkx/coloring.pyi +++ /dev/null @@ -1,21 +0,0 @@ -# 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/coloring.rs - -from .graph import PyGraph -from .digraph import PyDiGraph - -def graph_greedy_color(graph: PyGraph, /) -> dict[int, int]: ... -def graph_greedy_edge_color(graph: PyGraph, /) -> dict[int, int]: ... -def graph_is_bipartite(graph: PyGraph) -> bool: ... -def digraph_is_bipartite(graph: PyDiGraph) -> bool: ... -def graph_two_color(graph: PyGraph) -> dict[int, int]: ... -def digraph_two_color(graph: PyDiGraph) -> dict[int, int]: ... -def graph_misra_gries_edge_color(graph: PyGraph, /) -> dict[int, int]: ... diff --git a/rustworkx/connectivity.pyi b/rustworkx/connectivity.pyi deleted file mode 100644 index a49b075fb1..0000000000 --- a/rustworkx/connectivity.pyi +++ /dev/null @@ -1,106 +0,0 @@ -# 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/connectivity/mod.rs - -import numpy as np - -from .iterators import * -from .graph import PyGraph -from .digraph import PyDiGraph - -from typing import TypeVar, Callable, Iterator - -_S = TypeVar("_S") -_T = TypeVar("_T") - -def connected_components(graph: PyGraph, /) -> list[set[int]]: ... -def is_connected(graph: PyGraph, /) -> bool: ... -def is_weakly_connected(graph: PyDiGraph, /) -> bool: ... -def number_connected_components(graph: PyGraph, /) -> int: ... -def number_weakly_connected_components(graph: PyDiGraph, /) -> bool: ... -def node_connected_component(graph: PyGraph, node: int, /) -> set[int]: ... -def strongly_connected_components(graph: PyDiGraph, /) -> list[list[int]]: ... -def weakly_connected_components(graph: PyDiGraph, /) -> list[set[int]]: ... -def digraph_adjacency_matrix( - graph: PyDiGraph[_S, _T], - /, - weight_fn: Callable[[_T], float] | None = ..., - default_weight: float = ..., - null_value: float = ..., - parallel_edge: str = ..., -) -> np.ndarray: ... -def graph_adjacency_matrix( - graph: PyGraph[_S, _T], - /, - weight_fn: Callable[[_T], float] | None = ..., - default_weight: float = ..., - null_value: float = ..., - parallel_edge: str = ..., -) -> np.ndarray: ... -def cycle_basis(graph: PyGraph, /, root: int | None = ...) -> list[list[int]]: ... -def articulation_points(graph: PyGraph, /) -> set[int]: ... -def biconnected_components(graph: PyGraph, /) -> BiconnectedComponents: ... -def chain_decomposition(graph: PyGraph, /, source: int | None = ...) -> Chains: ... -def digraph_find_cycle( - graph: PyDiGraph[_S, _T], - /, - source: int | None = ..., -) -> EdgeList: ... -def digraph_complement(graph: PyDiGraph[_S, _T], /) -> PyDiGraph[_S, _T | None]: ... -def graph_complement( - graph: PyGraph[_S, _T], - /, -) -> PyGraph[_S, _T | None]: ... -def digraph_all_simple_paths( - graph: PyDiGraph, - origin: int, - to: int, - /, - min_depth: int | None = ..., - cutoff: int | None = ..., -) -> list[list[int]]: ... -def graph_all_simple_paths( - graph: PyGraph, - origin: int, - to: int, - /, - min_depth: int | None = ..., - cutoff: int | None = ..., -) -> list[list[int]]: ... -def digraph_all_pairs_all_simple_paths( - graph: PyDiGraph, - /, - min_depth: int | None = ..., - cutoff: int | None = ..., -) -> AllPairsMultiplePathMapping: ... -def graph_all_pairs_all_simple_paths( - graph: PyGraph, - /, - min_depth: int | None = ..., - cutoff: int | None = ..., -) -> AllPairsMultiplePathMapping: ... -def digraph_longest_simple_path(graph: PyDiGraph, /) -> NodeIndices | None: ... -def graph_longest_simple_path(graph: PyGraph, /) -> NodeIndices | None: ... -def digraph_core_number( - graph: PyDiGraph, - /, -) -> int: ... -def graph_core_number( - graph: PyGraph, - /, -) -> int: ... -def stoer_wagner_min_cut( - graph: PyGraph[_S, _T], - /, - weight_fn: Callable[[_T], float] | None = ..., -) -> tuple[float, NodeIndices] | None: ... -def simple_cycles(graph: PyDiGraph, /) -> Iterator[NodeIndices]: ... -def graph_isolates(graph: PyGraph) -> NodeIndices: ... -def digraph_isolates(graph: PyDiGraph) -> NodeIndices: ... diff --git a/rustworkx/dag_algo.pyi b/rustworkx/dag_algo.pyi deleted file mode 100644 index 7923939d8f..0000000000 --- a/rustworkx/dag_algo.pyi +++ /dev/null @@ -1,65 +0,0 @@ -# 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/dag_algo/mod.rs - -from .iterators import * -from .digraph import PyDiGraph - -from typing import TypeVar, Callable, final, Sequence - -_S = TypeVar("_S") -_T = TypeVar("_T") - -def collect_runs( - graph: PyDiGraph[_S, _T], - filter_fn: Callable[[_S], bool], -) -> list[list[_S]]: ... -def collect_bicolor_runs( - graph: PyDiGraph[_S, _T], - filter_fn: Callable[[_S], bool], - color_fn: Callable[[_T], int], -) -> list[list[_S]]: ... -def dag_longest_path( - graph: PyDiGraph[_S, _T], /, weight_fn: Callable[[int, int, _T], int] | None = ... -) -> NodeIndices: ... -def dag_longest_path_length( - graph: PyDiGraph[_S, _T], /, weight_fn: Callable[[int, int, _T], int] | None = ... -) -> int: ... -def dag_weighted_longest_path( - graph: PyDiGraph[_S, _T], - weight_fn: Callable[[int, int, _T], float], - /, -) -> NodeIndices: ... -def dag_weighted_longest_path_length( - graph: PyDiGraph[_S, _T], - weight_fn: Callable[[int, int, _T], float], - /, -) -> float: ... -def is_directed_acyclic_graph(graph: PyDiGraph, /) -> bool: ... -def topological_sort(graph: PyDiGraph, /) -> NodeIndices: ... -def topological_generations(dag: PyDiGraph, /) -> list[NodeIndices]: ... -def lexicographical_topological_sort( - dag: PyDiGraph[_S, _T], - key: Callable[[_S], str], - /, -) -> list[_S]: ... -def transitive_reduction(graph: PyDiGraph, /) -> tuple[PyDiGraph, dict[int, int]]: ... -def layers( - dag: PyDiGraph[_S, _T], - first_layer: list[int], - /, - 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/digraph.pyi b/rustworkx/digraph.pyi deleted file mode 100644 index a012b9b847..0000000000 --- a/rustworkx/digraph.pyi +++ /dev/null @@ -1,199 +0,0 @@ -# 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/digraph.rs - -import numpy as np -from .iterators import * - -from typing import Any, Callable, Generic, TypeVar, Sequence, TYPE_CHECKING - -if TYPE_CHECKING: - from .graph import PyGraph - -__all__ = ["PyDiGraph"] - -S = TypeVar("S") -T = TypeVar("T") - -class PyDiGraph(Generic[S, T]): - attrs: Any - check_cycle: bool = ... - multigraph: bool = ... - def __init__( - self, - /, - check_cycle: bool = ..., - multigraph: bool = ..., - ) -> None: ... - def add_child(self, parent: int, obj: S, edge: T, /) -> int: ... - def add_edge(self, parent: int, child: int, edge: T, /) -> int: ... - def add_edges_from( - self, - obj_list: Sequence[tuple[int, int, T]], - /, - ) -> list[int]: ... - def add_edges_from_no_data( - self: PyDiGraph[S, T | None], obj_list: Sequence[tuple[int, int]], / - ) -> list[int]: ... - def add_node(self, obj: S, /) -> int: ... - def add_nodes_from(self, obj_list: Sequence[S], /) -> NodeIndices: ... - def add_parent(self, child: int, obj: S, edge: T, /) -> int: ... - def adj(self, node: int, /) -> dict[int, T]: ... - def adj_direction(self, node: int, direction: bool, /) -> dict[int, T]: ... - def clear(self) -> None: ... - def clear_edges(self) -> None: ... - def compose( - self, - other: PyDiGraph[S, T], - node_map: dict[int, tuple[int, T]], - /, - node_map_func: Callable[[S], int] | None = ..., - edge_map_func: Callable[[T], int] | None = ..., - ) -> dict[int, int]: ... - def contract_nodes( - self, - nodes: Sequence[int], - obj: S, - /, - check_cycle: bool | None = ..., - weight_combo_fn: Callable[[T, T], T] | None = ..., - ) -> int: ... - def copy(self) -> PyDiGraph[S, T]: ... - def edge_index_map(self) -> EdgeIndexMap[T]: ... - def edge_indices(self) -> EdgeIndices: ... - def edge_list(self) -> EdgeList: ... - def edges(self) -> list[T]: ... - def edge_subgraph(self, edge_list: Sequence[tuple[int, int]], /) -> PyDiGraph[S, T]: ... - def extend_from_edge_list( - self: PyDiGraph[S | None, T | None], edge_list: Sequence[tuple[int, int]], / - ) -> None: ... - def extend_from_weighted_edge_list( - self: PyDiGraph[S | None, T], - edge_list: Sequence[tuple[int, int, T]], - /, - ) -> None: ... - def filter_edges(self, filter_function: Callable[[T], bool]) -> EdgeIndices: ... - def filter_nodes(self, filter_function: Callable[[S], bool]) -> NodeIndices: ... - def find_adjacent_node_by_edge(self, node: int, predicate: Callable[[T], bool], /) -> S: ... - def find_node_by_weight( - self, - obj: Callable[[S], bool], - /, - ) -> int | None: ... - def find_predecessors_by_edge( - self, node: int, filter_fn: Callable[[T], bool], / - ) -> list[S]: ... - def find_predecessor_node_by_edge(self, node: int, predicate: Callable[[T], bool], /) -> S: ... - def find_successors_by_edge(self, node: int, filter_fn: Callable[[T], bool], /) -> list[S]: ... - @staticmethod - def from_adjacency_matrix( - matrix: np.ndarray, /, null_value: float = ... - ) -> PyDiGraph[int, float]: ... - @staticmethod - def from_complex_adjacency_matrix( - matrix: np.ndarray, /, null_value: complex = ... - ) -> PyDiGraph[int, complex]: ... - def get_all_edge_data(self, node_a: int, node_b: int, /) -> list[T]: ... - def get_edge_data(self, node_a: int, node_b: int, /) -> T: ... - def get_node_data(self, node: int, /) -> S: ... - def get_edge_data_by_index(self, edge_index: int, /) -> T: ... - def get_edge_endpoints_by_index(self, edge_index: int, /) -> tuple[int, int]: ... - def has_edge(self, node_a: int, node_b: int, /) -> bool: ... - def has_parallel_edges(self) -> bool: ... - def in_degree(self, node: int, /) -> int: ... - def in_edges(self, node: int, /) -> WeightedEdgeList[T]: ... - def incident_edge_index_map(self, node: int, /, all_edges: bool = ...) -> EdgeIndexMap: ... - def incident_edges(self, node: int, /, all_edges: bool = ...) -> EdgeIndices: ... - def insert_node_on_in_edges(self, node: int, ref_node: int, /) -> None: ... - def insert_node_on_in_edges_multiple(self, node: int, ref_nodes: Sequence[int], /) -> None: ... - def insert_node_on_out_edges(self, node: int, ref_node: int, /) -> None: ... - def insert_node_on_out_edges_multiple(self, node: int, ref_nodes: Sequence[int], /) -> None: ... - def is_symmetric(self) -> bool: ... - def make_symmetric(self, edge_payload_fn: Callable[[T], T] | None = ...) -> None: ... - def merge_nodes(self, u: int, v: int, /) -> None: ... - def neighbors(self, node: int, /) -> NodeIndices: ... - def node_indexes(self) -> NodeIndices: ... - def node_indices(self) -> NodeIndices: ... - def nodes(self) -> list[S]: ... - def num_edges(self) -> int: ... - def num_nodes(self) -> int: ... - def out_degree(self, node: int, /) -> int: ... - def out_edges(self, node: int, /) -> WeightedEdgeList[T]: ... - def predecessor_indices(self, node: int, /) -> NodeIndices: ... - def predecessors(self, node: int, /) -> list[S]: ... - @staticmethod - def read_edge_list( - path: str, - /, - comment: str | None = ..., - deliminator: str | None = ..., - labels: bool = ..., - ) -> PyDiGraph: ... - def remove_edge(self, parent: int, child: int, /) -> None: ... - def remove_edge_from_index(self, edge: int, /) -> None: ... - def remove_edges_from(self, index_list: Sequence[tuple[int, int]], /) -> None: ... - def remove_node(self, node: int, /) -> None: ... - def remove_node_retain_edges( - self, - node: int, - /, - use_outgoing: bool | None = ..., - condition: Callable[[S, S], bool] | None = ..., - ) -> None: ... - def remove_nodes_from(self, index_list: Sequence[int], /) -> None: ... - def subgraph(self, nodes: Sequence[int], /, preserve_attrs: bool = ...) -> PyDiGraph[S, T]: ... - def substitute_node_with_subgraph( - self, - node: int, - other: PyDiGraph[S, T], - edge_map_fn: Callable[[int, int, T], int | None], - /, - node_filter: Callable[[S], bool] | None = ..., - edge_weight_map: Callable[[T], T] | None = ..., - ) -> NodeMap: ... - def successor_indices(self, node: int, /) -> NodeIndices: ... - def successors(self, node: int, /) -> list[S]: ... - def to_dot( - self, - /, - node_attr: Callable[[S], dict[str, str]] | None = ..., - edge_attr: Callable[[T], dict[str, str]] | None = ..., - graph_attr: dict[str, str] | None = ..., - filename: str | None = None, - ) -> str | None: ... - def to_undirected( - self, - /, - multigraph: bool = ..., - weight_combo_fn: Callable[[T, T], T] | None = ..., - ) -> PyGraph[S, T]: ... - def update_edge( - self, - source: int, - target: int, - edge: T, - /, - ) -> None: ... - def update_edge_by_index(self, edge_index: int, edge: T, /) -> None: ... - def weighted_edge_list(self) -> WeightedEdgeList[T]: ... - def write_edge_list( - self, - path: str, - /, - deliminator: str | None = ..., - weight_fn: Callable[[T], str] | None = ..., - ) -> None: ... - def reverse(self) -> None: ... - def __delitem__(self, idx: int, /) -> None: ... - def __getitem__(self, idx: int, /) -> S: ... - def __getstate__(self) -> Any: ... - def __len__(self) -> int: ... - def __setitem__(self, idx: int, value: S, /) -> None: ... - def __setstate__(self, state, /) -> None: ... diff --git a/rustworkx/graph.pyi b/rustworkx/graph.pyi deleted file mode 100644 index c4636e79f2..0000000000 --- a/rustworkx/graph.pyi +++ /dev/null @@ -1,165 +0,0 @@ -# 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/graph.rs - -import numpy as np -from .iterators import * - -from typing import ( - Any, - Callable, - Generic, - TypeVar, - Sequence, - TYPE_CHECKING, -) - -if TYPE_CHECKING: - from .digraph import PyDiGraph - -__all__ = ["PyGraph"] - -S = TypeVar("S") -T = TypeVar("T") - -class PyGraph(Generic[S, T]): - attrs: Any - multigraph: bool = ... - def __init__(self, /, multigraph: bool = ...) -> None: ... - def add_edge(self, node_a: int, node_b: int, edge: T, /) -> int: ... - def add_edges_from( - self, - obj_list: Sequence[tuple[int, int, T]], - /, - ) -> list[int]: ... - def add_edges_from_no_data( - self: PyGraph[S, T | None], obj_list: Sequence[tuple[int, int]], / - ) -> list[int]: ... - def add_node(self, obj: S, /) -> int: ... - def add_nodes_from(self, obj_list: Sequence[S], /) -> NodeIndices: ... - def adj(self, node: int, /) -> dict[int, T]: ... - def clear(self) -> None: ... - def clear_edges(self) -> None: ... - def compose( - self, - other: PyGraph[S, T], - node_map: dict[int, tuple[int, T]], - /, - node_map_func: Callable[[S], int] | None = ..., - edge_map_func: Callable[[T], int] | None = ..., - ) -> dict[int, int]: ... - def contract_nodes( - self, - nodes: Sequence[int], - obj: S, - /, - weight_combo_fn: Callable[[T, T], T] | None = ..., - ) -> int: ... - def copy(self) -> PyGraph[S, T]: ... - def degree(self, node: int, /) -> int: ... - def edge_index_map(self) -> EdgeIndexMap[T]: ... - def edge_indices(self) -> EdgeIndices: ... - def edge_list(self) -> EdgeList: ... - def edges(self) -> list[T]: ... - def edge_subgraph(self, edge_list: Sequence[tuple[int, int]], /) -> PyGraph[S, T]: ... - def extend_from_edge_list( - self: PyGraph[S | None, T | None], edge_list: Sequence[tuple[int, int]], / - ) -> None: ... - def extend_from_weighted_edge_list( - self: PyGraph[S | None, T], - edge_list: Sequence[tuple[int, int, T]], - /, - ) -> None: ... - def filter_edges(self, filter_function: Callable[[T], bool]) -> EdgeIndices: ... - def filter_nodes(self, filter_function: Callable[[S], bool]) -> NodeIndices: ... - def find_node_by_weight( - self, - obj: Callable[[S], bool], - /, - ) -> int | None: ... - @staticmethod - def from_adjacency_matrix( - matrix: np.ndarray, /, null_value: float = ... - ) -> PyGraph[int, float]: ... - @staticmethod - def from_complex_adjacency_matrix( - matrix: np.ndarray, /, null_value: complex = ... - ) -> PyGraph[int, complex]: ... - def get_all_edge_data(self, node_a: int, node_b: int, /) -> list[T]: ... - def get_edge_data(self, node_a: int, node_b: int, /) -> T: ... - def get_edge_data_by_index(self, edge_index: int, /) -> T: ... - def get_edge_endpoints_by_index(self, edge_index: int, /) -> tuple[int, int]: ... - def get_node_data(self, node: int, /) -> S: ... - def has_edge(self, node_a: int, node_b: int, /) -> bool: ... - def has_parallel_edges(self) -> bool: ... - def in_edges(self, node: int, /) -> WeightedEdgeList[T]: ... - def incident_edge_index_map(self, node: int, /) -> EdgeIndexMap: ... - def incident_edges(self, node: int, /) -> EdgeIndices: ... - def neighbors(self, node: int, /) -> NodeIndices: ... - def node_indexes(self) -> NodeIndices: ... - def node_indices(self) -> NodeIndices: ... - def nodes(self) -> list[S]: ... - def num_edges(self) -> int: ... - def num_nodes(self) -> int: ... - def out_edges(self, node: int, /) -> WeightedEdgeList[T]: ... - @staticmethod - def read_edge_list( - path: str, - /, - comment: str | None = ..., - deliminator: str | None = ..., - labels: bool = ..., - ) -> PyGraph: ... - def remove_edge(self, node_a: int, node_b: int, /) -> None: ... - def remove_edge_from_index(self, edge: int, /) -> None: ... - def remove_edges_from(self, index_list: Sequence[tuple[int, int]], /) -> None: ... - def remove_node(self, node: int, /) -> None: ... - def remove_nodes_from(self, index_list: Sequence[int], /) -> None: ... - def subgraph(self, nodes: Sequence[int], /, preserve_attrs: bool = ...) -> PyGraph[S, T]: ... - def substitute_node_with_subgraph( - self, - node: int, - other: PyGraph[S, T], - edge_map_fn: Callable[[int, int, T], int | None], - /, - node_filter: Callable[[S], bool] | None = ..., - edge_weight_map: Callable[[T], T] | None = ..., - ) -> NodeMap: ... - def to_dot( - self, - /, - node_attr: Callable[[S], dict[str, str]] | None = ..., - edge_attr: Callable[[T], dict[str, str]] | None = ..., - graph_attr: dict[str, str] | None = ..., - filename: str | None = None, - ) -> str | None: ... - def to_directed(self) -> PyDiGraph[S, T]: ... - def update_edge( - self, - source: int, - target: int, - edge: T, - /, - ) -> None: ... - def update_edge_by_index(self, edge_index: int, edge: T, /) -> None: ... - def weighted_edge_list(self) -> WeightedEdgeList[T]: ... - def write_edge_list( - self, - path: str, - /, - deliminator: str | None = ..., - weight_fn: Callable[[T], str] | None = ..., - ) -> None: ... - def __delitem__(self, idx: int, /) -> None: ... - def __getitem__(self, idx: int, /) -> S: ... - def __getstate__(self) -> Any: ... - def __len__(self) -> int: ... - def __setitem__(self, idx: int, value: S, /) -> None: ... - def __setstate__(self, state, /) -> None: ... diff --git a/rustworkx/isomorphism.pyi b/rustworkx/isomorphism.pyi deleted file mode 100644 index 00b19c7e4d..0000000000 --- a/rustworkx/isomorphism.pyi +++ /dev/null @@ -1,80 +0,0 @@ -# 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/lib.rs - -from .iterators import * -from .graph import PyGraph -from .digraph import PyDiGraph - -from typing import TypeVar, Callable, Iterator - -_S = TypeVar("_S") -_T = TypeVar("_T") - -def digraph_is_isomorphic( - first: PyDiGraph[_S, _T], - second: PyDiGraph[_S, _T], - /, - node_matcher: Callable[[_S, _S], bool] | None = ..., - edge_matcher: Callable[[_T, _T], bool] | None = ..., - id_order: bool = ..., - call_limit: int | None = ..., -) -> bool: ... -def graph_is_isomorphic( - first: PyGraph[_S, _T], - second: PyGraph[_S, _T], - /, - node_matcher: Callable[[_S, _S], bool] | None = ..., - edge_matcher: Callable[[_T, _T], bool] | None = ..., - id_order: bool = ..., - call_limit: int | None = ..., -) -> bool: ... -def digraph_is_subgraph_isomorphic( - first: PyDiGraph[_S, _T], - second: PyDiGraph[_S, _T], - /, - node_matcher: Callable[[_S, _S], bool] | None = ..., - edge_matcher: Callable[[_T, _T], bool] | None = ..., - id_order: bool = ..., - induced: bool = ..., - call_limit: int | None = ..., -) -> bool: ... -def graph_is_subgraph_isomorphic( - first: PyGraph[_S, _T], - second: PyGraph[_S, _T], - /, - node_matcher: Callable[[_S, _S], bool] | None = ..., - edge_matcher: Callable[[_T, _T], bool] | None = ..., - id_order: bool = ..., - induced: bool = ..., - call_limit: int | None = ..., -) -> bool: ... -def digraph_vf2_mapping( - first: PyDiGraph[_S, _T], - second: PyDiGraph[_S, _T], - /, - node_matcher: Callable[[_S, _S], bool] | None = ..., - edge_matcher: Callable[[_T, _T], bool] | None = ..., - id_order: bool = ..., - subgraph: bool = ..., - induced: bool = ..., - call_limit: int | None = ..., -) -> Iterator[NodeMap]: ... -def graph_vf2_mapping( - first: PyGraph[_S, _T], - second: PyGraph[_S, _T], - /, - node_matcher: Callable[[_S, _S], bool] | None = ..., - edge_matcher: Callable[[_T, _T], bool] | None = ..., - id_order: bool = ..., - subgraph: bool = ..., - induced: bool = ..., - call_limit: int | None = ..., -) -> Iterator[NodeMap]: ... diff --git a/rustworkx/iterators.pyi b/rustworkx/iterators.pyi deleted file mode 100644 index ca547a4ece..0000000000 --- a/rustworkx/iterators.pyi +++ /dev/null @@ -1,147 +0,0 @@ -# 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/iterators.rs - -from typing import ( - Any, - Generic, - ItemsView, - KeysView, - ValuesView, - Iterator, - Mapping, - TypeVar, - overload, - final, -) -from abc import ABC -from collections.abc import Sequence -from typing_extensions import Self - -import numpy as np - -S = TypeVar("S") -T_co = TypeVar("T_co", covariant=True) - -__all__ = [ - "NodeIndices", - "PathLengthMapping", - "PathMapping", - "AllPairsPathLengthMapping", - "AllPairsPathMapping", - "BFSPredecessors", - "BFSSuccessors", - "EdgeIndexMap", - "EdgeIndices", - "Chains", - "EdgeList", - "NodeMap", - "NodesCountMapping", - "Pos2DMapping", - "WeightedEdgeList", - "CentralityMapping", - "EdgeCentralityMapping", - "BiconnectedComponents", - "ProductNodeMap", - "MultiplePathMapping", - "AllPairsMultiplePathMapping", -] - -class RustworkxCustomVecIter(Generic[T_co], Sequence[T_co], ABC): - def __init__(self) -> None: ... - def __eq__(self, other: object) -> bool: ... - @overload - def __getitem__(self, index: int) -> T_co: ... - @overload - def __getitem__(self: Self, index: slice) -> Self: ... - def __getstate__(self) -> Any: ... - def __hash__(self) -> int: ... - def __len__(self) -> int: ... - def __ne__(self, other: object) -> bool: ... - def __setstate__(self, state: Sequence[T_co]) -> None: ... - def __array__(self, _dt: np.dtype | None = ...) -> np.ndarray: ... - -class RustworkxCustomHashMapIter(Generic[S, T_co], Mapping[S, T_co], ABC): - def __init__(self) -> None: ... - def items(self) -> ItemsView[S, T_co]: ... - def keys(self) -> KeysView[S]: ... - def values(self) -> ValuesView[T_co]: ... - def __contains__(self, other: object) -> bool: ... - def __eq__(self, other: object) -> bool: ... - def __getitem__(self, index: S) -> T_co: ... - def __getstate__(self) -> Any: ... - def __hash__(self) -> int: ... - def __iter__(self) -> Iterator[S]: ... - def __len__(self) -> int: ... - def __ne__(self, other: object) -> bool: ... - def __setstate__(self, state: Mapping[S, T_co]) -> None: ... - -@final -class NodeIndices(RustworkxCustomVecIter[int]): ... - -@final -class PathLengthMapping(RustworkxCustomHashMapIter[int, float]): ... - -@final -class PathMapping(RustworkxCustomHashMapIter[int, NodeIndices]): ... - -@final -class AllPairsPathLengthMapping(RustworkxCustomHashMapIter[int, PathLengthMapping]): ... - -@final -class AllPairsPathMapping(RustworkxCustomHashMapIter[int, PathMapping]): ... - -@final -class BFSSuccessors(Generic[T_co], RustworkxCustomVecIter[tuple[T_co, list[T_co]]]): ... - -@final -class BFSPredecessors(Generic[T_co], RustworkxCustomVecIter[tuple[T_co, list[T_co]]]): ... - -@final -class EdgeIndexMap(Generic[T_co], RustworkxCustomHashMapIter[int, tuple[int, int, T_co]]): ... - -@final -class EdgeIndices(RustworkxCustomVecIter[int]): ... - -@final -class Chains(RustworkxCustomVecIter[EdgeIndices]): ... - -@final -class EdgeList(RustworkxCustomVecIter[tuple[int, int]]): ... - -@final -class NodeMap(RustworkxCustomHashMapIter[int, int]): ... - -@final -class NodesCountMapping(RustworkxCustomHashMapIter[int, int]): ... - -@final -class Pos2DMapping(RustworkxCustomHashMapIter[int, tuple[float, float]]): ... - -@final -class WeightedEdgeList(Generic[T_co], RustworkxCustomVecIter[tuple[int, int, T_co]]): ... - -@final -class CentralityMapping(RustworkxCustomHashMapIter[int, float]): ... - -@final -class EdgeCentralityMapping(RustworkxCustomHashMapIter[int, float]): ... - -@final -class BiconnectedComponents(RustworkxCustomHashMapIter[tuple[int, int], int]): ... - -@final -class ProductNodeMap(RustworkxCustomHashMapIter[tuple[int, int], int]): ... - -@final -class MultiplePathMapping(RustworkxCustomHashMapIter[int, list[list[int]]]): ... - -@final -class AllPairsMultiplePathMapping(RustworkxCustomHashMapIter[int, MultiplePathMapping]): ... diff --git a/rustworkx/layout.pyi b/rustworkx/layout.pyi deleted file mode 100644 index d329800dff..0000000000 --- a/rustworkx/layout.pyi +++ /dev/null @@ -1,126 +0,0 @@ -# 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/layout/mod.rs - -from .iterators import * -from .graph import PyGraph -from .digraph import PyDiGraph - -from typing import TypeVar, Callable - -_S = TypeVar("_S") -_T = TypeVar("_T") - -def digraph_bipartite_layout( - graph: PyDiGraph, - first_nodes: set[int], - /, - horizontal: bool | None = ..., - scale: float | None = ..., - center: tuple[float, float] | None = ..., - aspect_ratio: float | None = ..., -) -> Pos2DMapping: ... -def graph_bipartite_layout( - graph: PyGraph, - first_nodes: set[int], - /, - horizontal: bool | None = ..., - scale: float | None = ..., - center: tuple[float, float] | None = ..., - aspect_ratio: float | None = ..., -) -> Pos2DMapping: ... -def digraph_circular_layout( - graph: PyDiGraph, - /, - scale: float | None = ..., - center: tuple[float, float] | None = ..., -) -> Pos2DMapping: ... -def graph_circular_layout( - graph: PyGraph, - /, - scale: float | None = ..., - center: tuple[float, float] | None = ..., -) -> Pos2DMapping: ... -def digraph_random_layout( - graph: PyDiGraph, - /, - center: tuple[float, float] | None = ..., - seed: int | None = ..., -) -> Pos2DMapping: ... -def graph_random_layout( - graph: PyGraph, - /, - center: tuple[float, float] | None = ..., - seed: int | None = ..., -) -> Pos2DMapping: ... -def digraph_shell_layout( - graph: PyDiGraph, - /, - nlist: list[list[int]] | None = ..., - rotate: float | None = ..., - scale: float | None = ..., - center: tuple[float, float] | None = ..., -) -> Pos2DMapping: ... -def graph_shell_layout( - graph: PyGraph, - /, - nlist: list[list[int]] | None = ..., - rotate: float | None = ..., - scale: float | None = ..., - center: tuple[float, float] | None = ..., -) -> Pos2DMapping: ... -def digraph_spiral_layout( - graph: PyDiGraph, - /, - scale: float | None = ..., - center: tuple[float, float] | None = ..., - resolution: float | None = ..., - equidistant: bool | None = ..., -) -> Pos2DMapping: ... -def graph_spiral_layout( - graph: PyGraph, - /, - scale: float | None = ..., - center: tuple[float, float] | None = ..., - resolution: float | None = ..., - equidistant: bool | None = ..., -) -> Pos2DMapping: ... -def digraph_spring_layout( - graph: PyDiGraph[_S, _T], - pos: dict[int, tuple[float, float]] | None = ..., - fixed: set[int] | None = ..., - k: float | None = ..., - repulsive_exponent: int = ..., - adaptive_cooling: bool = ..., - num_iter: int = ..., - tol: float | None = ..., - weight_fn: Callable[[_T], float] | None = ..., - default_weight: float = ..., - scale: float = ..., - center: tuple[float, float] | None = ..., - seed: int | None = ..., - /, -) -> Pos2DMapping: ... -def graph_spring_layout( - graph: PyGraph[_S, _T], - pos: dict[int, tuple[float, float]] | None = ..., - fixed: set[int] | None = ..., - k: float | None = ..., - repulsive_exponent: int = ..., - adaptive_cooling: bool = ..., - num_iter: int = ..., - tol: float | None = ..., - weight_fn: Callable[[_T], float] | None = ..., - default_weight: float = ..., - scale: float = ..., - center: tuple[float, float] | None = ..., - seed: int | None = ..., - /, -) -> Pos2DMapping: ... diff --git a/rustworkx/line_graph.pyi b/rustworkx/line_graph.pyi deleted file mode 100644 index a7851d4f07..0000000000 --- a/rustworkx/line_graph.pyi +++ /dev/null @@ -1,14 +0,0 @@ -# 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/line_graph.rs - -from .graph import PyGraph - -def graph_line_graph(graph: PyGraph, /) -> tuple[PyGraph, dict[int, int]]: ... diff --git a/rustworkx/link_analysis.pyi b/rustworkx/link_analysis.pyi deleted file mode 100644 index 65f69f39f0..0000000000 --- a/rustworkx/link_analysis.pyi +++ /dev/null @@ -1,39 +0,0 @@ -# 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/link_analysis.rs - -from .iterators import * -from .digraph import PyDiGraph - -from typing import TypeVar, Callable - -_S = TypeVar("_S") -_T = TypeVar("_T") - -def hits( - graph: PyDiGraph[_S, _T], - /, - weight_fn: Callable[[_T], float] | None = ..., - nstart: dict[int, float] | None = ..., - tol: float | None = ..., - max_iter: int | None = ..., - normalized: bool | None = ..., -) -> tuple[CentralityMapping, CentralityMapping]: ... -def pagerank( - graph: PyDiGraph[_S, _T], - /, - alpha: float | None = ..., - weight_fn: Callable[[_T], float] | None = ..., - nstart: dict[int, float] | None = ..., - personalization: dict[int, float] | None = ..., - tol: float | None = ..., - max_iter: int | None = ..., - dangling: dict[int, float] | None = ..., -) -> CentralityMapping: ... diff --git a/rustworkx/matching.pyi b/rustworkx/matching.pyi deleted file mode 100644 index fa02a47f3f..0000000000 --- a/rustworkx/matching.pyi +++ /dev/null @@ -1,36 +0,0 @@ -# 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/matcing/mod.rs - -from .graph import PyGraph - -from typing import TypeVar, Callable - -_S = TypeVar("_S") -_T = TypeVar("_T") - -def max_weight_matching( - graph: PyGraph[_S, _T], - /, - max_cardinality: bool = ..., - weight_fn: Callable[[_T], float] | None = ..., - default_weight: int = ..., - verify_optimum: bool = ..., -) -> set[tuple[int, int]]: ... -def is_matching( - graph: PyGraph, - matching: set[tuple[int, int]], - /, -) -> bool: ... -def is_maximal_matching( - graph: PyGraph, - matching: set[tuple[int, int]], - /, -) -> bool: ... diff --git a/rustworkx/planar.pyi b/rustworkx/planar.pyi deleted file mode 100644 index 6015ed5a28..0000000000 --- a/rustworkx/planar.pyi +++ /dev/null @@ -1,14 +0,0 @@ -# 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/planar.rs - -from .graph import PyGraph - -def is_planar(graph: PyGraph, /) -> bool: ... diff --git a/rustworkx/random_graph.pyi b/rustworkx/random_graph.pyi deleted file mode 100644 index 35c4d2eadd..0000000000 --- a/rustworkx/random_graph.pyi +++ /dev/null @@ -1,59 +0,0 @@ -# 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/lib.rs - -from .graph import PyGraph -from .digraph import PyDiGraph - -def directed_gnm_random_graph( - num_nodes: int, - num_edges: int, - /, - seed: int | None = ..., -) -> PyDiGraph: ... -def undirected_gnm_random_graph( - num_nodes: int, - num_edges: int, - /, - seed: int | None = ..., -) -> PyGraph: ... -def directed_gnp_random_graph( - num_nodes: int, - probability: float, - /, - seed: int | None = ..., -) -> PyDiGraph: ... -def undirected_gnp_random_graph( - num_nodes: int, - probability: float, - /, - seed: int | None = ..., -) -> PyGraph: ... -def random_geometric_graph( - num_nodes: int, - radius: float, - /, - dim: int = ..., - pos: list[list[float]] | None = ..., - p: float = ..., - seed: int | None = ..., -) -> PyGraph: ... -def barabasi_albert_graph( - n: int, - m: int, - seed: int | None = ..., - initial_graph: PyGraph | None = ..., -) -> PyGraph: ... -def directed_barabasi_albert_graph( - n: int, - m: int, - seed: int | None = ..., - initial_graph: PyDiGraph | None = ..., -) -> PyDiGraph: ... diff --git a/rustworkx/read_write.pyi b/rustworkx/read_write.pyi deleted file mode 100644 index 46e8b387a1..0000000000 --- a/rustworkx/read_write.pyi +++ /dev/null @@ -1,35 +0,0 @@ -# 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/json.rs, and src/graphml.rs -from .graph import PyGraph -from .digraph import PyDiGraph - -from typing import TypeVar, Callable, Any - -_S = TypeVar("_S") -_T = TypeVar("_T") - -def read_graphml(path: str, /) -> list[PyGraph | PyDiGraph]: ... -def digraph_node_link_json( - graph: PyDiGraph[_S, _T], - /, - path: str | None = ..., - graph_attrs: Callable[[Any], dict[str, str]] | None = ..., - node_attrs: Callable[[_S], str] | None = ..., - edge_attrs: Callable[[_T], str] | None = ..., -) -> str | None: ... -def graph_node_link_json( - graph: PyGraph[_S, _T], - /, - path: str | None = ..., - graph_attrs: Callable[[Any], dict[str, str]] | None = ..., - node_attrs: Callable[[_S], str] | None = ..., - edge_attrs: Callable[[_T], str] | None = ..., -) -> str | None: ... diff --git a/rustworkx/rustworkx.pyi b/rustworkx/rustworkx.pyi index ca4eea0e48..cc44779455 100644 --- a/rustworkx/rustworkx.pyi +++ b/rustworkx/rustworkx.pyi @@ -9,31 +9,31 @@ # This file contains only type annotations for PyO3 functions and classes # For implementation details, see __init__.py and src/lib.rs -from .iterators import * -from .graph import PyGraph as PyGraph -from .digraph import PyDiGraph as PyDiGraph - -from .cartesian_product import * -from .centrality import * -from .coloring import * -from .connectivity import * -from .dag_algo import * -from .isomorphism import * -from .layout import * -from .line_graph import * -from .link_analysis import * -from .matching import * -from .planar import * -from .random_graph import * -from .read_write import * -from .shortest_path import * -from .traversal import * -from .transitivity import * -from .tree import * -from .tensor_product import * -from .token_swapper import * -from .union import * -from . import generators as generators +from .visit import BFSVisitor, DFSVisitor, DijkstraVisitor +from typing import ( + TypeVar, + Callable, + Iterator, + final, + Sequence, + Any, + Generic, + ItemsView, + KeysView, + ValuesView, + Mapping, + overload, +) +from abc import ABC +from rustworkx import generators # noqa + +# from collections.abc import Sequence as SequenceCollection +from typing_extensions import Self + +import numpy as np + +_S = TypeVar("_S") +_T = TypeVar("_T") class DAGHasCycle(Exception): ... class DAGWouldCycle(Exception): ... @@ -46,3 +46,1316 @@ class NegativeCycle(Exception): ... class JSONSerializationError(Exception): ... class FailedToConverge(Exception): ... class InvalidMapping(Exception): ... + +# Cartesian product + +def digraph_cartesian_product( + first: PyDiGraph, + second: PyDiGraph, + /, +) -> tuple[PyDiGraph, ProductNodeMap]: ... +def graph_cartesian_product( + first: PyGraph, + second: PyGraph, + /, +) -> tuple[PyGraph, ProductNodeMap]: ... + +# Centrality + +def digraph_eigenvector_centrality( + graph: PyDiGraph[_S, _T], + /, + weight_fn: Callable[[_T], float] | None = ..., + default_weight: float = ..., + max_iter: int = ..., + tol: float = ..., +) -> CentralityMapping: ... +def graph_eigenvector_centrality( + graph: PyGraph[_S, _T], + /, + weight_fn: Callable[[_T], float] | None = ..., + default_weight: float = ..., + max_iter: int = ..., + tol: float = ..., +) -> CentralityMapping: ... +def digraph_betweenness_centrality( + graph: PyDiGraph[_S, _T], + /, + normalized: bool = ..., + endpoints: bool = ..., + parallel_threshold: int = ..., +) -> CentralityMapping: ... +def graph_betweenness_centrality( + graph: PyGraph[_S, _T], + /, + normalized: bool = ..., + endpoints: bool = ..., + parallel_threshold: int = ..., +) -> CentralityMapping: ... +def digraph_edge_betweenness_centrality( + graph: PyDiGraph[_S, _T], + /, + normalized: bool = ..., + parallel_threshold: int = ..., +) -> EdgeCentralityMapping: ... +def graph_edge_betweenness_centrality( + graph: PyGraph[_S, _T], + /, + normalized: bool = ..., + parallel_threshold: int = ..., +) -> EdgeCentralityMapping: ... +def digraph_closeness_centrality( + graph: PyDiGraph[_S, _T], + wf_improved: bool = ..., +) -> CentralityMapping: ... +def graph_closeness_centrality( + graph: PyGraph[_S, _T], + wf_improved: bool = ..., +) -> CentralityMapping: ... +def digraph_katz_centrality( + graph: PyDiGraph[_S, _T], + /, + alpha: float | None = ..., + beta: float | None = ..., + weight_fn: Callable[[_T], float] | None = ..., + default_weight: float | None = ..., + max_iter: int | None = ..., + tol: float | None = ..., +) -> CentralityMapping: ... +def graph_katz_centrality( + graph: PyGraph[_S, _T], + /, + alpha: float | None = ..., + beta: float | None = ..., + weight_fn: Callable[[_T], float] | None = ..., + default_weight: float | None = ..., + max_iter: int | None = ..., + tol: float | None = ..., +) -> CentralityMapping: ... + +# Coloring + +def graph_greedy_color(graph: PyGraph, /) -> dict[int, int]: ... +def graph_greedy_edge_color(graph: PyGraph, /) -> dict[int, int]: ... +def graph_is_bipartite(graph: PyGraph) -> bool: ... +def digraph_is_bipartite(graph: PyDiGraph) -> bool: ... +def graph_two_color(graph: PyGraph) -> dict[int, int]: ... +def digraph_two_color(graph: PyDiGraph) -> dict[int, int]: ... +def graph_misra_gries_edge_color(graph: PyGraph, /) -> dict[int, int]: ... + +# Connectivity + +def connected_components(graph: PyGraph, /) -> list[set[int]]: ... +def is_connected(graph: PyGraph, /) -> bool: ... +def is_weakly_connected(graph: PyDiGraph, /) -> bool: ... +def number_connected_components(graph: PyGraph, /) -> int: ... +def number_weakly_connected_components(graph: PyDiGraph, /) -> bool: ... +def node_connected_component(graph: PyGraph, node: int, /) -> set[int]: ... +def strongly_connected_components(graph: PyDiGraph, /) -> list[list[int]]: ... +def weakly_connected_components(graph: PyDiGraph, /) -> list[set[int]]: ... +def digraph_adjacency_matrix( + graph: PyDiGraph[_S, _T], + /, + weight_fn: Callable[[_T], float] | None = ..., + default_weight: float = ..., + null_value: float = ..., + parallel_edge: str = ..., +) -> np.ndarray: ... +def graph_adjacency_matrix( + graph: PyGraph[_S, _T], + /, + weight_fn: Callable[[_T], float] | None = ..., + default_weight: float = ..., + null_value: float = ..., + parallel_edge: str = ..., +) -> np.ndarray: ... +def cycle_basis(graph: PyGraph, /, root: int | None = ...) -> list[list[int]]: ... +def articulation_points(graph: PyGraph, /) -> set[int]: ... +def biconnected_components(graph: PyGraph, /) -> BiconnectedComponents: ... +def chain_decomposition(graph: PyGraph, /, source: int | None = ...) -> Chains: ... +def digraph_find_cycle( + graph: PyDiGraph[_S, _T], + /, + source: int | None = ..., +) -> EdgeList: ... +def digraph_complement(graph: PyDiGraph[_S, _T], /) -> PyDiGraph[_S, _T | None]: ... +def graph_complement( + graph: PyGraph[_S, _T], + /, +) -> PyGraph[_S, _T | None]: ... +def digraph_all_simple_paths( + graph: PyDiGraph, + origin: int, + to: int, + /, + min_depth: int | None = ..., + cutoff: int | None = ..., +) -> list[list[int]]: ... +def graph_all_simple_paths( + graph: PyGraph, + origin: int, + to: int, + /, + min_depth: int | None = ..., + cutoff: int | None = ..., +) -> list[list[int]]: ... +def digraph_all_pairs_all_simple_paths( + graph: PyDiGraph, + /, + min_depth: int | None = ..., + cutoff: int | None = ..., +) -> AllPairsMultiplePathMapping: ... +def graph_all_pairs_all_simple_paths( + graph: PyGraph, + /, + min_depth: int | None = ..., + cutoff: int | None = ..., +) -> AllPairsMultiplePathMapping: ... +def digraph_longest_simple_path(graph: PyDiGraph, /) -> NodeIndices | None: ... +def graph_longest_simple_path(graph: PyGraph, /) -> NodeIndices | None: ... +def digraph_core_number( + graph: PyDiGraph, + /, +) -> int: ... +def graph_core_number( + graph: PyGraph, + /, +) -> int: ... +def stoer_wagner_min_cut( + graph: PyGraph[_S, _T], + /, + weight_fn: Callable[[_T], float] | None = ..., +) -> tuple[float, NodeIndices] | None: ... +def simple_cycles(graph: PyDiGraph, /) -> Iterator[NodeIndices]: ... +def graph_isolates(graph: PyGraph) -> NodeIndices: ... +def digraph_isolates(graph: PyDiGraph) -> NodeIndices: ... + +# DAG Algorithms + +def collect_runs( + graph: PyDiGraph[_S, _T], + filter_fn: Callable[[_S], bool], +) -> list[list[_S]]: ... +def collect_bicolor_runs( + graph: PyDiGraph[_S, _T], + filter_fn: Callable[[_S], bool], + color_fn: Callable[[_T], int], +) -> list[list[_S]]: ... +def dag_longest_path( + graph: PyDiGraph[_S, _T], /, weight_fn: Callable[[int, int, _T], int] | None = ... +) -> NodeIndices: ... +def dag_longest_path_length( + graph: PyDiGraph[_S, _T], /, weight_fn: Callable[[int, int, _T], int] | None = ... +) -> int: ... +def dag_weighted_longest_path( + graph: PyDiGraph[_S, _T], + weight_fn: Callable[[int, int, _T], float], + /, +) -> NodeIndices: ... +def dag_weighted_longest_path_length( + graph: PyDiGraph[_S, _T], + weight_fn: Callable[[int, int, _T], float], + /, +) -> float: ... +def is_directed_acyclic_graph(graph: PyDiGraph, /) -> bool: ... +def topological_sort(graph: PyDiGraph, /) -> NodeIndices: ... +def topological_generations(dag: PyDiGraph, /) -> list[NodeIndices]: ... +def lexicographical_topological_sort( + dag: PyDiGraph[_S, _T], + key: Callable[[_S], str], + /, +) -> list[_S]: ... +def transitive_reduction(graph: PyDiGraph, /) -> tuple[PyDiGraph, dict[int, int]]: ... +def layers( + dag: PyDiGraph[_S, _T], + first_layer: list[int], + /, + 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: ... + +# isomorpism + +def digraph_is_isomorphic( + first: PyDiGraph[_S, _T], + second: PyDiGraph[_S, _T], + /, + node_matcher: Callable[[_S, _S], bool] | None = ..., + edge_matcher: Callable[[_T, _T], bool] | None = ..., + id_order: bool = ..., + call_limit: int | None = ..., +) -> bool: ... +def graph_is_isomorphic( + first: PyGraph[_S, _T], + second: PyGraph[_S, _T], + /, + node_matcher: Callable[[_S, _S], bool] | None = ..., + edge_matcher: Callable[[_T, _T], bool] | None = ..., + id_order: bool = ..., + call_limit: int | None = ..., +) -> bool: ... +def digraph_is_subgraph_isomorphic( + first: PyDiGraph[_S, _T], + second: PyDiGraph[_S, _T], + /, + node_matcher: Callable[[_S, _S], bool] | None = ..., + edge_matcher: Callable[[_T, _T], bool] | None = ..., + id_order: bool = ..., + induced: bool = ..., + call_limit: int | None = ..., +) -> bool: ... +def graph_is_subgraph_isomorphic( + first: PyGraph[_S, _T], + second: PyGraph[_S, _T], + /, + node_matcher: Callable[[_S, _S], bool] | None = ..., + edge_matcher: Callable[[_T, _T], bool] | None = ..., + id_order: bool = ..., + induced: bool = ..., + call_limit: int | None = ..., +) -> bool: ... +def digraph_vf2_mapping( + first: PyDiGraph[_S, _T], + second: PyDiGraph[_S, _T], + /, + node_matcher: Callable[[_S, _S], bool] | None = ..., + edge_matcher: Callable[[_T, _T], bool] | None = ..., + id_order: bool = ..., + subgraph: bool = ..., + induced: bool = ..., + call_limit: int | None = ..., +) -> Iterator[NodeMap]: ... +def graph_vf2_mapping( + first: PyGraph[_S, _T], + second: PyGraph[_S, _T], + /, + node_matcher: Callable[[_S, _S], bool] | None = ..., + edge_matcher: Callable[[_T, _T], bool] | None = ..., + id_order: bool = ..., + subgraph: bool = ..., + induced: bool = ..., + call_limit: int | None = ..., +) -> Iterator[NodeMap]: ... + +# Layout + +def digraph_bipartite_layout( + graph: PyDiGraph, + first_nodes: set[int], + /, + horizontal: bool | None = ..., + scale: float | None = ..., + center: tuple[float, float] | None = ..., + aspect_ratio: float | None = ..., +) -> Pos2DMapping: ... +def graph_bipartite_layout( + graph: PyGraph, + first_nodes: set[int], + /, + horizontal: bool | None = ..., + scale: float | None = ..., + center: tuple[float, float] | None = ..., + aspect_ratio: float | None = ..., +) -> Pos2DMapping: ... +def digraph_circular_layout( + graph: PyDiGraph, + /, + scale: float | None = ..., + center: tuple[float, float] | None = ..., +) -> Pos2DMapping: ... +def graph_circular_layout( + graph: PyGraph, + /, + scale: float | None = ..., + center: tuple[float, float] | None = ..., +) -> Pos2DMapping: ... +def digraph_random_layout( + graph: PyDiGraph, + /, + center: tuple[float, float] | None = ..., + seed: int | None = ..., +) -> Pos2DMapping: ... +def graph_random_layout( + graph: PyGraph, + /, + center: tuple[float, float] | None = ..., + seed: int | None = ..., +) -> Pos2DMapping: ... +def digraph_shell_layout( + graph: PyDiGraph, + /, + nlist: list[list[int]] | None = ..., + rotate: float | None = ..., + scale: float | None = ..., + center: tuple[float, float] | None = ..., +) -> Pos2DMapping: ... +def graph_shell_layout( + graph: PyGraph, + /, + nlist: list[list[int]] | None = ..., + rotate: float | None = ..., + scale: float | None = ..., + center: tuple[float, float] | None = ..., +) -> Pos2DMapping: ... +def digraph_spiral_layout( + graph: PyDiGraph, + /, + scale: float | None = ..., + center: tuple[float, float] | None = ..., + resolution: float | None = ..., + equidistant: bool | None = ..., +) -> Pos2DMapping: ... +def graph_spiral_layout( + graph: PyGraph, + /, + scale: float | None = ..., + center: tuple[float, float] | None = ..., + resolution: float | None = ..., + equidistant: bool | None = ..., +) -> Pos2DMapping: ... +def digraph_spring_layout( + graph: PyDiGraph[_S, _T], + pos: dict[int, tuple[float, float]] | None = ..., + fixed: set[int] | None = ..., + k: float | None = ..., + repulsive_exponent: int = ..., + adaptive_cooling: bool = ..., + num_iter: int = ..., + tol: float | None = ..., + weight_fn: Callable[[_T], float] | None = ..., + default_weight: float = ..., + scale: float = ..., + center: tuple[float, float] | None = ..., + seed: int | None = ..., + /, +) -> Pos2DMapping: ... +def graph_spring_layout( + graph: PyGraph[_S, _T], + pos: dict[int, tuple[float, float]] | None = ..., + fixed: set[int] | None = ..., + k: float | None = ..., + repulsive_exponent: int = ..., + adaptive_cooling: bool = ..., + num_iter: int = ..., + tol: float | None = ..., + weight_fn: Callable[[_T], float] | None = ..., + default_weight: float = ..., + scale: float = ..., + center: tuple[float, float] | None = ..., + seed: int | None = ..., + /, +) -> Pos2DMapping: ... + +# Line graph + +def graph_line_graph(graph: PyGraph, /) -> tuple[PyGraph, dict[int, int]]: ... + +# Link Analysis + +def hits( + graph: PyDiGraph[_S, _T], + /, + weight_fn: Callable[[_T], float] | None = ..., + nstart: dict[int, float] | None = ..., + tol: float | None = ..., + max_iter: int | None = ..., + normalized: bool | None = ..., +) -> tuple[CentralityMapping, CentralityMapping]: ... +def pagerank( + graph: PyDiGraph[_S, _T], + /, + alpha: float | None = ..., + weight_fn: Callable[[_T], float] | None = ..., + nstart: dict[int, float] | None = ..., + personalization: dict[int, float] | None = ..., + tol: float | None = ..., + max_iter: int | None = ..., + dangling: dict[int, float] | None = ..., +) -> CentralityMapping: ... + +# Matching + +def max_weight_matching( + graph: PyGraph[_S, _T], + /, + max_cardinality: bool = ..., + weight_fn: Callable[[_T], float] | None = ..., + default_weight: int = ..., + verify_optimum: bool = ..., +) -> set[tuple[int, int]]: ... +def is_matching( + graph: PyGraph, + matching: set[tuple[int, int]], + /, +) -> bool: ... +def is_maximal_matching( + graph: PyGraph, + matching: set[tuple[int, int]], + /, +) -> bool: ... + +# Planar + +def is_planar(graph: PyGraph, /) -> bool: ... + +# Random Graph + +def directed_gnm_random_graph( + num_nodes: int, + num_edges: int, + /, + seed: int | None = ..., +) -> PyDiGraph: ... +def undirected_gnm_random_graph( + num_nodes: int, + num_edges: int, + /, + seed: int | None = ..., +) -> PyGraph: ... +def directed_gnp_random_graph( + num_nodes: int, + probability: float, + /, + seed: int | None = ..., +) -> PyDiGraph: ... +def undirected_gnp_random_graph( + num_nodes: int, + probability: float, + /, + seed: int | None = ..., +) -> PyGraph: ... +def random_geometric_graph( + num_nodes: int, + radius: float, + /, + dim: int = ..., + pos: list[list[float]] | None = ..., + p: float = ..., + seed: int | None = ..., +) -> PyGraph: ... +def barabasi_albert_graph( + n: int, + m: int, + seed: int | None = ..., + initial_graph: PyGraph | None = ..., +) -> PyGraph: ... +def directed_barabasi_albert_graph( + n: int, + m: int, + seed: int | None = ..., + initial_graph: PyDiGraph | None = ..., +) -> PyDiGraph: ... + +# Read Write + +def read_graphml(path: str, /) -> list[PyGraph | PyDiGraph]: ... +def digraph_node_link_json( + graph: PyDiGraph[_S, _T], + /, + path: str | None = ..., + graph_attrs: Callable[[Any], dict[str, str]] | None = ..., + node_attrs: Callable[[_S], str] | None = ..., + edge_attrs: Callable[[_T], str] | None = ..., +) -> str | None: ... +def graph_node_link_json( + graph: PyGraph[_S, _T], + /, + path: str | None = ..., + graph_attrs: Callable[[Any], dict[str, str]] | None = ..., + node_attrs: Callable[[_S], str] | None = ..., + edge_attrs: Callable[[_T], str] | None = ..., +) -> str | None: ... + +# Shortest Path + +def digraph_bellman_ford_shortest_paths( + graph: PyDiGraph[_S, _T], + source: int, + /, + target: int | None = ..., + weight_fn: Callable[[_T], float] | None = ..., + default_weight: float = ..., + as_undirected: bool = ..., +) -> PathMapping: ... +def graph_bellman_ford_shortest_paths( + graph: PyDiGraph[_S, _T], + source: int, + /, + target: int | None = ..., + weight_fn: Callable[[_T], float] | None = ..., + default_weight: float = ..., +) -> PathMapping: ... +def digraph_bellman_ford_shortest_path_lengths( + graph: PyDiGraph[_S, _T], + node: int, + edge_cost_fn: Callable[[_T], float] | None, + /, + goal: int | None = ..., +) -> PathLengthMapping: ... +def graph_bellman_ford_shortest_path_lengths( + graph: PyGraph[_S, _T], + node: int, + edge_cost_fn: Callable[[_T], float] | None, + /, + goal: int | None = ..., +) -> PathLengthMapping: ... +def digraph_dijkstra_shortest_paths( + graph: PyDiGraph[_S, _T], + source: int, + /, + target: int | None, + weight_fn: Callable[[_T], float] | None = ..., + default_weight: float = ..., + as_undirected: bool = ..., +) -> PathMapping: ... +def graph_dijkstra_shortest_paths( + graph: PyDiGraph[_S, _T], + source: int, + /, + target: int | None, + weight_fn: Callable[[_T], float] | None = ..., + default_weight: float = ..., +) -> PathMapping: ... +def digraph_dijkstra_shortest_path_lengths( + graph: PyDiGraph[_S, _T], + node: int, + edge_cost_fn: Callable[[_T], float] | None, + /, + goal: int | None = ..., +) -> PathLengthMapping: ... +def graph_dijkstra_shortest_path_lengths( + graph: PyGraph[_S, _T], + node: int, + edge_cost_fn: Callable[[_T], float] | None, + /, + goal: int | None = ..., +) -> PathLengthMapping: ... +def digraph_all_pairs_bellman_ford_path_lengths( + graph: PyDiGraph[_S, _T], + edge_cost: Callable[[_T], float], + /, +) -> AllPairsPathLengthMapping: ... +def graph_all_pairs_bellman_ford_path_lengths( + graph: PyGraph[_S, _T], + edge_cost: Callable[[_T], float], + /, +) -> AllPairsPathLengthMapping: ... +def digraph_all_pairs_bellman_ford_shortest_paths( + graph: PyDiGraph[_S, _T], + edge_cost: Callable[[_T], float], + /, +) -> AllPairsPathMapping: ... +def graph_all_pairs_bellman_ford_shortest_paths( + graph: PyDiGraph[_S, _T], + edge_cost: Callable[[_T], float], + /, +) -> AllPairsPathMapping: ... +def digraph_all_pairs_dijkstra_path_lengths( + graph: PyDiGraph[_S, _T], + edge_cost: Callable[[_T], float], + /, +) -> AllPairsPathLengthMapping: ... +def graph_all_pairs_dijkstra_path_lengths( + graph: PyGraph[_S, _T], + edge_cost: Callable[[_T], float], + /, +) -> AllPairsPathLengthMapping: ... +def digraph_all_pairs_dijkstra_shortest_paths( + graph: PyDiGraph[_S, _T], + edge_cost: Callable[[_T], float], + /, +) -> AllPairsPathMapping: ... +def graph_all_pairs_dijkstra_shortest_paths( + graph: PyDiGraph[_S, _T], + edge_cost: Callable[[_T], float], + /, +) -> AllPairsPathMapping: ... +def digraph_astar_shortest_path( + graph: PyDiGraph[_S, _T], + node: int, + goal_fn: Callable[[_S], bool], + edge_cost_fn: Callable[[_T], float], + estimate_cost_fn: Callable[[_S], float], + /, +) -> NodeIndices: ... +def graph_astar_shortest_path( + graph: PyGraph[_S, _T], + node: int, + goal_fn: Callable[[_S], bool], + edge_cost_fn: Callable[[_T], float], + estimate_cost_fn: Callable[[_S], float], + /, +) -> NodeIndices: ... +def digraph_k_shortest_path_lengths( + graph: PyDiGraph[_S, _T], + start: int, + k: int, + edge_cost: Callable[[_T], float], + /, + goal: int | None = ..., +) -> PathLengthMapping: ... +def graph_k_shortest_path_lengths( + graph: PyGraph[_S, _T], + start: int, + k: int, + edge_cost: Callable[[_T], float], + /, + goal: int | None = ..., +) -> PathLengthMapping: ... +def digraph_has_path( + graph: PyDiGraph, + source: int, + target: int, + /, + as_undirected: bool | None = ..., +) -> bool: ... +def graph_has_path( + graph: PyGraph, + source: int, + target: int, +) -> bool: ... +def digraph_num_shortest_paths_unweighted( + graph: PyDiGraph, + source: int, + /, +) -> NodesCountMapping: ... +def graph_num_shortest_paths_unweighted( + graph: PyGraph, + source: int, + /, +) -> NodesCountMapping: ... +def digraph_unweighted_average_shortest_path_length( + graph: PyDiGraph, + /, + parallel_threshold: int | None = ..., + as_undirected: bool | None = ..., + disconnected: bool | None = ..., +) -> float: ... +def graph_unweighted_average_shortest_path_length( + graph: PyGraph, + /, + parallel_threshold: int | None = ..., + disconnected: bool | None = ..., +) -> float: ... +def digraph_distance_matrix( + graph: PyDiGraph, + /, + parallel_threshold: int | None = ..., + as_undirected: bool | None = ..., + null_value: float | None = ..., +) -> np.ndarray: ... +def graph_distance_matrix( + graph: PyGraph, + /, + parallel_threshold: int | None = ..., + null_value: float | None = ..., +) -> np.ndarray: ... +def digraph_floyd_warshall( + graph: PyDiGraph[_S, _T], + /, + weight_fn: Callable[[_T], float] | None = ..., + as_undirected: bool | None = ..., + default_weight: float | None = ..., + parallel_threshold: int | None = ..., +) -> AllPairsPathLengthMapping: ... +def graph_floyd_warshall( + graph: PyGraph[_S, _T], + /, + weight_fn: Callable[[_T], float] | None = ..., + default_weight: float | None = ..., + parallel_threshold: int | None = ..., +) -> AllPairsPathLengthMapping: ... +def digraph_floyd_warshall_numpy( + graph: PyDiGraph[_S, _T], + /, + weight_fn: Callable[[_T], float] | None = ..., + as_undirected: bool | None = ..., + default_weight: float | None = ..., + parallel_threshold: int | None = ..., +) -> np.ndarray: ... +def graph_floyd_warshall_numpy( + graph: PyGraph[_S, _T], + /, + weight_fn: Callable[[_T], float] | None = ..., + default_weight: float | None = ..., + parallel_threshold: int | None = ..., +) -> np.ndarray: ... +def digraph_floyd_warshall_successor_and_distance( + graph: PyDiGraph[_S, _T], + /, + weight_fn: Callable[[_T], float] | None = ..., + as_undirected: bool | None = ..., + default_weight: float | None = ..., + parallel_threshold: int | None = ..., +) -> tuple[np.ndarray, np.ndarray]: ... +def graph_floyd_warshall_successor_and_distance( + graph: PyGraph[_S, _T], + /, + weight_fn: Callable[[_T], float] | None = ..., + default_weight: float | None = ..., + parallel_threshold: int | None = ..., +) -> tuple[np.ndarray, np.ndarray]: ... +def find_negative_cycle( + graph: PyDiGraph[_S, _T], + edge_cost_fn: Callable[[_T], float], + /, +) -> NodeIndices: ... +def negative_edge_cycle( + graph: PyDiGraph[_S, _T], + 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]]: ... + +# Tensor Product + +def digraph_tensor_product( + first: PyDiGraph, + second: PyDiGraph, + /, +) -> tuple[PyDiGraph, ProductNodeMap]: ... +def graph_tensor_product( + first: PyGraph, + second: PyGraph, + /, +) -> tuple[PyGraph, ProductNodeMap]: ... + +# Token Swapper + +def graph_token_swapper( + graph: PyGraph, + mapping: dict[int, int], + /, + trials: int | None = ..., + seed: int | None = ..., + parallel_threshold: int | None = ..., +) -> EdgeList: ... + +# Transitivity + +def digraph_transitivity(graph: PyDiGraph, /) -> float: ... +def graph_transitivity(graph: PyGraph, /) -> float: ... + +# Traversal + +_BFSVisitor = TypeVar("_BFSVisitor", bound=BFSVisitor) +_DFSVisitor = TypeVar("_DFSVisitor", bound=DFSVisitor) +_DijkstraVisitor = TypeVar("_DijkstraVisitor", bound=DijkstraVisitor) + +def digraph_bfs_search( + graph: PyDiGraph, + source: int | None = ..., + visitor: _BFSVisitor | None = ..., +) -> None: ... +def graph_bfs_search( + graph: PyGraph, + source: int | None = ..., + visitor: _BFSVisitor | None = ..., +) -> None: ... +def digraph_dfs_search( + graph: PyDiGraph, + source: int | None = ..., + visitor: _DFSVisitor | None = ..., +) -> None: ... +def graph_dfs_search( + graph: PyGraph, + source: int | None = ..., + visitor: _DFSVisitor | None = ..., +) -> None: ... +def digraph_dijkstra_search( + graph: PyDiGraph, + source: int | None = ..., + weight_fn: Callable[[Any], float] | None = ..., + visitor: _DijkstraVisitor | None = ..., +) -> None: ... +def graph_dijkstra_search( + graph: PyGraph, + source: int | None = ..., + weight_fn: Callable[[Any], float] | None = ..., + visitor: _DijkstraVisitor | None = ..., +) -> None: ... +def digraph_dfs_edges(graph: PyDiGraph[_S, _T], /, source: int | None = ...) -> EdgeList: ... +def graph_dfs_edges(graph: PyGraph[_S, _T], /, source: int | None = ...) -> EdgeList: ... +def ancestors(graph: PyDiGraph, node: int, /) -> set[int]: ... +def bfs_predecessors(graph: PyDiGraph, node: int, /) -> BFSPredecessors: ... +def bfs_successors(graph: PyDiGraph, node: int, /) -> BFSSuccessors: ... +def descendants(graph: PyDiGraph, node: int, /) -> set[int]: ... + +# Tree + +def minimum_spanning_edges( + graph: PyGraph[_S, _T], + weight_fn: Callable[[_T], float] | None = ..., + default_weight: float = ..., +) -> WeightedEdgeList: ... +def minimum_spanning_tree( + graph: PyGraph[_S, _T], + weight_fn: Callable[[_T], float] | None = ..., + default_weight: float = ..., +) -> PyGraph[_S, _T]: ... +def steiner_tree( + graph: PyGraph[_S, _T], + terminal_nodes: list[int], + weight_fn: Callable[[_T], float], + /, +) -> PyGraph[_S, _T]: ... +def metric_closure( + graph: PyGraph[_S, _T], + weight_fn: Callable[[_T], float], + /, +) -> PyGraph: ... + +# Union + +def digraph_union( + first: PyDiGraph[_S, _T], + second: PyDiGraph[_S, _T], + /, + merge_nodes: bool = ..., + merge_edges: bool = ..., +) -> PyDiGraph[_S, _T]: ... +def graph_union( + first: PyGraph[_S, _T], + second: PyGraph[_S, _T], + /, + merge_nodes: bool = ..., + merge_edges: bool = ..., +) -> PyGraph[_S, _T]: ... + +# Iterators + +_T_co = TypeVar("_T_co", covariant=True) + +class _RustworkxCustomVecIter(Generic[_T_co], Sequence[_T_co], ABC): + def __init__(self) -> None: ... + def __eq__(self, other: object) -> bool: ... + @overload + def __getitem__(self, index: int) -> _T_co: ... + @overload + def __getitem__(self: Self, index: slice) -> Self: ... + def __getstate__(self) -> Any: ... + def __hash__(self) -> int: ... + def __len__(self) -> int: ... + def __ne__(self, other: object) -> bool: ... + def __setstate__(self, state: Sequence[_T_co]) -> None: ... + def __array__(self, _dt: np.dtype | None = ...) -> np.ndarray: ... + +class _RustworkxCustomHashMapIter(Generic[_S, _T_co], Mapping[_S, _T_co], ABC): + def __init__(self) -> None: ... + def items(self) -> ItemsView[_S, _T_co]: ... + def keys(self) -> KeysView[_S]: ... + def values(self) -> ValuesView[_T_co]: ... + def __contains__(self, other: object) -> bool: ... + def __eq__(self, other: object) -> bool: ... + def __getitem__(self, index: _S) -> _T_co: ... + def __getstate__(self) -> Any: ... + def __hash__(self) -> int: ... + def __iter__(self) -> Iterator[_S]: ... + def __len__(self) -> int: ... + def __ne__(self, other: object) -> bool: ... + def __setstate__(self, state: Mapping[_S, _T_co]) -> None: ... + +@final +class NodeIndices(_RustworkxCustomVecIter[int]): ... + +@final +class PathLengthMapping(_RustworkxCustomHashMapIter[int, float]): ... + +@final +class PathMapping(_RustworkxCustomHashMapIter[int, NodeIndices]): ... + +@final +class AllPairsPathLengthMapping(_RustworkxCustomHashMapIter[int, PathLengthMapping]): ... + +@final +class AllPairsPathMapping(_RustworkxCustomHashMapIter[int, PathMapping]): ... + +@final +class BFSSuccessors(Generic[_T_co], _RustworkxCustomVecIter[tuple[_T_co, list[_T_co]]]): ... + +@final +class BFSPredecessors(Generic[_T_co], _RustworkxCustomVecIter[tuple[_T_co, list[_T_co]]]): ... + +@final +class EdgeIndexMap(Generic[_T_co], _RustworkxCustomHashMapIter[int, tuple[int, int, _T_co]]): ... + +@final +class EdgeIndices(_RustworkxCustomVecIter[int]): ... + +@final +class Chains(_RustworkxCustomVecIter[EdgeIndices]): ... + +@final +class EdgeList(_RustworkxCustomVecIter[tuple[int, int]]): ... + +@final +class NodeMap(_RustworkxCustomHashMapIter[int, int]): ... + +@final +class NodesCountMapping(_RustworkxCustomHashMapIter[int, int]): ... + +@final +class Pos2DMapping(_RustworkxCustomHashMapIter[int, tuple[float, float]]): ... + +@final +class WeightedEdgeList(Generic[_T_co], _RustworkxCustomVecIter[tuple[int, int, _T_co]]): ... + +@final +class CentralityMapping(_RustworkxCustomHashMapIter[int, float]): ... + +@final +class EdgeCentralityMapping(_RustworkxCustomHashMapIter[int, float]): ... + +@final +class BiconnectedComponents(_RustworkxCustomHashMapIter[tuple[int, int], int]): ... + +@final +class ProductNodeMap(_RustworkxCustomHashMapIter[tuple[int, int], int]): ... + +@final +class MultiplePathMapping(_RustworkxCustomHashMapIter[int, list[list[int]]]): ... + +@final +class AllPairsMultiplePathMapping(_RustworkxCustomHashMapIter[int, MultiplePathMapping]): ... + +# Graph + +class PyGraph(Generic[_S, _T]): + attrs: Any + multigraph: bool = ... + def __init__(self, /, multigraph: bool = ...) -> None: ... + def add_edge(self, node_a: int, node_b: int, edge: _T, /) -> int: ... + def add_edges_from( + self, + obj_list: Sequence[tuple[int, int, _T]], + /, + ) -> list[int]: ... + def add_edges_from_no_data( + self: PyGraph[_S, _T | None], obj_list: Sequence[tuple[int, int]], / + ) -> list[int]: ... + def add_node(self, obj: _S, /) -> int: ... + def add_nodes_from(self, obj_list: Sequence[_S], /) -> NodeIndices: ... + def adj(self, node: int, /) -> dict[int, _T]: ... + def clear(self) -> None: ... + def clear_edges(self) -> None: ... + def compose( + self, + other: PyGraph[_S, _T], + node_map: dict[int, tuple[int, _T]], + /, + node_map_func: Callable[[_S], int] | None = ..., + edge_map_func: Callable[[_T], int] | None = ..., + ) -> dict[int, int]: ... + def contract_nodes( + self, + nodes: Sequence[int], + obj: _S, + /, + weight_combo_fn: Callable[[_T, _T], _T] | None = ..., + ) -> int: ... + def copy(self) -> PyGraph[_S, _T]: ... + def degree(self, node: int, /) -> int: ... + def edge_index_map(self) -> EdgeIndexMap[_T]: ... + def edge_indices(self) -> EdgeIndices: ... + def edge_list(self) -> EdgeList: ... + def edges(self) -> list[_T]: ... + def edge_subgraph(self, edge_list: Sequence[tuple[int, int]], /) -> PyGraph[_S, _T]: ... + def extend_from_edge_list( + self: PyGraph[_S | None, _T | None], edge_list: Sequence[tuple[int, int]], / + ) -> None: ... + def extend_from_weighted_edge_list( + self: PyGraph[_S | None, _T], + edge_list: Sequence[tuple[int, int, _T]], + /, + ) -> None: ... + def filter_edges(self, filter_function: Callable[[_T], bool]) -> EdgeIndices: ... + def filter_nodes(self, filter_function: Callable[[_S], bool]) -> NodeIndices: ... + def find_node_by_weight( + self, + obj: Callable[[_S], bool], + /, + ) -> int | None: ... + @staticmethod + def from_adjacency_matrix( + matrix: np.ndarray, /, null_value: float = ... + ) -> PyGraph[int, float]: ... + @staticmethod + def from_complex_adjacency_matrix( + matrix: np.ndarray, /, null_value: complex = ... + ) -> PyGraph[int, complex]: ... + def get_all_edge_data(self, node_a: int, node_b: int, /) -> list[_T]: ... + def get_edge_data(self, node_a: int, node_b: int, /) -> _T: ... + def get_edge_data_by_index(self, edge_index: int, /) -> _T: ... + def get_edge_endpoints_by_index(self, edge_index: int, /) -> tuple[int, int]: ... + def get_node_data(self, node: int, /) -> _S: ... + def has_edge(self, node_a: int, node_b: int, /) -> bool: ... + def has_parallel_edges(self) -> bool: ... + def in_edges(self, node: int, /) -> WeightedEdgeList[_T]: ... + def incident_edge_index_map(self, node: int, /) -> EdgeIndexMap: ... + def incident_edges(self, node: int, /) -> EdgeIndices: ... + def neighbors(self, node: int, /) -> NodeIndices: ... + def node_indexes(self) -> NodeIndices: ... + def node_indices(self) -> NodeIndices: ... + def nodes(self) -> list[_S]: ... + def num_edges(self) -> int: ... + def num_nodes(self) -> int: ... + def out_edges(self, node: int, /) -> WeightedEdgeList[_T]: ... + @staticmethod + def read_edge_list( + path: str, + /, + comment: str | None = ..., + deliminator: str | None = ..., + labels: bool = ..., + ) -> PyGraph: ... + def remove_edge(self, node_a: int, node_b: int, /) -> None: ... + def remove_edge_from_index(self, edge: int, /) -> None: ... + def remove_edges_from(self, index_list: Sequence[tuple[int, int]], /) -> None: ... + def remove_node(self, node: int, /) -> None: ... + def remove_nodes_from(self, index_list: Sequence[int], /) -> None: ... + def subgraph(self, nodes: Sequence[int], /, preserve_attrs: bool = ...) -> PyGraph[_S, _T]: ... + def substitute_node_with_subgraph( + self, + node: int, + other: PyGraph[_S, _T], + edge_map_fn: Callable[[int, int, _T], int | None], + /, + node_filter: Callable[[_S], bool] | None = ..., + edge_weight_map: Callable[[_T], _T] | None = ..., + ) -> NodeMap: ... + def to_dot( + self, + /, + node_attr: Callable[[_S], dict[str, str]] | None = ..., + edge_attr: Callable[[_T], dict[str, str]] | None = ..., + graph_attr: dict[str, str] | None = ..., + filename: str | None = None, + ) -> str | None: ... + def to_directed(self) -> PyDiGraph[_S, _T]: ... + def update_edge( + self, + source: int, + target: int, + edge: _T, + /, + ) -> None: ... + def update_edge_by_index(self, edge_index: int, edge: _T, /) -> None: ... + def weighted_edge_list(self) -> WeightedEdgeList[_T]: ... + def write_edge_list( + self, + path: str, + /, + deliminator: str | None = ..., + weight_fn: Callable[[_T], str] | None = ..., + ) -> None: ... + def __delitem__(self, idx: int, /) -> None: ... + def __getitem__(self, idx: int, /) -> _S: ... + def __getstate__(self) -> Any: ... + def __len__(self) -> int: ... + def __setitem__(self, idx: int, value: _S, /) -> None: ... + def __setstate__(self, state, /) -> None: ... + +# Digraph + +class PyDiGraph(Generic[_S, _T]): + attrs: Any + check_cycle: bool = ... + multigraph: bool = ... + def __init__( + self, + /, + check_cycle: bool = ..., + multigraph: bool = ..., + ) -> None: ... + def add_child(self, parent: int, obj: _S, edge: _T, /) -> int: ... + def add_edge(self, parent: int, child: int, edge: _T, /) -> int: ... + def add_edges_from( + self, + obj_list: Sequence[tuple[int, int, _T]], + /, + ) -> list[int]: ... + def add_edges_from_no_data( + self: PyDiGraph[_S, _T | None], obj_list: Sequence[tuple[int, int]], / + ) -> list[int]: ... + def add_node(self, obj: _S, /) -> int: ... + def add_nodes_from(self, obj_list: Sequence[_S], /) -> NodeIndices: ... + def add_parent(self, child: int, obj: _S, edge: _T, /) -> int: ... + def adj(self, node: int, /) -> dict[int, _T]: ... + def adj_direction(self, node: int, direction: bool, /) -> dict[int, _T]: ... + def clear(self) -> None: ... + def clear_edges(self) -> None: ... + def compose( + self, + other: PyDiGraph[_S, _T], + node_map: dict[int, tuple[int, _T]], + /, + node_map_func: Callable[[_S], int] | None = ..., + edge_map_func: Callable[[_T], int] | None = ..., + ) -> dict[int, int]: ... + def contract_nodes( + self, + nodes: Sequence[int], + obj: _S, + /, + check_cycle: bool | None = ..., + weight_combo_fn: Callable[[_T, _T], _T] | None = ..., + ) -> int: ... + def copy(self) -> PyDiGraph[_S, _T]: ... + def edge_index_map(self) -> EdgeIndexMap[_T]: ... + def edge_indices(self) -> EdgeIndices: ... + def edge_list(self) -> EdgeList: ... + def edges(self) -> list[_T]: ... + def edge_subgraph(self, edge_list: Sequence[tuple[int, int]], /) -> PyDiGraph[_S, _T]: ... + def extend_from_edge_list( + self: PyDiGraph[_S | None, _T | None], edge_list: Sequence[tuple[int, int]], / + ) -> None: ... + def extend_from_weighted_edge_list( + self: PyDiGraph[_S | None, _T], + edge_list: Sequence[tuple[int, int, _T]], + /, + ) -> None: ... + def filter_edges(self, filter_function: Callable[[_T], bool]) -> EdgeIndices: ... + def filter_nodes(self, filter_function: Callable[[_S], bool]) -> NodeIndices: ... + def find_adjacent_node_by_edge(self, node: int, predicate: Callable[[_T], bool], /) -> _S: ... + def find_node_by_weight( + self, + obj: Callable[[_S], bool], + /, + ) -> int | None: ... + def find_predecessors_by_edge( + self, node: int, filter_fn: Callable[[_T], bool], / + ) -> list[_S]: ... + def find_predecessor_node_by_edge( + self, node: int, predicate: Callable[[_T], bool], / + ) -> _S: ... + def find_successors_by_edge( + self, node: int, filter_fn: Callable[[_T], bool], / + ) -> list[_S]: ... + @staticmethod + def from_adjacency_matrix( + matrix: np.ndarray, /, null_value: float = ... + ) -> PyDiGraph[int, float]: ... + @staticmethod + def from_complex_adjacency_matrix( + matrix: np.ndarray, /, null_value: complex = ... + ) -> PyDiGraph[int, complex]: ... + def get_all_edge_data(self, node_a: int, node_b: int, /) -> list[_T]: ... + def get_edge_data(self, node_a: int, node_b: int, /) -> _T: ... + def get_node_data(self, node: int, /) -> _S: ... + def get_edge_data_by_index(self, edge_index: int, /) -> _T: ... + def get_edge_endpoints_by_index(self, edge_index: int, /) -> tuple[int, int]: ... + def has_edge(self, node_a: int, node_b: int, /) -> bool: ... + def has_parallel_edges(self) -> bool: ... + def in_degree(self, node: int, /) -> int: ... + def in_edges(self, node: int, /) -> WeightedEdgeList[_T]: ... + def incident_edge_index_map(self, node: int, /, all_edges: bool = ...) -> EdgeIndexMap: ... + def incident_edges(self, node: int, /, all_edges: bool = ...) -> EdgeIndices: ... + def insert_node_on_in_edges(self, node: int, ref_node: int, /) -> None: ... + def insert_node_on_in_edges_multiple(self, node: int, ref_nodes: Sequence[int], /) -> None: ... + def insert_node_on_out_edges(self, node: int, ref_node: int, /) -> None: ... + def insert_node_on_out_edges_multiple(self, node: int, ref_nodes: Sequence[int], /) -> None: ... + def is_symmetric(self) -> bool: ... + def make_symmetric(self, edge_payload_fn: Callable[[_T], _T] | None = ...) -> None: ... + def merge_nodes(self, u: int, v: int, /) -> None: ... + def neighbors(self, node: int, /) -> NodeIndices: ... + def node_indexes(self) -> NodeIndices: ... + def node_indices(self) -> NodeIndices: ... + def nodes(self) -> list[_S]: ... + def num_edges(self) -> int: ... + def num_nodes(self) -> int: ... + def out_degree(self, node: int, /) -> int: ... + def out_edges(self, node: int, /) -> WeightedEdgeList[_T]: ... + def predecessor_indices(self, node: int, /) -> NodeIndices: ... + def predecessors(self, node: int, /) -> list[_S]: ... + @staticmethod + def read_edge_list( + path: str, + /, + comment: str | None = ..., + deliminator: str | None = ..., + labels: bool = ..., + ) -> PyDiGraph: ... + def remove_edge(self, parent: int, child: int, /) -> None: ... + def remove_edge_from_index(self, edge: int, /) -> None: ... + def remove_edges_from(self, index_list: Sequence[tuple[int, int]], /) -> None: ... + def remove_node(self, node: int, /) -> None: ... + def remove_node_retain_edges( + self, + node: int, + /, + use_outgoing: bool | None = ..., + condition: Callable[[_S, _S], bool] | None = ..., + ) -> None: ... + def remove_nodes_from(self, index_list: Sequence[int], /) -> None: ... + def subgraph( + self, nodes: Sequence[int], /, preserve_attrs: bool = ... + ) -> PyDiGraph[_S, _T]: ... + def substitute_node_with_subgraph( + self, + node: int, + other: PyDiGraph[_S, _T], + edge_map_fn: Callable[[int, int, _T], int | None], + /, + node_filter: Callable[[_S], bool] | None = ..., + edge_weight_map: Callable[[_T], _T] | None = ..., + ) -> NodeMap: ... + def successor_indices(self, node: int, /) -> NodeIndices: ... + def successors(self, node: int, /) -> list[_S]: ... + def to_dot( + self, + /, + node_attr: Callable[[_S], dict[str, str]] | None = ..., + edge_attr: Callable[[_T], dict[str, str]] | None = ..., + graph_attr: dict[str, str] | None = ..., + filename: str | None = None, + ) -> str | None: ... + def to_undirected( + self, + /, + multigraph: bool = ..., + weight_combo_fn: Callable[[_T, _T], _T] | None = ..., + ) -> PyGraph[_S, _T]: ... + def update_edge( + self, + source: int, + target: int, + edge: _T, + /, + ) -> None: ... + def update_edge_by_index(self, edge_index: int, edge: _T, /) -> None: ... + def weighted_edge_list(self) -> WeightedEdgeList[_T]: ... + def write_edge_list( + self, + path: str, + /, + deliminator: str | None = ..., + weight_fn: Callable[[_T], str] | None = ..., + ) -> None: ... + def reverse(self) -> None: ... + def __delitem__(self, idx: int, /) -> None: ... + def __getitem__(self, idx: int, /) -> _S: ... + def __getstate__(self) -> Any: ... + def __len__(self) -> int: ... + def __setitem__(self, idx: int, value: _S, /) -> None: ... + def __setstate__(self, state, /) -> None: ... diff --git a/rustworkx/shortest_path.pyi b/rustworkx/shortest_path.pyi deleted file mode 100644 index 2a6b7b243a..0000000000 --- a/rustworkx/shortest_path.pyi +++ /dev/null @@ -1,276 +0,0 @@ -# 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 TypeVar, Callable - -_S = TypeVar("_S") -_T = TypeVar("_T") - -def digraph_bellman_ford_shortest_paths( - graph: PyDiGraph[_S, _T], - source: int, - /, - target: int | None = ..., - weight_fn: Callable[[_T], float] | None = ..., - default_weight: float = ..., - as_undirected: bool = ..., -) -> PathMapping: ... -def graph_bellman_ford_shortest_paths( - graph: PyDiGraph[_S, _T], - source: int, - /, - target: int | None = ..., - weight_fn: Callable[[_T], float] | None = ..., - default_weight: float = ..., -) -> PathMapping: ... -def digraph_bellman_ford_shortest_path_lengths( - graph: PyDiGraph[_S, _T], - node: int, - edge_cost_fn: Callable[[_T], float] | None, - /, - goal: int | None = ..., -) -> PathLengthMapping: ... -def graph_bellman_ford_shortest_path_lengths( - graph: PyGraph[_S, _T], - node: int, - edge_cost_fn: Callable[[_T], float] | None, - /, - goal: int | None = ..., -) -> PathLengthMapping: ... -def digraph_dijkstra_shortest_paths( - graph: PyDiGraph[_S, _T], - source: int, - /, - target: int | None, - weight_fn: Callable[[_T], float] | None = ..., - default_weight: float = ..., - as_undirected: bool = ..., -) -> PathMapping: ... -def graph_dijkstra_shortest_paths( - graph: PyDiGraph[_S, _T], - source: int, - /, - target: int | None, - weight_fn: Callable[[_T], float] | None = ..., - default_weight: float = ..., -) -> PathMapping: ... -def digraph_dijkstra_shortest_path_lengths( - graph: PyDiGraph[_S, _T], - node: int, - edge_cost_fn: Callable[[_T], float] | None, - /, - goal: int | None = ..., -) -> PathLengthMapping: ... -def graph_dijkstra_shortest_path_lengths( - graph: PyGraph[_S, _T], - node: int, - edge_cost_fn: Callable[[_T], float] | None, - /, - goal: int | None = ..., -) -> PathLengthMapping: ... -def digraph_all_pairs_bellman_ford_path_lengths( - graph: PyDiGraph[_S, _T], - edge_cost: Callable[[_T], float], - /, -) -> AllPairsPathLengthMapping: ... -def graph_all_pairs_bellman_ford_path_lengths( - graph: PyGraph[_S, _T], - edge_cost: Callable[[_T], float], - /, -) -> AllPairsPathLengthMapping: ... -def digraph_all_pairs_bellman_ford_shortest_paths( - graph: PyDiGraph[_S, _T], - edge_cost: Callable[[_T], float], - /, -) -> AllPairsPathMapping: ... -def graph_all_pairs_bellman_ford_shortest_paths( - graph: PyDiGraph[_S, _T], - edge_cost: Callable[[_T], float], - /, -) -> AllPairsPathMapping: ... -def digraph_all_pairs_dijkstra_path_lengths( - graph: PyDiGraph[_S, _T], - edge_cost: Callable[[_T], float], - /, -) -> AllPairsPathLengthMapping: ... -def graph_all_pairs_dijkstra_path_lengths( - graph: PyGraph[_S, _T], - edge_cost: Callable[[_T], float], - /, -) -> AllPairsPathLengthMapping: ... -def digraph_all_pairs_dijkstra_shortest_paths( - graph: PyDiGraph[_S, _T], - edge_cost: Callable[[_T], float], - /, -) -> AllPairsPathMapping: ... -def graph_all_pairs_dijkstra_shortest_paths( - graph: PyDiGraph[_S, _T], - edge_cost: Callable[[_T], float], - /, -) -> AllPairsPathMapping: ... -def digraph_astar_shortest_path( - graph: PyDiGraph[_S, _T], - node: int, - goal_fn: Callable[[_S], bool], - edge_cost_fn: Callable[[_T], float], - estimate_cost_fn: Callable[[_S], float], - /, -) -> NodeIndices: ... -def graph_astar_shortest_path( - graph: PyGraph[_S, _T], - node: int, - goal_fn: Callable[[_S], bool], - edge_cost_fn: Callable[[_T], float], - estimate_cost_fn: Callable[[_S], float], - /, -) -> NodeIndices: ... -def digraph_k_shortest_path_lengths( - graph: PyDiGraph[_S, _T], - start: int, - k: int, - edge_cost: Callable[[_T], float], - /, - goal: int | None = ..., -) -> PathLengthMapping: ... -def graph_k_shortest_path_lengths( - graph: PyGraph[_S, _T], - start: int, - k: int, - edge_cost: Callable[[_T], float], - /, - goal: int | None = ..., -) -> PathLengthMapping: ... -def digraph_has_path( - graph: PyDiGraph, - source: int, - target: int, - /, - as_undirected: bool | None = ..., -) -> bool: ... -def graph_has_path( - graph: PyGraph, - source: int, - target: int, -) -> bool: ... -def digraph_num_shortest_paths_unweighted( - graph: PyDiGraph, - source: int, - /, -) -> NodesCountMapping: ... -def graph_num_shortest_paths_unweighted( - graph: PyGraph, - source: int, - /, -) -> NodesCountMapping: ... -def digraph_unweighted_average_shortest_path_length( - graph: PyDiGraph, - /, - parallel_threshold: int | None = ..., - as_undirected: bool | None = ..., - disconnected: bool | None = ..., -) -> float: ... -def graph_unweighted_average_shortest_path_length( - graph: PyGraph, - /, - parallel_threshold: int | None = ..., - disconnected: bool | None = ..., -) -> float: ... -def digraph_distance_matrix( - graph: PyDiGraph, - /, - parallel_threshold: int | None = ..., - as_undirected: bool | None = ..., - null_value: float | None = ..., -) -> np.ndarray: ... -def graph_distance_matrix( - graph: PyGraph, - /, - parallel_threshold: int | None = ..., - null_value: float | None = ..., -) -> np.ndarray: ... -def digraph_floyd_warshall( - graph: PyDiGraph[_S, _T], - /, - weight_fn: Callable[[_T], float] | None = ..., - as_undirected: bool | None = ..., - default_weight: float | None = ..., - parallel_threshold: int | None = ..., -) -> AllPairsPathLengthMapping: ... -def graph_floyd_warshall( - graph: PyGraph[_S, _T], - /, - weight_fn: Callable[[_T], float] | None = ..., - default_weight: float | None = ..., - parallel_threshold: int | None = ..., -) -> AllPairsPathLengthMapping: ... -def digraph_floyd_warshall_numpy( - graph: PyDiGraph[_S, _T], - /, - weight_fn: Callable[[_T], float] | None = ..., - as_undirected: bool | None = ..., - default_weight: float | None = ..., - parallel_threshold: int | None = ..., -) -> np.ndarray: ... -def graph_floyd_warshall_numpy( - graph: PyGraph[_S, _T], - /, - weight_fn: Callable[[_T], float] | None = ..., - default_weight: float | None = ..., - parallel_threshold: int | None = ..., -) -> np.ndarray: ... -def digraph_floyd_warshall_successor_and_distance( - graph: PyDiGraph[_S, _T], - /, - weight_fn: Callable[[_T], float] | None = ..., - as_undirected: bool | None = ..., - default_weight: float | None = ..., - parallel_threshold: int | None = ..., -) -> tuple[np.ndarray, np.ndarray]: ... -def graph_floyd_warshall_successor_and_distance( - graph: PyGraph[_S, _T], - /, - weight_fn: Callable[[_T], float] | None = ..., - default_weight: float | None = ..., - parallel_threshold: int | None = ..., -) -> tuple[np.ndarray, np.ndarray]: ... -def find_negative_cycle( - graph: PyDiGraph[_S, _T], - edge_cost_fn: Callable[[_T], float], - /, -) -> NodeIndices: ... -def negative_edge_cycle( - graph: PyDiGraph[_S, _T], - 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/rustworkx/tensor_product.pyi b/rustworkx/tensor_product.pyi deleted file mode 100644 index d648b4c594..0000000000 --- a/rustworkx/tensor_product.pyi +++ /dev/null @@ -1,25 +0,0 @@ -# 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/tensor_product.rs - -from .iterators import * -from .graph import PyGraph -from .digraph import PyDiGraph - -def digraph_tensor_product( - first: PyDiGraph, - second: PyDiGraph, - /, -) -> tuple[PyDiGraph, ProductNodeMap]: ... -def graph_tensor_product( - first: PyGraph, - second: PyGraph, - /, -) -> tuple[PyGraph, ProductNodeMap]: ... diff --git a/rustworkx/token_swapper.pyi b/rustworkx/token_swapper.pyi deleted file mode 100644 index 3532d1e7ef..0000000000 --- a/rustworkx/token_swapper.pyi +++ /dev/null @@ -1,22 +0,0 @@ -# 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/token_swapper.rs - -from .iterators import * -from .graph import PyGraph - -def graph_token_swapper( - graph: PyGraph, - mapping: dict[int, int], - /, - trials: int | None = ..., - seed: int | None = ..., - parallel_threshold: int | None = ..., -) -> EdgeList: ... diff --git a/rustworkx/transitivity.pyi b/rustworkx/transitivity.pyi deleted file mode 100644 index f2902faefd..0000000000 --- a/rustworkx/transitivity.pyi +++ /dev/null @@ -1,16 +0,0 @@ -# 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/transitivity.rs - -from .graph import PyGraph -from .digraph import PyDiGraph - -def digraph_transitivity(graph: PyDiGraph, /) -> float: ... -def graph_transitivity(graph: PyGraph, /) -> float: ... diff --git a/rustworkx/traversal.pyi b/rustworkx/traversal.pyi deleted file mode 100644 index d00e1507b7..0000000000 --- a/rustworkx/traversal.pyi +++ /dev/null @@ -1,62 +0,0 @@ -# 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/traversal/mod.rs - -from .iterators import * -from .graph import PyGraph -from .digraph import PyDiGraph -from .visit import BFSVisitor, DFSVisitor, DijkstraVisitor - -from typing import Any, TypeVar, Callable - -_S = TypeVar("_S") -_T = TypeVar("_T") -_BFSVisitor = TypeVar("_BFSVisitor", bound=BFSVisitor) -_DFSVisitor = TypeVar("_DFSVisitor", bound=DFSVisitor) -_DijkstraVisitor = TypeVar("_DijkstraVisitor", bound=DijkstraVisitor) - -def digraph_bfs_search( - graph: PyDiGraph, - source: int | None = ..., - visitor: _BFSVisitor | None = ..., -) -> None: ... -def graph_bfs_search( - graph: PyGraph, - source: int | None = ..., - visitor: _BFSVisitor | None = ..., -) -> None: ... -def digraph_dfs_search( - graph: PyDiGraph, - source: int | None = ..., - visitor: _DFSVisitor | None = ..., -) -> None: ... -def graph_dfs_search( - graph: PyGraph, - source: int | None = ..., - visitor: _DFSVisitor | None = ..., -) -> None: ... -def digraph_dijkstra_search( - graph: PyDiGraph, - source: int | None = ..., - weight_fn: Callable[[Any], float] | None = ..., - visitor: _DijkstraVisitor | None = ..., -) -> None: ... -def graph_dijkstra_search( - graph: PyGraph, - source: int | None = ..., - weight_fn: Callable[[Any], float] | None = ..., - visitor: _DijkstraVisitor | None = ..., -) -> None: ... -def digraph_dfs_edges(graph: PyDiGraph[_S, _T], /, source: int | None = ...) -> EdgeList: ... -def graph_dfs_edges(graph: PyGraph[_S, _T], /, source: int | None = ...) -> EdgeList: ... -def ancestors(graph: PyDiGraph, node: int, /) -> set[int]: ... -def bfs_predecessors(graph: PyDiGraph, node: int, /) -> BFSPredecessors: ... -def bfs_successors(graph: PyDiGraph, node: int, /) -> BFSSuccessors: ... -def descendants(graph: PyDiGraph, node: int, /) -> set[int]: ... diff --git a/rustworkx/tree.pyi b/rustworkx/tree.pyi deleted file mode 100644 index cc690b593c..0000000000 --- a/rustworkx/tree.pyi +++ /dev/null @@ -1,40 +0,0 @@ -# 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, src/tree.rs, and src/steiner_tree.rs - -from .iterators import * -from .graph import PyGraph - -from typing import TypeVar, Callable - -_S = TypeVar("_S") -_T = TypeVar("_T") - -def minimum_spanning_edges( - graph: PyGraph[_S, _T], - weight_fn: Callable[[_T], float] | None = ..., - default_weight: float = ..., -) -> WeightedEdgeList: ... -def minimum_spanning_tree( - graph: PyGraph[_S, _T], - weight_fn: Callable[[_T], float] | None = ..., - default_weight: float = ..., -) -> PyGraph[_S, _T]: ... -def steiner_tree( - graph: PyGraph[_S, _T], - terminal_nodes: list[int], - weight_fn: Callable[[_T], float], - /, -) -> PyGraph[_S, _T]: ... -def metric_closure( - graph: PyGraph[_S, _T], - weight_fn: Callable[[_T], float], - /, -) -> PyGraph: ... diff --git a/rustworkx/union.pyi b/rustworkx/union.pyi deleted file mode 100644 index 0e2945daac..0000000000 --- a/rustworkx/union.pyi +++ /dev/null @@ -1,33 +0,0 @@ -# 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/union.rs - -from .graph import PyGraph -from .digraph import PyDiGraph - -from typing import TypeVar - -_S = TypeVar("_S") -_T = TypeVar("_T") - -def digraph_union( - first: PyDiGraph[_S, _T], - second: PyDiGraph[_S, _T], - /, - merge_nodes: bool = ..., - merge_edges: bool = ..., -) -> PyDiGraph[_S, _T]: ... -def graph_union( - first: PyGraph[_S, _T], - second: PyGraph[_S, _T], - /, - merge_nodes: bool = ..., - merge_edges: bool = ..., -) -> PyGraph[_S, _T]: ... diff --git a/rustworkx/visit.pyi b/rustworkx/visit.pyi index 80d975fa8d..0171307556 100644 --- a/rustworkx/visit.pyi +++ b/rustworkx/visit.pyi @@ -34,6 +34,6 @@ class DFSVisitor(Generic[_T]): class DijkstraVisitor(Generic[_T]): def discover_vertex(self, v: int, score: float): ... def finish_vertex(self, v: int): ... - def examine_edge(self, e: tuple[int, int, _T]): ... - def edge_relaxed(self, e: tuple[int, int, _T]): ... - def edge_not_relaxed(self, e: tuple[int, int, _T]): ... + def examine_edge(self, edge: tuple[int, int, _T]): ... + def edge_relaxed(self, edge: tuple[int, int, _T]): ... + def edge_not_relaxed(self, edge: tuple[int, int, _T]): ... diff --git a/src/generators.rs b/src/generators.rs index f8168d0c73..77bb0feef3 100644 --- a/src/generators.rs +++ b/src/generators.rs @@ -50,7 +50,6 @@ use rustworkx_core::generators as core_generators; #[pyfunction] #[pyo3( signature=(num_nodes=None, weights=None, multigraph=true), - text_signature = "(/, num_nodes=None, weights=None, multigraph=True)" )] pub fn cycle_graph( py: Python, @@ -106,7 +105,6 @@ pub fn cycle_graph( #[pyfunction] #[pyo3( signature=(num_nodes=None, weights=None, bidirectional=false, multigraph=true), - text_signature = "(/, num_nodes=None, weights=None, bidirectional=False, multigraph=True)" )] pub fn directed_cycle_graph( py: Python, @@ -168,7 +166,6 @@ pub fn directed_cycle_graph( #[pyfunction] #[pyo3( signature=(num_nodes=None, weights=None, multigraph=true), - text_signature = "(/, num_nodes=None, weights=None, multigraph=True)" )] pub fn path_graph( py: Python, @@ -224,7 +221,6 @@ pub fn path_graph( #[pyfunction] #[pyo3( signature=(num_nodes=None, weights=None, bidirectional=false, multigraph=true), - text_signature = "(/, num_nodes=None, weights=None, bidirectional=False, multigraph=True)" )] pub fn directed_path_graph( py: Python, @@ -287,7 +283,6 @@ pub fn directed_path_graph( #[pyfunction] #[pyo3( signature=(num_nodes=None, weights=None, multigraph=true), - text_signature = "(/, num_nodes=None, weights=None, multigraph=True)" )] pub fn star_graph( py: Python, @@ -355,7 +350,6 @@ pub fn star_graph( #[pyfunction] #[pyo3( signature=(num_nodes=None, weights=None, inward=false, bidirectional=false, multigraph=true), - text_signature = "(/, num_nodes=None, weights=None, inward=False, bidirectional=False, multigraph=True)" )] pub fn directed_star_graph( py: Python, @@ -418,7 +412,6 @@ pub fn directed_star_graph( #[pyfunction] #[pyo3( signature=(num_nodes=None, weights=None, multigraph=true), - text_signature = "(/, num_nodes=None, weights=None, multigraph=True)" )] pub fn mesh_graph( py: Python, @@ -456,7 +449,6 @@ pub fn mesh_graph( #[pyfunction] #[pyo3( signature=(num_nodes=None, weights=None, multigraph=true), - text_signature = "(/, num_nodes=None, weights=None, multigraph=True)" )] pub fn directed_mesh_graph( py: Python, @@ -502,7 +494,6 @@ pub fn directed_mesh_graph( #[pyfunction] #[pyo3( signature=(rows=None, cols=None, weights=None, multigraph=true), - text_signature = "(/, rows=None, cols=None, weights=None, multigraph=True)" )] pub fn grid_graph( py: Python, @@ -564,7 +555,6 @@ pub fn grid_graph( #[pyfunction] #[pyo3( signature=(rows=None, cols=None, weights=None, bidirectional=false, multigraph=true), - text_signature = "(/, rows=None, cols=None, weights=None, bidirectional=False, multigraph=True)" )] pub fn directed_grid_graph( py: Python, @@ -653,7 +643,6 @@ pub fn directed_grid_graph( #[pyfunction] #[pyo3( signature=(d, multigraph=true), - text_signature = "(d, /, multigraph=True)" )] pub fn heavy_square_graph(py: Python, d: usize, multigraph: bool) -> PyResult { let default_fn = || py.None(); @@ -726,7 +715,6 @@ pub fn heavy_square_graph(py: Python, d: usize, multigraph: bool) -> PyResult PyResult { let default_fn = || py.None(); @@ -893,7 +880,6 @@ pub fn heavy_hex_graph(py: Python, d: usize, multigraph: bool) -> PyResult PyResult { let mut graph = StableUnGraph::::default(); @@ -1502,7 +1480,6 @@ pub fn empty_graph(py: Python, n: usize, multigraph: bool) -> PyResult Date: Fri, 19 Jan 2024 16:42:23 -0500 Subject: [PATCH 08/19] Ignore matplotlib type checks --- rustworkx/visualization/matplotlib.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rustworkx/visualization/matplotlib.py b/rustworkx/visualization/matplotlib.py index 92952dbf19..7f1437112d 100644 --- a/rustworkx/visualization/matplotlib.py +++ b/rustworkx/visualization/matplotlib.py @@ -196,7 +196,7 @@ def mpl_draw(graph, pos=None, ax=None, arrows=True, with_labels=False, **kwds): plt.draw() """ try: - import matplotlib.pyplot as plt + import matplotlib.pyplot as plt # type: ignore except ImportError as e: raise ImportError( "matplotlib needs to be installed prior to running " @@ -427,7 +427,7 @@ def draw_nodes( """ try: import matplotlib as mpl - import matplotlib.collections # call as mpl.collections + import matplotlib.collections # type: ignore import matplotlib.pyplot as plt except ImportError as e: raise ImportError( @@ -602,9 +602,9 @@ def draw_edges( """ try: import matplotlib as mpl - import matplotlib.colors # call as mpl.colors - import matplotlib.patches # call as mpl.patches - import matplotlib.path # call as mpl.path + import matplotlib.colors # type: ignore + import matplotlib.patches # type: ignore + import matplotlib.path # type: ignore import matplotlib.pyplot as plt except ImportError as e: raise ImportError( @@ -1092,7 +1092,7 @@ def apply_alpha(colors, alpha, elem_list, cmap=None, vmin=None, vmax=None): try: import matplotlib as mpl import matplotlib.colors # call as mpl.colors - import matplotlib.cm # call as mpl.cm + import matplotlib.cm # type: ignore except ImportError as e: raise ImportError( "matplotlib needs to be installed prior to running " From 6663969687a17d01f1fd5783f43656276ec3c4e1 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sat, 20 Jan 2024 07:58:37 -0500 Subject: [PATCH 09/19] Add back type hints lost during rebase --- rustworkx/rustworkx.pyi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rustworkx/rustworkx.pyi b/rustworkx/rustworkx.pyi index cc44779455..0b8333e91c 100644 --- a/rustworkx/rustworkx.pyi +++ b/rustworkx/rustworkx.pyi @@ -171,6 +171,7 @@ def graph_adjacency_matrix( ) -> np.ndarray: ... def cycle_basis(graph: PyGraph, /, root: int | None = ...) -> list[list[int]]: ... def articulation_points(graph: PyGraph, /) -> set[int]: ... +def bridges(graph: PyGraph, /) -> set[tuple[int]]: ... def biconnected_components(graph: PyGraph, /) -> BiconnectedComponents: ... def chain_decomposition(graph: PyGraph, /, source: int | None = ...) -> Chains: ... def digraph_find_cycle( @@ -1078,6 +1079,7 @@ class PyGraph(Generic[_S, _T]): def degree(self, node: int, /) -> int: ... def edge_index_map(self) -> EdgeIndexMap[_T]: ... def edge_indices(self) -> EdgeIndices: ... + def edge_indices_from_endpoints(self, node_a: int, node_b: int) -> EdgeIndices: ... def edge_list(self) -> EdgeList: ... def edges(self) -> list[_T]: ... def edge_subgraph(self, edge_list: Sequence[tuple[int, int]], /) -> PyGraph[_S, _T]: ... @@ -1224,6 +1226,7 @@ class PyDiGraph(Generic[_S, _T]): def copy(self) -> PyDiGraph[_S, _T]: ... def edge_index_map(self) -> EdgeIndexMap[_T]: ... def edge_indices(self) -> EdgeIndices: ... + def edge_indices_from_endpoints(self, node_a: int, node_b: int) -> EdgeIndices: ... def edge_list(self) -> EdgeList: ... def edges(self) -> list[_T]: ... def edge_subgraph(self, edge_list: Sequence[tuple[int, int]], /) -> PyDiGraph[_S, _T]: ... From 63a33ba0a9112a5e243ef537b504170d29bba884 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sat, 20 Jan 2024 08:12:26 -0500 Subject: [PATCH 10/19] Add stub file for matplotlib visualization --- rustworkx/visualization/matplotlib.pyi | 58 ++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 rustworkx/visualization/matplotlib.pyi diff --git a/rustworkx/visualization/matplotlib.pyi b/rustworkx/visualization/matplotlib.pyi new file mode 100644 index 0000000000..d41583aca1 --- /dev/null +++ b/rustworkx/visualization/matplotlib.pyi @@ -0,0 +1,58 @@ +# 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. + +import typing +from rustworkx.rustworkx import PyGraph, PyDiGraph + +if typing.TYPE_CHECKING: + from matplotlib.axes import Axes + from matplotlib.figure import Figure + from matplotlib.colors import Colormap + +_S = typing.TypeVar("_S") +_T = typing.TypeVar("_T") + +class DrawKwargs(typing.TypedDict): + arrowstyle: str + arrow_size: int + node_list: list[int] + edge_list: list[int] + node_size: int | list[int] + node_color: str | tuple[float, float, float] | tuple[float, float, float, float] | list[ + str + ] | list[tuple[float, float, float]] | list[tuple[float, float, float, float]] + node_shape: str + alpha: float + cmap: Colormap + vmin: float + vmax: float + linewidths: float | list[float] + edge_color: str | tuple[float, float, float] | tuple[float, float, float, float] | list[ + str + ] | list[tuple[float, float, float]] | list[tuple[float, float, float, float]] + edge_cmap: Colormap + edge_vmin: float + edge_vmax: float + style: str + labels: typing.Callable[[_S], str] + edge_labels: typing.Callable[[_T], str] + font_size: int + font_color: str + font_weight: str + font_family: str + label: str + connectionstyle: str + +def mpl_draw( + graph: PyGraph[_S, _T] | PyDiGraph[_S, _T], + pos: typing.Mapping[int, tuple[float, float]] | None = ..., + ax: Axes | None = ..., + arrows: bool = ..., + with_labels: bool = ..., + **kwards: typing.Unpack[DrawKwargs], +) -> Figure | None: ... From 90db18cf035147532c5e9483a655cb02673f0429 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sat, 20 Jan 2024 08:16:07 -0500 Subject: [PATCH 11/19] Bump mypy version used in tests --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index b16da749e4..a73b693d19 100644 --- a/tox.ini +++ b/tox.ini @@ -75,5 +75,5 @@ commands = black {posargs} '../rustworkx' '../tests' '../retworkx' [testenv:stubs] basepython = python3 deps = - mypy==1.0.1 + mypy==1.8.0 commands = python -m mypy.stubtest --concise rustworkx From 718033eed7e6df4cd7f8f5fd9b80a6a1ad5a3532 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sat, 20 Jan 2024 08:20:39 -0500 Subject: [PATCH 12/19] Add stub file for graphviz too --- rustworkx/visualization/graphviz.pyi | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 rustworkx/visualization/graphviz.pyi diff --git a/rustworkx/visualization/graphviz.pyi b/rustworkx/visualization/graphviz.pyi new file mode 100644 index 0000000000..f37bd5bcf4 --- /dev/null +++ b/rustworkx/visualization/graphviz.pyi @@ -0,0 +1,26 @@ +# 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. + +import typing +from rustworkx.rustworkx import PyGraph, PyDiGraph + +if typing.TYPE_CHECKING: + from PIL import Image # type: ignore + +_S = typing.TypeVar("_S") +_T = typing.TypeVar("_T") + +def graphviz_draw( + graph: PyDiGraph[_S, _T] | PyGraph[_S, _T], + node_attr_fn: typing.Callable[[_S], dict[str, str]] | None = ..., + edge_attr_fn: typing.Callable[[_T], dict[str, str]] | None = ..., + graph_attr: dict[str, str] | None = ..., + filename: str | None = ..., + image_type: str | None = ..., + method: str | None = ..., +) -> Image | None: ... From f0e2af50eb02727e807eed8bd7b23d837ccc2959 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sat, 20 Jan 2024 08:20:51 -0500 Subject: [PATCH 13/19] Fix last failure --- rustworkx/visualization/matplotlib.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rustworkx/visualization/matplotlib.pyi b/rustworkx/visualization/matplotlib.pyi index d41583aca1..b44d19d119 100644 --- a/rustworkx/visualization/matplotlib.pyi +++ b/rustworkx/visualization/matplotlib.pyi @@ -17,7 +17,7 @@ if typing.TYPE_CHECKING: _S = typing.TypeVar("_S") _T = typing.TypeVar("_T") -class DrawKwargs(typing.TypedDict): +class _DrawKwargs(typing.TypedDict): arrowstyle: str arrow_size: int node_list: list[int] @@ -54,5 +54,5 @@ def mpl_draw( ax: Axes | None = ..., arrows: bool = ..., with_labels: bool = ..., - **kwards: typing.Unpack[DrawKwargs], + **kwards: typing.Unpack[_DrawKwargs], ) -> Figure | None: ... From 732df7b1bde195021c67efd3dd3cb2a339109e11 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sat, 20 Jan 2024 08:22:32 -0500 Subject: [PATCH 14/19] Fix typo --- rustworkx/visualization/matplotlib.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rustworkx/visualization/matplotlib.pyi b/rustworkx/visualization/matplotlib.pyi index b44d19d119..6f3d5cc0ad 100644 --- a/rustworkx/visualization/matplotlib.pyi +++ b/rustworkx/visualization/matplotlib.pyi @@ -54,5 +54,5 @@ def mpl_draw( ax: Axes | None = ..., arrows: bool = ..., with_labels: bool = ..., - **kwards: typing.Unpack[_DrawKwargs], + **kwds: typing.Unpack[_DrawKwargs], ) -> Figure | None: ... From b31d6dc639fb3cefe1714165cc10e9b7412778bb Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sat, 20 Jan 2024 16:16:26 -0500 Subject: [PATCH 15/19] Use typing_extensions for mpl_draw type hints --- rustworkx/visualization/matplotlib.pyi | 5 ++++- tox.ini | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/rustworkx/visualization/matplotlib.pyi b/rustworkx/visualization/matplotlib.pyi index 6f3d5cc0ad..33a57538b4 100644 --- a/rustworkx/visualization/matplotlib.pyi +++ b/rustworkx/visualization/matplotlib.pyi @@ -7,6 +7,9 @@ # that they have been altered from the originals. import typing + +import typing_extensions + from rustworkx.rustworkx import PyGraph, PyDiGraph if typing.TYPE_CHECKING: @@ -54,5 +57,5 @@ def mpl_draw( ax: Axes | None = ..., arrows: bool = ..., with_labels: bool = ..., - **kwds: typing.Unpack[_DrawKwargs], + **kwds: typing_extensions.Unpack[_DrawKwargs], ) -> Figure | None: ... diff --git a/tox.ini b/tox.ini index a73b693d19..0258a17c51 100644 --- a/tox.ini +++ b/tox.ini @@ -76,4 +76,8 @@ commands = black {posargs} '../rustworkx' '../tests' '../retworkx' basepython = python3 deps = mypy==1.8.0 + typing-extensions +extras = + mpl + graphviz commands = python -m mypy.stubtest --concise rustworkx From 85672db3dd3a87726856983c6996896e69c0f1d6 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sun, 21 Jan 2024 09:09:02 -0500 Subject: [PATCH 16/19] Add re-exports to root __init__.pyi This commit adds back the re-exports to the root `__init__.pyi` stub file. As was reported in #960 the manual re-exports are necessary to ensure that mypy can find symbols in the root of the package, where most people use them, instead of off the inner `rustworkx.rustworkx` module. --- rustworkx/__init__.pyi | 236 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 234 insertions(+), 2 deletions(-) diff --git a/rustworkx/__init__.pyi b/rustworkx/__init__.pyi index ec90282b3c..9e8ff6086b 100644 --- a/rustworkx/__init__.pyi +++ b/rustworkx/__init__.pyi @@ -10,11 +10,243 @@ # For implementation details, see __init__.py and src/lib.rs import numpy as np -import rustworkx.visit as visit -from .rustworkx import * from typing import Generic, TypeVar, Any, Callable, Iterator, overload +# Re-Exports of rust native functions in rustworkx.rustworkx +# To workaround limitations in mypy around re-exporting objects from the inner +# rustworkx module we need to explicitly re-export every inner function from +# rustworkx.rustworkx (the root rust module) in the form: +# `from .rustworkx import foo as foo` so that mypy will treat `rustworkx.foo` +# as a valid path +import rustworkx.visit as visit + +from .rustworkx import DAGHasCycle as DAGHasCycle +from .rustworkx import DAGWouldCycle as DAGWouldCycle +from .rustworkx import InvalidNode as InvalidNode +from .rustworkx import NoEdgeBetweenNodes as NoEdgeBetweenNodes +from .rustworkx import NoPathFound as NoPathFound +from .rustworkx import NoSuitableNeighbors as NoSuitableNeighbors +from .rustworkx import NullGraph as NullGraph +from .rustworkx import NegativeCycle as NegativeCycle +from .rustworkx import JSONSerializationError as JSONSerializationError +from .rustworkx import FailedToConverge as FailedToConverge +from .rustworkx import InvalidMapping as InvalidMapping + +from .rustworkx import digraph_cartesian_product as digraph_cartesian_product +from .rustworkx import graph_cartesian_product as graph_cartesian_product +from .rustworkx import digraph_eigenvector_centrality as digraph_eigenvector_centrality +from .rustworkx import graph_eigenvector_centrality as graph_eigenvector_centrality +from .rustworkx import digraph_betweenness_centrality as digraph_betweenness_centrality +from .rustworkx import graph_betweenness_centrality as graph_betweenness_centrality +from .rustworkx import digraph_edge_betweenness_centrality as digraph_edge_betweenness_centrality +from .rustworkx import graph_edge_betweenness_centrality as graph_edge_betweenness_centrality +from .rustworkx import digraph_closeness_centrality as digraph_closeness_centrality +from .rustworkx import graph_closeness_centrality as graph_closeness_centrality +from .rustworkx import digraph_katz_centrality as digraph_katz_centrality +from .rustworkx import graph_katz_centrality as graph_katz_centrality +from .rustworkx import graph_greedy_color as graph_greedy_color +from .rustworkx import graph_greedy_edge_color as graph_greedy_edge_color +from .rustworkx import graph_is_bipartite as graph_is_bipartite +from .rustworkx import digraph_is_bipartite as digraph_is_bipartite +from .rustworkx import graph_two_color as graph_two_color +from .rustworkx import digraph_two_color as digraph_two_color +from .rustworkx import graph_misra_gries_edge_color as graph_misra_gries_edge_color +from .rustworkx import connected_components as connected_components +from .rustworkx import is_connected as is_connected +from .rustworkx import is_weakly_connected as is_weakly_connected +from .rustworkx import number_connected_components as number_connected_components +from .rustworkx import number_weakly_connected_components as number_weakly_connected_components +from .rustworkx import node_connected_component as node_connected_component +from .rustworkx import strongly_connected_components as strongly_connected_components +from .rustworkx import weakly_connected_components as weakly_connected_components +from .rustworkx import digraph_adjacency_matrix as digraph_adjacency_matrix +from .rustworkx import graph_adjacency_matrix as graph_adjacency_matrix +from .rustworkx import cycle_basis as cycle_basis +from .rustworkx import articulation_points as articulation_points +from .rustworkx import bridges as bridges +from .rustworkx import biconnected_components as biconnected_components +from .rustworkx import chain_decomposition as chain_decomposition +from .rustworkx import digraph_find_cycle as digraph_find_cycle +from .rustworkx import digraph_complement as digraph_complement +from .rustworkx import graph_complement as graph_complement +from .rustworkx import digraph_all_simple_paths as digraph_all_simple_paths +from .rustworkx import graph_all_simple_paths as graph_all_simple_paths +from .rustworkx import digraph_all_pairs_all_simple_paths as digraph_all_pairs_all_simple_paths +from .rustworkx import graph_all_pairs_all_simple_paths as graph_all_pairs_all_simple_paths +from .rustworkx import digraph_longest_simple_path as digraph_longest_simple_path +from .rustworkx import graph_longest_simple_path as graph_longest_simple_path +from .rustworkx import digraph_core_number as digraph_core_number +from .rustworkx import graph_core_number as graph_core_number +from .rustworkx import stoer_wagner_min_cut as stoer_wagner_min_cut +from .rustworkx import simple_cycles as simple_cycles +from .rustworkx import digraph_isolates as digraph_isolates +from .rustworkx import graph_isolates as graph_isolates +from .rustworkx import collect_runs as collect_runs +from .rustworkx import collect_bicolor_runs as collect_bicolor_runs +from .rustworkx import dag_longest_path as dag_longest_path +from .rustworkx import dag_longest_path_length as dag_longest_path_length +from .rustworkx import dag_weighted_longest_path as dag_weighted_longest_path +from .rustworkx import dag_weighted_longest_path_length as dag_weighted_longest_path_length +from .rustworkx import is_directed_acyclic_graph as is_directed_acyclic_graph +from .rustworkx import topological_sort as topological_sort +from .rustworkx import topological_generations as topological_generations +from .rustworkx import lexicographical_topological_sort as lexicographical_topological_sort +from .rustworkx import transitive_reduction as transitive_reduction +from .rustworkx import layers as layers +from .rustworkx import TopologicalSorter as TopologicalSorter +from .rustworkx import digraph_is_isomorphic as digraph_is_isomorphic +from .rustworkx import graph_is_isomorphic as graph_is_isomorphic +from .rustworkx import digraph_is_subgraph_isomorphic as digraph_is_subgraph_isomorphic +from .rustworkx import graph_is_subgraph_isomorphic as graph_is_subgraph_isomorphic +from .rustworkx import digraph_vf2_mapping as digraph_vf2_mapping +from .rustworkx import graph_vf2_mapping as graph_vf2_mapping +from .rustworkx import digraph_bipartite_layout as digraph_bipartite_layout +from .rustworkx import graph_bipartite_layout as graph_bipartite_layout +from .rustworkx import digraph_circular_layout as digraph_circular_layout +from .rustworkx import graph_circular_layout as graph_circular_layout +from .rustworkx import digraph_random_layout as digraph_random_layout +from .rustworkx import graph_random_layout as graph_random_layout +from .rustworkx import digraph_shell_layout as digraph_shell_layout +from .rustworkx import graph_shell_layout as graph_shell_layout +from .rustworkx import digraph_spiral_layout as digraph_spiral_layout +from .rustworkx import graph_spiral_layout as graph_spiral_layout +from .rustworkx import digraph_spring_layout as digraph_spring_layout +from .rustworkx import graph_spring_layout as graph_spring_layout +from .rustworkx import graph_line_graph as graph_line_graph +from .rustworkx import hits as hits +from .rustworkx import pagerank as pagerank +from .rustworkx import max_weight_matching as max_weight_matching +from .rustworkx import is_matching as is_matching +from .rustworkx import is_maximal_matching as is_maximal_matching +from .rustworkx import is_planar as is_planar +from .rustworkx import directed_gnm_random_graph as directed_gnm_random_graph +from .rustworkx import undirected_gnm_random_graph as undirected_gnm_random_graph +from .rustworkx import directed_gnp_random_graph as directed_gnp_random_graph +from .rustworkx import undirected_gnp_random_graph as undirected_gnp_random_graph +from .rustworkx import random_geometric_graph as random_geometric_graph +from .rustworkx import barabasi_albert_graph as barabasi_albert_graph +from .rustworkx import directed_barabasi_albert_graph as directed_barabasi_albert_graph +from .rustworkx import read_graphml as read_graphml +from .rustworkx import digraph_node_link_json as digraph_node_link_json +from .rustworkx import graph_node_link_json as graph_node_link_json +from .rustworkx import digraph_bellman_ford_shortest_paths as digraph_bellman_ford_shortest_paths +from .rustworkx import graph_bellman_ford_shortest_paths as graph_bellman_ford_shortest_paths +from .rustworkx import ( + digraph_bellman_ford_shortest_path_lengths as digraph_bellman_ford_shortest_path_lengths, +) +from .rustworkx import ( + graph_bellman_ford_shortest_path_lengths as graph_bellman_ford_shortest_path_lengths, +) +from .rustworkx import digraph_dijkstra_shortest_paths as digraph_dijkstra_shortest_paths +from .rustworkx import graph_dijkstra_shortest_paths as graph_dijkstra_shortest_paths +from .rustworkx import ( + digraph_dijkstra_shortest_path_lengths as digraph_dijkstra_shortest_path_lengths, +) +from .rustworkx import graph_dijkstra_shortest_path_lengths as graph_dijkstra_shortest_path_lengths +from .rustworkx import ( + digraph_all_pairs_bellman_ford_path_lengths as digraph_all_pairs_bellman_ford_path_lengths, +) +from .rustworkx import ( + graph_all_pairs_bellman_ford_path_lengths as graph_all_pairs_bellman_ford_path_lengths, +) +from .rustworkx import ( + digraph_all_pairs_bellman_ford_shortest_paths as digraph_all_pairs_bellman_ford_shortest_paths, +) +from .rustworkx import ( + graph_all_pairs_bellman_ford_shortest_paths as graph_all_pairs_bellman_ford_shortest_paths, +) +from .rustworkx import ( + digraph_all_pairs_dijkstra_path_lengths as digraph_all_pairs_dijkstra_path_lengths, +) +from .rustworkx import ( + graph_all_pairs_dijkstra_path_lengths as graph_all_pairs_dijkstra_path_lengths, +) +from .rustworkx import ( + digraph_all_pairs_dijkstra_shortest_paths as digraph_all_pairs_dijkstra_shortest_paths, +) +from .rustworkx import ( + graph_all_pairs_dijkstra_shortest_paths as graph_all_pairs_dijkstra_shortest_paths, +) +from .rustworkx import digraph_astar_shortest_path as digraph_astar_shortest_path +from .rustworkx import graph_astar_shortest_path as graph_astar_shortest_path +from .rustworkx import digraph_k_shortest_path_lengths as digraph_k_shortest_path_lengths +from .rustworkx import graph_k_shortest_path_lengths as graph_k_shortest_path_lengths +from .rustworkx import digraph_has_path as digraph_has_path +from .rustworkx import graph_has_path as graph_has_path +from .rustworkx import ( + digraph_num_shortest_paths_unweighted as digraph_num_shortest_paths_unweighted, +) +from .rustworkx import graph_num_shortest_paths_unweighted as graph_num_shortest_paths_unweighted +from .rustworkx import ( + digraph_unweighted_average_shortest_path_length as digraph_unweighted_average_shortest_path_length, +) +from .rustworkx import ( + graph_unweighted_average_shortest_path_length as graph_unweighted_average_shortest_path_length, +) +from .rustworkx import digraph_distance_matrix as digraph_distance_matrix +from .rustworkx import graph_distance_matrix as graph_distance_matrix +from .rustworkx import digraph_floyd_warshall as digraph_floyd_warshall +from .rustworkx import graph_floyd_warshall as graph_floyd_warshall +from .rustworkx import digraph_floyd_warshall_numpy as digraph_floyd_warshall_numpy +from .rustworkx import graph_floyd_warshall_numpy as graph_floyd_warshall_numpy +from .rustworkx import ( + digraph_floyd_warshall_successor_and_distance as digraph_floyd_warshall_successor_and_distance, +) +from .rustworkx import ( + graph_floyd_warshall_successor_and_distance as graph_floyd_warshall_successor_and_distance, +) +from .rustworkx import find_negative_cycle as find_negative_cycle +from .rustworkx import negative_edge_cycle as negative_edge_cycle +from .rustworkx import digraph_all_shortest_paths as digraph_all_shortest_paths +from .rustworkx import graph_all_shortest_paths as graph_all_shortest_paths +from .rustworkx import digraph_tensor_product as digraph_tensor_product +from .rustworkx import graph_tensor_product as graph_tensor_product +from .rustworkx import graph_token_swapper as graph_token_swapper +from .rustworkx import digraph_transitivity as digraph_transitivity +from .rustworkx import graph_transitivity as graph_transitivity +from .rustworkx import digraph_bfs_search as digraph_bfs_search +from .rustworkx import graph_bfs_search as graph_bfs_search +from .rustworkx import digraph_dfs_search as digraph_dfs_search +from .rustworkx import graph_dfs_search as graph_dfs_search +from .rustworkx import digraph_dijkstra_search as digraph_dijkstra_search +from .rustworkx import graph_dijkstra_search as graph_dijkstra_search +from .rustworkx import digraph_dfs_edges as digraph_dfs_edges +from .rustworkx import graph_dfs_edges as graph_dfs_edges +from .rustworkx import ancestors as ancestors +from .rustworkx import bfs_predecessors as bfs_predecessors +from .rustworkx import bfs_successors as bfs_successors +from .rustworkx import descendants as descendants +from .rustworkx import minimum_spanning_edges as minimum_spanning_edges +from .rustworkx import minimum_spanning_tree as minimum_spanning_tree +from .rustworkx import steiner_tree as steiner_tree +from .rustworkx import metric_closure as metric_closure +from .rustworkx import digraph_union as digraph_union +from .rustworkx import graph_union as graph_union +from .rustworkx import NodeIndices as NodeIndices +from .rustworkx import PathLengthMapping as PathLengthMapping +from .rustworkx import PathMapping as PathMapping +from .rustworkx import AllPairsPathLengthMapping as AllPairsPathLengthMapping +from .rustworkx import AllPairsPathMapping as AllPairsPathMapping +from .rustworkx import BFSSuccessors as BFSSuccessors +from .rustworkx import BFSPredecessors as BFSPredecessors +from .rustworkx import EdgeIndexMap as EdgeIndexMap +from .rustworkx import EdgeIndices as EdgeIndices +from .rustworkx import Chains as Chains +from .rustworkx import EdgeList as EdgeList +from .rustworkx import NodeMap as NodeMap +from .rustworkx import NodesCountMapping as NodesCountMapping +from .rustworkx import Pos2DMapping as Pos2DMapping +from .rustworkx import WeightedEdgeList as WeightedEdgeList +from .rustworkx import CentralityMapping as CentralityMapping +from .rustworkx import EdgeCentralityMapping as EdgeCentralityMapping +from .rustworkx import BiconnectedComponents as BiconnectedComponents +from .rustworkx import ProductNodeMap as ProductNodeMap +from .rustworkx import MultiplePathMapping as MultiplePathMapping +from .rustworkx import AllPairsMultiplePathMapping as AllPairsMultiplePathMapping +from .rustworkx import PyGraph as PyGraph +from .rustworkx import PyDiGraph as PyDiGraph + _S = TypeVar("_S") _T = TypeVar("_T") _BFSVisitor = TypeVar("_BFSVisitor", bound=visit.BFSVisitor) From 3dc59eb08898d80a6a7ac0050ad4269916d24dfa Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sun, 21 Jan 2024 09:17:38 -0500 Subject: [PATCH 17/19] Add release note --- releasenotes/notes/fully-typed-0fbab79a7206d7e3.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 releasenotes/notes/fully-typed-0fbab79a7206d7e3.yaml diff --git a/releasenotes/notes/fully-typed-0fbab79a7206d7e3.yaml b/releasenotes/notes/fully-typed-0fbab79a7206d7e3.yaml new file mode 100644 index 0000000000..e7fe7d873f --- /dev/null +++ b/releasenotes/notes/fully-typed-0fbab79a7206d7e3.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + The ``rustworkx` package is now fully typed with + `mypy `__. Building off of the previous 0.13.0 + release which introduced partial type annotations to the library, rustworkx + now includes type annotations for the entire public API. From 2e0712c6043d61d7bb3cc59ee2e829629f85980b Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sun, 21 Jan 2024 09:21:40 -0500 Subject: [PATCH 18/19] Add type check ignore to mpl for 3.8 failures --- rustworkx/visualization/matplotlib.pyi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rustworkx/visualization/matplotlib.pyi b/rustworkx/visualization/matplotlib.pyi index 33a57538b4..c4ab0e71a8 100644 --- a/rustworkx/visualization/matplotlib.pyi +++ b/rustworkx/visualization/matplotlib.pyi @@ -13,9 +13,9 @@ import typing_extensions from rustworkx.rustworkx import PyGraph, PyDiGraph if typing.TYPE_CHECKING: - from matplotlib.axes import Axes - from matplotlib.figure import Figure - from matplotlib.colors import Colormap + from matplotlib.axes import Axes # type: ignore + from matplotlib.figure import Figure # type: ignore + from matplotlib.colors import Colormap # type: ignore _S = typing.TypeVar("_S") _T = typing.TypeVar("_T") From 44cdb1803e7bdd9301bba3e20dcdd3023126264c Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sun, 21 Jan 2024 09:43:55 -0500 Subject: [PATCH 19/19] Fix release note typo --- releasenotes/notes/fully-typed-0fbab79a7206d7e3.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releasenotes/notes/fully-typed-0fbab79a7206d7e3.yaml b/releasenotes/notes/fully-typed-0fbab79a7206d7e3.yaml index e7fe7d873f..e3c2417564 100644 --- a/releasenotes/notes/fully-typed-0fbab79a7206d7e3.yaml +++ b/releasenotes/notes/fully-typed-0fbab79a7206d7e3.yaml @@ -1,7 +1,7 @@ --- features: - | - The ``rustworkx` package is now fully typed with + The ``rustworkx`` Python package is now fully typed with `mypy `__. Building off of the previous 0.13.0 release which introduced partial type annotations to the library, rustworkx now includes type annotations for the entire public API.