networkx: type is_* and has_* functions (#14054)

This commit is contained in:
Avasam
2025-05-14 08:10:29 -04:00
committed by GitHub
parent b7d5b1d7f1
commit 5a81bf54e6
31 changed files with 96 additions and 57 deletions
@@ -6,4 +6,4 @@ __all__ = ["is_at_free", "find_asteroidal_triple"]
@_dispatchable
def find_asteroidal_triple(G: Graph[_Node]): ...
@_dispatchable
def is_at_free(G: Graph[_Node]): ...
def is_at_free(G: Graph[_Node]) -> bool: ...
@@ -9,9 +9,9 @@ __all__ = ["is_bipartite", "is_bipartite_node_set", "color", "sets", "density",
@_dispatchable
def color(G: Graph[_Node]): ...
@_dispatchable
def is_bipartite(G: Graph[_Node]): ...
def is_bipartite(G: Graph[_Node]) -> bool: ...
@_dispatchable
def is_bipartite_node_set(G: Graph[_Node], nodes): ...
def is_bipartite_node_set(G: Graph[_Node], nodes: Iterable[Incomplete]) -> bool: ...
@_dispatchable
def sets(G: Graph[_Node], top_nodes: Iterable[Incomplete] | None = None): ...
@_dispatchable
@@ -1,7 +1,15 @@
from _typeshed import Incomplete, SupportsGetItem
from collections.abc import Mapping
from typing import SupportsIndex
from networkx.classes.graph import Graph, _Node
from networkx.utils.backends import _dispatchable
__all__ = ["equitable_color"]
@_dispatchable
def is_coloring(G: Graph[_Node], coloring: SupportsGetItem[Incomplete, Incomplete]) -> bool: ...
@_dispatchable
def is_equitable(G: Graph[_Node], coloring: Mapping[Incomplete, Incomplete], num_colors: SupportsIndex | None = None) -> bool: ...
@_dispatchable
def equitable_color(G: Graph[_Node], num_colors): ...
@@ -1,7 +1,9 @@
from collections.abc import Container, Iterable
from networkx.classes.graph import Graph, _Node
from networkx.utils.backends import _dispatchable
__all__ = ["is_partition"]
@_dispatchable
def is_partition(G: Graph[_Node], communities): ...
def is_partition(G: Graph[_Node], communities: Iterable[Container[_Node]]) -> bool: ...
@@ -1,6 +1,9 @@
from _typeshed import Incomplete
from collections.abc import Generator
from networkx.classes.digraph import DiGraph
from networkx.classes.graph import _Node
from networkx.classes.multidigraph import MultiDiGraph
from networkx.utils.backends import _dispatchable
__all__ = ["number_attracting_components", "attracting_components", "is_attracting_component"]
@@ -10,4 +13,4 @@ def attracting_components(G) -> Generator[Incomplete, None, None]: ...
@_dispatchable
def number_attracting_components(G): ...
@_dispatchable
def is_attracting_component(G): ...
def is_attracting_component(G: DiGraph[_Node] | MultiDiGraph[_Node]) -> bool: ...
@@ -7,7 +7,7 @@ from networkx.utils.backends import _dispatchable
__all__ = ["biconnected_components", "biconnected_component_edges", "is_biconnected", "articulation_points"]
@_dispatchable
def is_biconnected(G: Graph[_Node]): ...
def is_biconnected(G: Graph[_Node]) -> bool: ...
@_dispatchable
def biconnected_component_edges(G: Graph[_Node]) -> Generator[Incomplete, Incomplete, None]: ...
@_dispatchable
@@ -11,6 +11,6 @@ def connected_components(G: Graph[_Node]) -> Generator[Incomplete, None, None]:
@_dispatchable
def number_connected_components(G: Graph[_Node]): ...
@_dispatchable
def is_connected(G: Graph[_Node]): ...
def is_connected(G: Graph[_Node]) -> bool: ...
@_dispatchable
def node_connected_component(G: Graph[_Node], n: _Node): ...
@@ -4,4 +4,4 @@ from networkx.utils.backends import _dispatchable
__all__ = ["is_semiconnected"]
@_dispatchable
def is_semiconnected(G: Graph[_Node]): ...
def is_semiconnected(G: Graph[_Node]) -> bool: ...
@@ -7,9 +7,9 @@ from networkx.utils.backends import _dispatchable
__all__ = ["k_edge_augmentation", "is_k_edge_connected", "is_locally_k_edge_connected"]
@_dispatchable
def is_k_edge_connected(G: Graph[_Node], k: int): ...
def is_k_edge_connected(G: Graph[_Node], k: int) -> bool: ...
@_dispatchable
def is_locally_k_edge_connected(G: Graph[_Node], s: _Node, t: _Node, k: int): ...
def is_locally_k_edge_connected(G: Graph[_Node], s: _Node, t: _Node, k: int) -> bool: ...
@_dispatchable
def k_edge_augmentation(
G: Graph[_Node],
@@ -1,5 +1,5 @@
from _typeshed import Incomplete
from collections.abc import Callable
from collections.abc import Callable, Iterable
from networkx.classes.graph import Graph, _Node
from networkx.utils.backends import _dispatchable
@@ -9,4 +9,4 @@ __all__ = ["min_edge_cover", "is_edge_cover"]
@_dispatchable
def min_edge_cover(G: Graph[_Node], matching_algorithm: Callable[..., Incomplete] | None = None): ...
@_dispatchable
def is_edge_cover(G: Graph[_Node], cover: set[Incomplete]): ...
def is_edge_cover(G: Graph[_Node], cover: Iterable[Iterable[Incomplete]]) -> bool: ...
@@ -7,7 +7,7 @@ from networkx.utils.backends import _dispatchable
__all__ = ["is_d_separator", "is_minimal_d_separator", "find_minimal_d_separator", "d_separated", "minimal_d_separator"]
@_dispatchable
def is_d_separator(G, x, y, z) -> bool: ...
def is_d_separator(G: DiGraph[_Node], x: _Node | set[_Node], y: _Node | set[_Node], z: _Node | set[_Node]) -> bool: ...
@_dispatchable
def find_minimal_d_separator(G, x, y, *, included=None, restricted=None) -> set[Incomplete] | None: ...
@_dispatchable
@@ -15,4 +15,12 @@ def d_separated(G, x, y, z): ...
@_dispatchable
def minimal_d_separator(G, u, v): ...
@_dispatchable
def is_minimal_d_separator(G: DiGraph[_Node], x, y, z, *, included=None, restricted=None): ...
def is_minimal_d_separator(
G: DiGraph[_Node],
x: _Node | set[_Node],
y: _Node | set[_Node],
z: _Node | set[_Node],
*,
included: _Node | set[_Node] | None = None,
restricted: _Node | set[_Node] | None = None,
) -> bool: ...
@@ -4,10 +4,10 @@ from networkx.utils.backends import _dispatchable
__all__ = ["is_distance_regular", "is_strongly_regular", "intersection_array", "global_parameters"]
@_dispatchable
def is_distance_regular(G: Graph[_Node]): ...
def is_distance_regular(G: Graph[_Node]) -> bool: ...
@_dispatchable
def global_parameters(b, c): ...
@_dispatchable
def intersection_array(G: Graph[_Node]): ...
@_dispatchable
def is_strongly_regular(G: Graph[_Node]): ...
def is_strongly_regular(G: Graph[_Node]) -> bool: ...
@@ -1,4 +1,3 @@
from _typeshed import Incomplete
from collections.abc import Iterable
from networkx.classes.graph import Graph, _Node
@@ -9,4 +8,4 @@ __all__ = ["dominating_set", "is_dominating_set"]
@_dispatchable
def dominating_set(G: Graph[_Node], start_with: _Node | None = None): ...
@_dispatchable
def is_dominating_set(G: Graph[_Node], nbunch: Iterable[Incomplete]): ...
def is_dominating_set(G: Graph[_Node], nbunch: Iterable[_Node]) -> bool: ...
+3 -3
View File
@@ -7,15 +7,15 @@ from networkx.utils.backends import _dispatchable
__all__ = ["is_eulerian", "eulerian_circuit", "eulerize", "is_semieulerian", "has_eulerian_path", "eulerian_path"]
@_dispatchable
def is_eulerian(G: Graph[_Node]): ...
def is_eulerian(G: Graph[_Node]) -> bool: ...
@_dispatchable
def is_semieulerian(G): ...
def is_semieulerian(G: Graph[_Node]) -> bool: ...
@_dispatchable
def eulerian_circuit(
G: Graph[_Node], source: _Node | None = None, keys: bool = False
) -> Generator[Incomplete, Incomplete, None]: ...
@_dispatchable
def has_eulerian_path(G: Graph[_Node], source: _Node | None = None): ...
def has_eulerian_path(G: Graph[_Node], source: _Node | None = None) -> bool: ...
@_dispatchable
def eulerian_path(G: Graph[_Node], source=None, keys: bool = False) -> Generator[Incomplete, Incomplete, None]: ...
@_dispatchable
@@ -18,7 +18,7 @@ class Level:
class GlobalRelabelThreshold:
def __init__(self, n, m, freq) -> None: ...
def add_work(self, work) -> None: ...
def is_reached(self): ...
def is_reached(self) -> bool: ...
def clear_work(self) -> None: ...
@_dispatchable
@@ -1,5 +1,6 @@
from _typeshed import Incomplete
from collections.abc import Iterable
from typing import Literal
from networkx.utils.backends import _dispatchable
@@ -13,14 +14,14 @@ __all__ = [
]
@_dispatchable
def is_graphical(sequence: Iterable[Incomplete], method="eg"): ...
def is_graphical(sequence: Iterable[Incomplete], method: Literal["eg", "hh"] = "eg") -> bool: ...
@_dispatchable
def is_valid_degree_sequence_havel_hakimi(deg_sequence: Iterable[Incomplete]): ...
def is_valid_degree_sequence_havel_hakimi(deg_sequence: Iterable[Incomplete]) -> bool: ...
@_dispatchable
def is_valid_degree_sequence_erdos_gallai(deg_sequence: Iterable[Incomplete]): ...
def is_valid_degree_sequence_erdos_gallai(deg_sequence: Iterable[Incomplete]) -> bool: ...
@_dispatchable
def is_multigraphical(sequence: Iterable[Incomplete]): ...
def is_multigraphical(sequence: Iterable[Incomplete]) -> bool: ...
@_dispatchable
def is_pseudographical(sequence: Iterable[Incomplete]): ...
def is_pseudographical(sequence: Iterable[Incomplete]) -> bool: ...
@_dispatchable
def is_digraphical(in_sequence: Iterable[Incomplete], out_sequence: Iterable[Incomplete]): ...
def is_digraphical(in_sequence: Iterable[Incomplete], out_sequence: Iterable[Incomplete]) -> bool: ...
@@ -6,4 +6,4 @@ __all__ = ["kl_connected_subgraph", "is_kl_connected"]
@_dispatchable
def kl_connected_subgraph(G: Graph[_Node], k: int, l: int, low_memory: bool = False, same_as_graph: bool = False): ...
@_dispatchable
def is_kl_connected(G: Graph[_Node], k: int, l: int, low_memory: bool = False): ...
def is_kl_connected(G: Graph[_Node], k: int, l: int, low_memory: bool = False) -> bool: ...
@@ -4,7 +4,7 @@ from networkx.utils.backends import _dispatchable
__all__ = ["is_isolate", "isolates", "number_of_isolates"]
@_dispatchable
def is_isolate(G: Graph[_Node], n: _Node): ...
def is_isolate(G: Graph[_Node], n: _Node) -> bool: ...
@_dispatchable
def isolates(G: Graph[_Node]): ...
@_dispatchable
@@ -13,7 +13,7 @@ class ISMAGS:
def find_isomorphisms(self, symmetry: bool = True) -> Generator[Incomplete, Incomplete, Incomplete]: ...
def largest_common_subgraph(self, symmetry: bool = True) -> Generator[Incomplete, Incomplete, None]: ...
def analyze_symmetry(self, graph, node_partitions, edge_colors): ...
def is_isomorphic(self, symmetry: bool = False): ...
def is_isomorphic(self, symmetry: bool = False) -> bool: ...
def subgraph_is_isomorphic(self, symmetry: bool = False): ...
def isomorphisms_iter(self, symmetry: bool = True) -> Generator[Incomplete, Incomplete, None]: ...
def subgraph_isomorphisms_iter(self, symmetry: bool = True): ...
@@ -23,7 +23,7 @@ class GraphMatcher:
mapping: Incomplete
def initialize(self) -> None: ...
def is_isomorphic(self): ...
def is_isomorphic(self) -> bool: ...
def isomorphisms_iter(self) -> Generator[Incomplete, Incomplete, None]: ...
def match(self) -> Generator[Incomplete, Incomplete, None]: ...
def semantic_feasibility(self, G1_node, G2_node): ...
@@ -1,3 +1,6 @@
from _typeshed import Incomplete
from collections.abc import Iterable, Mapping
from networkx.classes.graph import Graph, _Node
from networkx.utils.backends import _dispatchable
@@ -12,12 +15,13 @@ __all__ = [
@_dispatchable
def maximal_matching(G: Graph[_Node]): ...
def matching_dict_to_set(matching: Mapping[Incomplete, Incomplete]) -> set[Incomplete]: ...
@_dispatchable
def is_matching(G: Graph[_Node], matching): ...
def is_matching(G: Graph[_Node], matching: dict[Incomplete, Incomplete] | Iterable[Iterable[Incomplete]]) -> bool: ...
@_dispatchable
def is_maximal_matching(G: Graph[_Node], matching): ...
def is_maximal_matching(G: Graph[_Node], matching: dict[Incomplete, Incomplete] | Iterable[Iterable[Incomplete]]) -> bool: ...
@_dispatchable
def is_perfect_matching(G: Graph[_Node], matching): ...
def is_perfect_matching(G: Graph[_Node], matching: dict[Incomplete, Incomplete] | Iterable[Iterable[Incomplete]]) -> bool: ...
@_dispatchable
def min_weight_matching(G: Graph[_Node], weight: str | None = "weight"): ...
@_dispatchable
@@ -4,8 +4,8 @@ from networkx.utils.backends import _dispatchable
__all__ = ["is_regular", "is_k_regular", "k_factor"]
@_dispatchable
def is_regular(G: Graph[_Node]): ...
def is_regular(G: Graph[_Node]) -> bool: ...
@_dispatchable
def is_k_regular(G: Graph[_Node], k): ...
def is_k_regular(G: Graph[_Node], k) -> bool: ...
@_dispatchable
def k_factor(G: Graph[_Node], k, matching_weight: str | None = "weight"): ...
@@ -1,5 +1,5 @@
from _typeshed import Incomplete, SupportsGetItem
from collections.abc import Callable, Generator, Iterable
from collections.abc import Callable, Collection, Generator
from typing import Any
from networkx.classes.graph import Graph, _Node
@@ -8,7 +8,7 @@ from networkx.utils.backends import _dispatchable
__all__ = ["all_simple_paths", "is_simple_path", "shortest_simple_paths", "all_simple_edge_paths"]
@_dispatchable
def is_simple_path(G: Graph[_Node], nodes: Iterable[Incomplete]): ...
def is_simple_path(G: Graph[_Node], nodes: Collection[Incomplete]) -> bool: ...
@_dispatchable
def all_simple_paths(G: Graph[_Node], source: _Node, target, cutoff: int | None = None) -> Generator[list[_Node], None, None]: ...
@_dispatchable
@@ -1,9 +1,12 @@
from collections.abc import Sequence
from networkx.classes.graph import Graph, _Node
from networkx.utils.backends import _dispatchable
__all__ = ["is_threshold_graph", "find_threshold_graph"]
@_dispatchable
def is_threshold_graph(G: Graph[_Node]): ...
def is_threshold_graph(G: Graph[_Node]) -> bool: ...
def is_threshold_sequence(degree_sequence: Sequence[list[int]]) -> bool: ...
@_dispatchable
def find_threshold_graph(G: Graph[_Node], create_using: Graph[_Node] | None = None): ...
@@ -5,7 +5,7 @@ from numpy.random import RandomState
__all__ = ["hamiltonian_path", "is_reachable", "is_strongly_connected", "is_tournament", "random_tournament", "score_sequence"]
@_dispatchable
def is_tournament(G: Graph[_Node]): ...
def is_tournament(G: Graph[_Node]) -> bool: ...
@_dispatchable
def hamiltonian_path(G: Graph[_Node]): ...
@_dispatchable
@@ -13,6 +13,6 @@ def random_tournament(n: int, seed: int | RandomState | None = None): ...
@_dispatchable
def score_sequence(G: Graph[_Node]): ...
@_dispatchable
def is_reachable(G: Graph[_Node], s: _Node, t: _Node): ...
def is_reachable(G: Graph[_Node], s: _Node, t: _Node) -> bool: ...
@_dispatchable
def is_strongly_connected(G: Graph[_Node]): ...
def is_strongly_connected(G: Graph[_Node]) -> bool: ...
@@ -5,10 +5,10 @@ from networkx.utils.backends import _dispatchable
__all__ = ["is_arborescence", "is_branching", "is_forest", "is_tree"]
@_dispatchable
def is_arborescence(G: Graph[_Node]): ...
def is_arborescence(G: Graph[_Node]) -> bool: ...
@_dispatchable
def is_branching(G: DiGraph[_Node]): ...
def is_branching(G: DiGraph[_Node]) -> bool: ...
@_dispatchable
def is_forest(G: Graph[_Node]): ...
def is_forest(G: Graph[_Node]) -> bool: ...
@_dispatchable
def is_tree(G: Graph[_Node]): ...
def is_tree(G: Graph[_Node]) -> bool: ...
@@ -11,7 +11,7 @@ __all__ = ["triadic_census", "is_triad", "all_triplets", "all_triads", "triads_b
@_dispatchable
def triadic_census(G: DiGraph[_Node], nodelist: Collection[_Node] | None = None): ...
@_dispatchable
def is_triad(G: Graph[_Node]): ...
def is_triad(G: Graph[_Node]) -> bool: ...
@_dispatchable
def all_triplets(G: DiGraph[_Node]): ...
@_dispatchable
+3 -3
View File
@@ -67,7 +67,7 @@ def is_directed(G: DiGraph[Hashable]) -> Literal[True]: ... # type: ignore[misc
@overload
def is_directed(G: Graph[Hashable]) -> Literal[False]: ...
def freeze(G): ...
def is_frozen(G): ...
def is_frozen(G: Graph[Incomplete]) -> bool: ...
def add_star(G_to_add_to, nodes_for_star, **attr) -> None: ...
def add_path(G_to_add_to, nodes_for_path, **attr) -> None: ...
def add_cycle(G_to_add_to, nodes_for_cycle, **attr) -> None: ...
@@ -104,7 +104,7 @@ def non_edges(graph: Graph[_Node]) -> Generator[tuple[_Node, _Node], None, None]
def common_neighbors(G: Graph[_Node], u: _Node, v: _Node) -> Generator[_Node, None, None]: ...
def is_weighted(G: Graph[_Node], edge: tuple[_Node, _Node] | None = None, weight: str = "weight") -> bool: ...
@_dispatchable
def is_negatively_weighted(G: Graph[_Node], edge: tuple[_Node, _Node] | None = None, weight: str = "weight"): ...
def is_negatively_weighted(G: Graph[_Node], edge: tuple[_Node, _Node] | None = None, weight: str = "weight") -> bool: ...
def is_empty(G: Graph[Hashable]) -> bool: ...
def nodes_with_selfloops(G: Graph[_Node]) -> Generator[_Node, None, None]: ...
@overload
@@ -136,5 +136,5 @@ def selfloop_edges(
G: Graph[_Node], data: str, keys: Literal[True], default: _U | None = None
) -> Generator[tuple[_Node, _Node, int, _U], None, None]: ...
def number_of_selfloops(G: Graph[Hashable]) -> int: ...
def is_path(G, path) -> bool: ...
def is_path(G: Graph[_Node], path: Iterable[Incomplete]) -> bool: ...
def path_weight(G, path, weight) -> int: ...
@@ -20,7 +20,7 @@ class MultiGraph(Graph[_Node]):
def new_edge_key(self, u: _Node, v: _Node) -> int: ...
def add_edge(self, u_for_edge, v_for_edge, key=None, **attr): ... # type: ignore[override] # Has an additional `key` keyword argument
def remove_edge(self, u, v, key=None): ...
def has_edge(self, u, v, key=None): ...
def has_edge(self, u: _Node, v: _Node, key=None) -> bool: ...
def get_edge_data( # type: ignore[override] # Has an additional `key` keyword argument
self, u, v, key=None, default=None
): ...
@@ -1,3 +1,4 @@
from networkx.classes.graph import Graph, _Node
from networkx.utils.backends import _dispatchable
__all__ = [
@@ -18,6 +19,6 @@ def paley_graph(p, create_using=None): ...
@_dispatchable
def maybe_regular_expander(n, d, *, create_using=None, max_tries=100, seed=None): ...
@_dispatchable
def is_regular_expander(G, *, epsilon=0) -> bool: ...
def is_regular_expander(G: Graph[_Node], *, epsilon: float = 0) -> bool: ...
@_dispatchable
def random_regular_expander_graph(n, d, *, epsilon=0, create_using=None, max_tries=100, seed=None): ...
@@ -1,12 +1,22 @@
from collections.abc import Mapping, Sequence
from networkx.utils.backends import _dispatchable
from numpy.random import RandomState
__all__ = ["is_valid_joint_degree", "is_valid_directed_joint_degree", "joint_degree_graph", "directed_joint_degree_graph"]
@_dispatchable
def is_valid_joint_degree(joint_degrees): ...
def is_valid_joint_degree(joint_degrees: Mapping[int, Mapping[int, int]]) -> bool: ...
@_dispatchable
def joint_degree_graph(joint_degrees, seed=None): ...
def joint_degree_graph(joint_degrees: Mapping[int, Mapping[int, int]], seed: int | RandomState | None = None): ...
@_dispatchable
def is_valid_directed_joint_degree(in_degrees, out_degrees, nkk): ...
def is_valid_directed_joint_degree(
in_degrees: Sequence[int], out_degrees: Sequence[int], nkk: Mapping[int, Mapping[int, int]]
) -> bool: ...
@_dispatchable
def directed_joint_degree_graph(in_degrees, out_degrees, nkk, seed=None): ...
def directed_joint_degree_graph(
in_degrees: Sequence[int],
out_degrees: Sequence[int],
nkk: Mapping[int, Mapping[int, int]],
seed: int | RandomState | None = None,
): ...