From 3c09cc9e23df45675399bc0c7443f599a6aae460 Mon Sep 17 00:00:00 2001 From: Ivan Carvalho Date: Tue, 15 Aug 2023 23:37:25 -0400 Subject: [PATCH 1/4] Add missing methods in PyGraph and PyDiGraph stubs --- rustworkx/digraph.pyi | 39 +++++++++++++++++++++++++++++++++++++-- rustworkx/graph.pyi | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/rustworkx/digraph.pyi b/rustworkx/digraph.pyi index 13735b5fc..0c359bba4 100644 --- a/rustworkx/digraph.pyi +++ b/rustworkx/digraph.pyi @@ -9,11 +9,26 @@ # This file contains only type annotations for PyO3 functions and classes # For implementation details, see __init__.py and src/digraph.rs +from __future__ import annotations + import numpy as np from .iterators import * -from .graph import PyGraph -from typing import Any, Callable, Dict, Generic, TypeVar, Optional, List, Tuple, Sequence +from typing import ( + Any, + Callable, + Dict, + Generic, + TypeVar, + Optional, + List, + Tuple, + Sequence, + TYPE_CHECKING, +) + +if TYPE_CHECKING: + from .graph import PyGraph __all__ = ["PyDiGraph"] @@ -21,6 +36,7 @@ S = TypeVar("S") T = TypeVar("T") class PyDiGraph(Generic[S, T]): + attrs: Any check_cycle: bool = ... multigraph: bool = ... def __init__( @@ -52,11 +68,20 @@ class PyDiGraph(Generic[S, T]): node_map_func: Optional[Callable[[S], int]] = ..., edge_map_func: Optional[Callable[[T], int]] = ..., ) -> Dict[int, int]: ... + def contract_nodes( + self, + nodes: List[int], + obj: S, + /, + check_cycle: Optional[bool] = ..., + weight_combo_fn: Optional[Callable[[T, T], T]] = ..., + ) -> 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: List[Tuple[int, int]], /) -> PyDiGraph[S, T]: ... def extend_from_edge_list( self: PyDiGraph[Optional[S], Optional[T]], edge_list: Sequence[Tuple[int, int]], / ) -> None: ... @@ -65,6 +90,8 @@ class PyDiGraph(Generic[S, 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, @@ -74,6 +101,7 @@ class PyDiGraph(Generic[S, T]): 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( @@ -86,17 +114,24 @@ class PyDiGraph(Generic[S, T]): 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: Optional[Callable[[T], T]] = ...) -> 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: ... diff --git a/rustworkx/graph.pyi b/rustworkx/graph.pyi index 44eb37260..3a3e7bacb 100644 --- a/rustworkx/graph.pyi +++ b/rustworkx/graph.pyi @@ -9,6 +9,8 @@ # This file contains only type annotations for PyO3 functions and classes # For implementation details, see __init__.py and src/graph.rs +from __future__ import annotations + import numpy as np from .iterators import * @@ -22,14 +24,19 @@ from typing import ( List, Tuple, 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: ... @@ -52,12 +59,20 @@ class PyGraph(Generic[S, T]): node_map_func: Optional[Callable[[S], int]] = ..., edge_map_func: Optional[Callable[[T], int]] = ..., ) -> Dict[int, int]: ... + def contract_nodes( + self, + nodes: List[int], + obj: S, + /, + weight_combo_fn: Optional[Callable[[T, T], T]] = ..., + ) -> 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: List[Tuple[int, int]], /) -> PyGraph[S, T]: ... def extend_from_edge_list( self: PyGraph[Optional[S], Optional[T]], edge_list: Sequence[Tuple[int, int]], / ) -> None: ... @@ -66,6 +81,13 @@ class PyGraph(Generic[S, 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], + /, + ) -> Optional[int]: ... @staticmethod def from_adjacency_matrix( matrix: np.ndarray, /, null_value: float = ... @@ -76,13 +98,21 @@ class PyGraph(Generic[S, T]): ) -> 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, @@ -114,6 +144,7 @@ class PyGraph(Generic[S, T]): graph_attr: Optional[Dict[str, str]] = ..., filename: Optional[str] = ..., ) -> Optional[str]: ... + def to_directed(self) -> PyDiGraph[S, T]: ... def update_edge( self, source: int, @@ -136,3 +167,10 @@ class PyGraph(Generic[S, T]): def __len__(self) -> int: ... def __setitem__(self, idx: int, value: S, /) -> None: ... def __setstate__(self, state, /) -> None: ... + +""" +rustworkx.rustworkx.PyDiGraph.incident_edge_index_map is not present in stub +rustworkx.rustworkx.PyDiGraph.incident_edges is not present in stub +rustworkx.rustworkx.PyGraph.incident_edge_index_map is not present in stub +rustworkx.rustworkx.PyGraph.incident_edges is not present in stub +""" From 510bedf39c55a882f39c6a2a3b5d20dfac552ad1 Mon Sep 17 00:00:00 2001 From: Ivan Carvalho Date: Tue, 15 Aug 2023 23:40:33 -0400 Subject: [PATCH 2/4] Remove TODOs --- rustworkx/graph.pyi | 7 ------- 1 file changed, 7 deletions(-) diff --git a/rustworkx/graph.pyi b/rustworkx/graph.pyi index 3a3e7bacb..80b8ebc6c 100644 --- a/rustworkx/graph.pyi +++ b/rustworkx/graph.pyi @@ -167,10 +167,3 @@ class PyGraph(Generic[S, T]): def __len__(self) -> int: ... def __setitem__(self, idx: int, value: S, /) -> None: ... def __setstate__(self, state, /) -> None: ... - -""" -rustworkx.rustworkx.PyDiGraph.incident_edge_index_map is not present in stub -rustworkx.rustworkx.PyDiGraph.incident_edges is not present in stub -rustworkx.rustworkx.PyGraph.incident_edge_index_map is not present in stub -rustworkx.rustworkx.PyGraph.incident_edges is not present in stub -""" From 2b872fe12831426bcbdadbb053e75a6a84d19b09 Mon Sep 17 00:00:00 2001 From: Ivan Carvalho Date: Wed, 18 Oct 2023 21:58:54 -0400 Subject: [PATCH 3/4] Add new methods --- rustworkx/digraph.pyi | 2 ++ rustworkx/graph.pyi | 2 ++ 2 files changed, 4 insertions(+) diff --git a/rustworkx/digraph.pyi b/rustworkx/digraph.pyi index 065c0eeb3..318661e5c 100644 --- a/rustworkx/digraph.pyi +++ b/rustworkx/digraph.pyi @@ -47,6 +47,8 @@ class PyDiGraph(Generic[S, T]): 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], diff --git a/rustworkx/graph.pyi b/rustworkx/graph.pyi index 57c80b290..04c32440c 100644 --- a/rustworkx/graph.pyi +++ b/rustworkx/graph.pyi @@ -45,6 +45,8 @@ class PyGraph(Generic[S, T]): 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], From 4c62d13104d214adf9c048ff290a8819fc167564 Mon Sep 17 00:00:00 2001 From: Ivan Carvalho Date: Sat, 13 Jan 2024 09:21:35 -0500 Subject: [PATCH 4/4] Add comments from review --- rustworkx/digraph.pyi | 4 ++-- rustworkx/graph.pyi | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rustworkx/digraph.pyi b/rustworkx/digraph.pyi index 318661e5c..ae470846f 100644 --- a/rustworkx/digraph.pyi +++ b/rustworkx/digraph.pyi @@ -59,7 +59,7 @@ class PyDiGraph(Generic[S, T]): ) -> dict[int, int]: ... def contract_nodes( self, - nodes: list[int], + nodes: Sequence[int], obj: S, /, check_cycle: bool | None = ..., @@ -70,7 +70,7 @@ class PyDiGraph(Generic[S, T]): def edge_indices(self) -> EdgeIndices: ... def edge_list(self) -> EdgeList: ... def edges(self) -> list[T]: ... - def edge_subgraph(self, edge_list: list[tuple[int, int]], /) -> PyDiGraph[S, 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: ... diff --git a/rustworkx/graph.pyi b/rustworkx/graph.pyi index 04c32440c..d710f6a1d 100644 --- a/rustworkx/graph.pyi +++ b/rustworkx/graph.pyi @@ -57,7 +57,7 @@ class PyGraph(Generic[S, T]): ) -> dict[int, int]: ... def contract_nodes( self, - nodes: list[int], + nodes: Sequence[int], obj: S, /, weight_combo_fn: Callable[[T, T], T] | None = ..., @@ -68,7 +68,7 @@ class PyGraph(Generic[S, T]): def edge_indices(self) -> EdgeIndices: ... def edge_list(self) -> EdgeList: ... def edges(self) -> list[T]: ... - def edge_subgraph(self, edge_list: list[tuple[int, int]], /) -> PyGraph[S, 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: ...