diff --git a/stubs/networkx/@tests/stubtest_allowlist.txt b/stubs/networkx/@tests/stubtest_allowlist.txt index 263c21909..99e031efd 100644 --- a/stubs/networkx/@tests/stubtest_allowlist.txt +++ b/stubs/networkx/@tests/stubtest_allowlist.txt @@ -21,3 +21,10 @@ networkx\.(generators\.)?(random_graphs\.)?erdos_renyi_graph # failing to account for explicitly passing in the default value." # Which is true, but would require some way of concatenating `backend` to ParamSpec.kwargs networkx\.(utils\.backends\.)?_dispatch\.__call__ + +# TODO: stubtest does not like @cached_property https://github.com/python/mypy/issues/17625 +# "is inconsistent, cannot reconcile @property on stub with runtime object" +networkx(\.classes(\.graph)?)?\.Graph\.(adj|degree|edges|nodes) +networkx(\.classes(\.multigraph)?)?\.MultiGraph\.(adj|degree|edges) +networkx(\.classes(\.digraph)?)?\.DiGraph\.(adj|degree|edges|in_degree|in_edges|out_degree|out_edges|pred|succ) +networkx(\.classes(\.multidigraph)?)?\.MultiDiGraph\.(adj|degree|edges|in_degree|in_edges|out_degree|out_edges|pred|succ) diff --git a/stubs/networkx/METADATA.toml b/stubs/networkx/METADATA.toml index d808108cf..d8e565fd0 100644 --- a/stubs/networkx/METADATA.toml +++ b/stubs/networkx/METADATA.toml @@ -1,8 +1,7 @@ version = "3.2.1" upstream_repository = "https://github.com/networkx/networkx" # requires a version of numpy with a `py.typed` file -# TODO: Lots of stubtest errors when using numpy 2 -requires = ["numpy>=1.20,<2"] +requires = ["numpy>=1.20"] partial_stub = true [tool.stubtest] diff --git a/stubs/networkx/networkx/classes/digraph.pyi b/stubs/networkx/networkx/classes/digraph.pyi index 1636f6307..2c3476e70 100644 --- a/stubs/networkx/networkx/classes/digraph.pyi +++ b/stubs/networkx/networkx/classes/digraph.pyi @@ -1,28 +1,28 @@ from _typeshed import Incomplete from collections.abc import Iterator +from functools import cached_property from networkx.classes.coreviews import AdjacencyView from networkx.classes.graph import Graph, _Node -from networkx.classes.reportviews import ( - InDegreeView, - InEdgeView, - InMultiDegreeView, - OutDegreeView, - OutEdgeView, - OutMultiDegreeView, -) +from networkx.classes.reportviews import DiDegreeView, OutEdgeView class DiGraph(Graph[_Node]): - succ: AdjacencyView[_Node, _Node, dict[str, Incomplete]] - pred: AdjacencyView[_Node, _Node, dict[str, Incomplete]] + @cached_property + def succ(self) -> AdjacencyView[_Node, _Node, dict[str, Incomplete]]: ... + @cached_property + def pred(self) -> AdjacencyView[_Node, _Node, dict[str, Incomplete]]: ... def has_successor(self, u: _Node, v: _Node) -> bool: ... def has_predecessor(self, u: _Node, v: _Node) -> bool: ... def successors(self, n: _Node) -> Iterator[_Node]: ... def predecessors(self, n: _Node) -> Iterator[_Node]: ... - in_edges: InEdgeView[_Node] - in_degree: InDegreeView[_Node] | InMultiDegreeView[_Node] # ugly hack to make MultiDiGraph work - out_edges: OutEdgeView[_Node] - out_degree: OutDegreeView[_Node] | OutMultiDegreeView[_Node] # ugly hack to make MultiDiGraph work + @cached_property + def out_edges(self) -> OutEdgeView[_Node]: ... + @cached_property + def in_edges(self) -> OutEdgeView[_Node]: ... + @cached_property + def in_degree(self) -> DiDegreeView[_Node]: ... + @cached_property + def out_degree(self) -> DiDegreeView[_Node]: ... def to_undirected(self, reciprocal: bool = False, as_view: bool = False): ... # type: ignore[override] # Has an additional `reciprocal` keyword argument def reverse(self, copy: bool = True) -> DiGraph[_Node]: ... def copy(self, as_view: bool = False) -> DiGraph[_Node]: ... diff --git a/stubs/networkx/networkx/classes/graph.pyi b/stubs/networkx/networkx/classes/graph.pyi index 9edca89f4..c0743d193 100644 --- a/stubs/networkx/networkx/classes/graph.pyi +++ b/stubs/networkx/networkx/classes/graph.pyi @@ -1,5 +1,6 @@ from _typeshed import Incomplete from collections.abc import Callable, Collection, Hashable, Iterable, Iterator, Mapping, MutableMapping +from functools import cached_property from typing import Any, ClassVar, TypeVar, overload from typing_extensions import Self, TypeAlias @@ -36,10 +37,12 @@ class Graph(Collection[_Node]): def to_directed_class(self) -> type[DiGraph[_Node]]: ... def to_undirected_class(self) -> type[Graph[_Node]]: ... def __init__(self, incoming_graph_data: _Data[_Node] | None = None, **attr) -> None: ... - - adj: AdjacencyView[_Node, _Node, dict[str, Incomplete]] - name: str - + @cached_property + def adj(self) -> AdjacencyView[_Node, _Node, dict[str, Incomplete]]: ... + @property + def name(self) -> str: ... + @name.setter + def name(self, s: str) -> None: ... def __getitem__(self, n: _Node) -> AtlasView[_Node, _Node, dict[str, Incomplete]]: ... def __iter__(self) -> Iterator[_Node]: ... def __contains__(self, n: object) -> bool: ... @@ -48,7 +51,8 @@ class Graph(Collection[_Node]): def add_nodes_from(self, nodes_for_adding: Iterable[_NodePlus[_Node]], **attr) -> None: ... def remove_node(self, n: _Node) -> None: ... def remove_nodes_from(self, nodes: Iterable[_Node]) -> None: ... - nodes: NodeView[_Node] + @cached_property + def nodes(self) -> NodeView[_Node]: ... def number_of_nodes(self) -> int: ... def order(self) -> int: ... def has_node(self, n: _Node) -> bool: ... @@ -67,12 +71,12 @@ class Graph(Collection[_Node]): ) -> None: ... def has_edge(self, u: _Node, v: _Node) -> bool: ... def neighbors(self, n: _Node) -> Iterator[_Node]: ... - edges: OutEdgeView[_Node] + @cached_property + def edges(self) -> OutEdgeView[_Node]: ... def get_edge_data(self, u: _Node, v: _Node, default: Incomplete | None = None) -> Mapping[str, Incomplete]: ... def adjacency(self) -> Iterator[tuple[_Node, Mapping[_Node, Mapping[str, Incomplete]]]]: ... - - degree: DiDegreeView[_Node] - + @cached_property + def degree(self) -> DiDegreeView[_Node]: ... def clear(self) -> None: ... def clear_edges(self) -> None: ... def is_multigraph(self) -> bool: ... diff --git a/stubs/networkx/networkx/classes/multidigraph.pyi b/stubs/networkx/networkx/classes/multidigraph.pyi index 8f90911ec..e9a2b91b1 100644 --- a/stubs/networkx/networkx/classes/multidigraph.pyi +++ b/stubs/networkx/networkx/classes/multidigraph.pyi @@ -1,12 +1,25 @@ +from _typeshed import Incomplete +from functools import cached_property + +from networkx.classes.coreviews import MultiAdjacencyView from networkx.classes.digraph import DiGraph from networkx.classes.graph import _Node from networkx.classes.multigraph import MultiGraph -from networkx.classes.reportviews import InMultiDegreeView, MultiDegreeView, OutMultiDegreeView +from networkx.classes.reportviews import InMultiDegreeView, OutMultiDegreeView, OutMultiEdgeView class MultiDiGraph(MultiGraph[_Node], DiGraph[_Node]): - degree: MultiDegreeView[_Node] - in_degree: InMultiDegreeView[_Node] - out_degree: OutMultiDegreeView[_Node] + @cached_property + def succ(self) -> MultiAdjacencyView[_Node, _Node, dict[str, Incomplete]]: ... + @cached_property + def pred(self) -> MultiAdjacencyView[_Node, _Node, dict[str, Incomplete]]: ... + @cached_property + def out_edges(self) -> OutMultiEdgeView[_Node]: ... + @cached_property + def in_edges(self) -> OutMultiEdgeView[_Node]: ... + @cached_property + def in_degree(self) -> InMultiDegreeView[_Node]: ... + @cached_property + def out_degree(self) -> OutMultiDegreeView[_Node]: ... def to_undirected(self, reciprocal: bool = False, as_view: bool = False) -> MultiGraph[_Node]: ... # type: ignore def reverse(self, copy: bool = True) -> MultiDiGraph[_Node]: ... def copy(self, as_view: bool = False) -> MultiDiGraph[_Node]: ... diff --git a/stubs/networkx/networkx/classes/multigraph.pyi b/stubs/networkx/networkx/classes/multigraph.pyi index 9462bd64c..fac092060 100644 --- a/stubs/networkx/networkx/classes/multigraph.pyi +++ b/stubs/networkx/networkx/classes/multigraph.pyi @@ -1,6 +1,8 @@ from _typeshed import Incomplete +from functools import cached_property from typing_extensions import TypeAlias +from networkx.classes.coreviews import MultiAdjacencyView from networkx.classes.graph import Graph, _Node from networkx.classes.multidigraph import MultiDiGraph @@ -8,6 +10,8 @@ _MultiEdge: TypeAlias = tuple[_Node, _Node, int] # noqa: Y047 class MultiGraph(Graph[_Node]): def __init__(self, incoming_graph_data: Incomplete | None = None, multigraph_input: bool | None = None, **attr) -> None: ... + @cached_property + def adj(self) -> MultiAdjacencyView[_Node, _Node, dict[str, Incomplete]]: ... def new_edge_key(self, u: _Node, v: _Node) -> int: ... def add_edge(self, u_for_edge, v_for_edge, key: Incomplete | None = None, **attr): ... # type: ignore[override] # Has an additional `key` keyword argument def remove_edge(self, u, v, key: Incomplete | None = None): ...