diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b55878ce4..82b591d60 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/setup-python@v4 with: python-version: 3.8 - - run: pip install -U flake8 black~=22.0 + - run: pip install -U ruff black~=22.0 - uses: dtolnay/rust-toolchain@stable with: components: rustfmt @@ -38,7 +38,7 @@ jobs: - name: Black Codestyle Format run: black --check --diff retworkx rustworkx retworkx tests - name: Python Lint - run: flake8 --per-file-ignores='retworkx/__init__.py:F405,F403' setup.py retworkx tests rustworkx + run: ruff check rustworkx retworkx setup.py tests - name: Check stray release notes run: python tools/find_stray_release_notes.py - name: rustworkx-core Rust Tests diff --git a/pyproject.toml b/pyproject.toml index 4aee0fecb..4a913c495 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,6 +6,35 @@ build-backend = "setuptools.build_meta" line-length = 100 target-version = ['py38', 'py39', 'py310', 'py311'] +[tool.ruff] +line-length = 100 +src = ["rustworkx", "setup.py", "retworkx", "tests"] +select = [ + "E", # pycodestyle + "F", # pyflakes + "UP", # pyupgrade + "PYI", # flake8-pyi + "Q", # flake8-quotes +] +target-version = "py38" +exclude = [ + ".venv", + ".git", + ".tox", + ".eggs", + "dist", + "doc", + "build", +] + +[tool.ruff.per-file-ignores] +"rustworkx/__init__.py" = ["F405", "F403"] +"rustworkx/__init__.pyi" = ["F403", "F405", "PYI001"] +"rustworkx/digraph.pyi" = ["F403", "F405", "PYI001"] +"rustworkx/graph.pyi" = ["F403", "F405", "PYI001"] +"rustworkx/iterators.pyi" = ["F403", "F405", "PYI001"] +"rustworkx/rustworkx.pyi" = ["F403", "F405", "PYI001"] + [tool.cibuildwheel] manylinux-x86_64-image = "manylinux2014" manylinux-i686-image = "manylinux2014" diff --git a/rustworkx/digraph.pyi b/rustworkx/digraph.pyi index 13735b5fc..1eb54a083 100644 --- a/rustworkx/digraph.pyi +++ b/rustworkx/digraph.pyi @@ -13,7 +13,7 @@ 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, Generic, TypeVar, Sequence __all__ = ["PyDiGraph"] @@ -33,36 +33,36 @@ class PyDiGraph(Generic[S, T]): def add_edge(self, parent: int, child: int, edge: T, /) -> int: ... def add_edges_from( self, - obj_list: Sequence[Tuple[int, int, T]], + obj_list: Sequence[tuple[int, int, T]], /, - ) -> List[int]: ... + ) -> list[int]: ... def add_edges_from_no_data( - self: PyDiGraph[S, Optional[T]], obj_list: Sequence[Tuple[int, int]], / - ) -> List[int]: ... + 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 adj(self, node: int, /) -> dict[int, T]: ... + def adj_direction(self, node: int, direction: bool, /) -> dict[int, T]: ... def compose( self, other: PyDiGraph[S, T], - node_map: Dict[int, Tuple[int, T]], + node_map: dict[int, tuple[int, T]], /, - node_map_func: Optional[Callable[[S], int]] = ..., - edge_map_func: Optional[Callable[[T], int]] = ..., - ) -> Dict[int, int]: ... + node_map_func: Callable[[S], int] | None = ..., + edge_map_func: Callable[[T], int] | None = ..., + ) -> dict[int, 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 edges(self) -> list[T]: ... def extend_from_edge_list( - self: PyDiGraph[Optional[S], Optional[T]], edge_list: Sequence[Tuple[int, int]], / + self: PyDiGraph[S | None, T | None], edge_list: Sequence[tuple[int, int]], / ) -> None: ... def extend_from_weighted_edge_list( - self: PyDiGraph[Optional[S], T], - edge_list: Sequence[Tuple[int, int, T]], + self: PyDiGraph[S | None, T], + edge_list: Sequence[tuple[int, int, T]], /, ) -> None: ... def find_adjacent_node_by_edge(self, node: int, predicate: Callable[[T], bool], /) -> S: ... @@ -70,11 +70,11 @@ class PyDiGraph(Generic[S, T]): self, obj: Callable[[S], bool], /, - ) -> Optional[int]: ... + ) -> int | None: ... def find_predecessors_by_edge( self, node: int, filter_fn: Callable[[T], bool], / - ) -> List[S]: ... - def find_successors_by_edge(self, node: int, filter_fn: Callable[[T], bool], /) -> List[S]: ... + ) -> list[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 = ... @@ -83,7 +83,7 @@ class PyDiGraph(Generic[S, T]): 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_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 has_edge(self, node_a: int, node_b: int, /) -> bool: ... @@ -97,31 +97,31 @@ class PyDiGraph(Generic[S, T]): def merge_nodes(self, u: int, v: int, /) -> None: ... def neighbors(self, node: int, /) -> NodeIndices: ... def node_indexes(self) -> NodeIndices: ... - def nodes(self) -> List[S]: ... + 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]: ... + def predecessors(self, node: int, /) -> list[S]: ... @staticmethod def read_edge_list( path: str, /, - comment: Optional[str] = ..., - deliminator: Optional[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_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: Optional[bool] = ..., - condition: Optional[Callable[[S, S], bool]] = ..., + 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]: ... @@ -129,26 +129,26 @@ class PyDiGraph(Generic[S, T]): self, node: int, other: PyDiGraph[S, T], - edge_map_fn: Callable[[int, int, T], Optional[int]], + edge_map_fn: Callable[[int, int, T], int | None], /, - node_filter: Optional[Callable[[S], bool]] = ..., - edge_weight_map: Optional[Callable[[T], T]] = ..., + 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 successors(self, node: int, /) -> list[S]: ... def to_dot( self, /, - node_attr: Optional[Callable[[S], Dict[str, str]]] = ..., - edge_attr: Optional[Callable[[T], Dict[str, str]]] = ..., - graph_attr: Optional[Dict[str, str]] = ..., - filename: Optional[str] = ..., - ) -> Optional[str]: ... + 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: ... def to_undirected( self, /, multigraph: bool = ..., - weight_combo_fn: Optional[Callable[[T, T], T]] = ..., + weight_combo_fn: Callable[[T, T], T] | None = ..., ) -> PyGraph[S, T]: ... def update_edge( self, @@ -163,8 +163,8 @@ class PyDiGraph(Generic[S, T]): self, path: str, /, - deliminator: Optional[str] = ..., - weight_fn: Optional[Callable[[T], str]] = ..., + deliminator: str | None = ..., + weight_fn: Callable[[T], str] | None = ..., ) -> None: ... def reverse(self) -> None: ... def __delitem__(self, idx: int, /) -> None: ... diff --git a/rustworkx/graph.pyi b/rustworkx/graph.pyi index 44eb37260..e491b4c8f 100644 --- a/rustworkx/graph.pyi +++ b/rustworkx/graph.pyi @@ -15,12 +15,8 @@ from .iterators import * from typing import ( Any, Callable, - Dict, Generic, TypeVar, - Optional, - List, - Tuple, Sequence, ) @@ -35,35 +31,35 @@ class PyGraph(Generic[S, T]): 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]], + obj_list: Sequence[tuple[int, int, T]], /, - ) -> List[int]: ... + ) -> list[int]: ... def add_edges_from_no_data( - self: PyGraph[S, Optional[T]], obj_list: Sequence[Tuple[int, int]], / - ) -> List[int]: ... + 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 adj(self, node: int, /) -> dict[int, T]: ... def compose( self, other: PyGraph[S, T], - node_map: Dict[int, Tuple[int, T]], + node_map: dict[int, tuple[int, T]], /, - node_map_func: Optional[Callable[[S], int]] = ..., - edge_map_func: Optional[Callable[[T], int]] = ..., - ) -> Dict[int, int]: ... + node_map_func: Callable[[S], int] | None = ..., + edge_map_func: Callable[[T], int] | None = ..., + ) -> dict[int, 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 edges(self) -> list[T]: ... def extend_from_edge_list( - self: PyGraph[Optional[S], Optional[T]], edge_list: Sequence[Tuple[int, int]], / + self: PyGraph[S | None, T | None], edge_list: Sequence[tuple[int, int]], / ) -> None: ... def extend_from_weighted_edge_list( - self: PyGraph[Optional[S], T], - edge_list: Sequence[Tuple[int, int, T]], + self: PyGraph[S | None, T], + edge_list: Sequence[tuple[int, int, T]], /, ) -> None: ... @staticmethod @@ -74,26 +70,26 @@ class PyGraph(Generic[S, T]): 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_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 has_edge(self, node_a: int, node_b: int, /) -> bool: ... def neighbors(self, node: int, /) -> NodeIndices: ... def node_indexes(self) -> NodeIndices: ... - def nodes(self) -> List[S]: ... + def nodes(self) -> list[S]: ... def num_edges(self) -> int: ... def num_nodes(self) -> int: ... @staticmethod def read_edge_list( path: str, /, - comment: Optional[str] = ..., - deliminator: Optional[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_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]: ... @@ -101,19 +97,19 @@ class PyGraph(Generic[S, T]): self, node: int, other: PyGraph[S, T], - edge_map_fn: Callable[[int, int, T], Optional[int]], + edge_map_fn: Callable[[int, int, T], int | None], /, - node_filter: Optional[Callable[[S], bool]] = ..., - edge_weight_map: Optional[Callable[[T], T]] = ..., + node_filter: Callable[[S], bool] | None = ..., + edge_weight_map: Callable[[T], T] | None = ..., ) -> NodeMap: ... def to_dot( self, /, - node_attr: Optional[Callable[[S], Dict[str, str]]] = ..., - edge_attr: Optional[Callable[[T], Dict[str, str]]] = ..., - graph_attr: Optional[Dict[str, str]] = ..., - filename: Optional[str] = ..., - ) -> Optional[str]: ... + 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: ... def update_edge( self, source: int, @@ -127,8 +123,8 @@ class PyGraph(Generic[S, T]): self, path: str, /, - deliminator: Optional[str] = ..., - weight_fn: Optional[Callable[[T], str]] = ..., + deliminator: str | None = ..., + weight_fn: Callable[[T], str] | None = ..., ) -> None: ... def __delitem__(self, idx: int, /) -> None: ... def __getitem__(self, idx: int, /) -> S: ... diff --git a/rustworkx/iterators.pyi b/rustworkx/iterators.pyi index e0d32c2f8..20779aa18 100644 --- a/rustworkx/iterators.pyi +++ b/rustworkx/iterators.pyi @@ -12,18 +12,14 @@ from typing import ( Any, Generic, - List, - Dict, ItemsView, KeysView, ValuesView, Iterator, Mapping, TypeVar, - Tuple, overload, final, - Optional, ) from abc import ABC from collections.abc import Sequence @@ -65,11 +61,10 @@ class RustworkxCustomVecIter(Generic[T_co], Sequence[T_co], ABC): def __getitem__(self: Self, index: slice) -> Self: ... def __getstate__(self) -> Any: ... def __hash__(self) -> int: ... - def __str__(self) -> str: ... def __len__(self) -> int: ... def __ne__(self, other: object) -> bool: ... def __setstate__(self, state: Sequence[T_co]) -> None: ... - def __array__(self, _dt: Optional[np.dtype] = ...) -> np.ndarray: ... + def __array__(self, _dt: np.dtype | None = ...) -> np.ndarray: ... class RustworkxCustomHashMapIter(Generic[S, T_co], Mapping[S, T_co], ABC): def __init__(self) -> None: ... @@ -81,7 +76,6 @@ class RustworkxCustomHashMapIter(Generic[S, T_co], Mapping[S, T_co], ABC): def __getitem__(self, index: S) -> T_co: ... def __getstate__(self) -> Any: ... def __hash__(self) -> int: ... - def __str__(self) -> str: ... def __iter__(self) -> Iterator[S]: ... def __len__(self) -> int: ... def __ne__(self, other: object) -> bool: ... @@ -103,10 +97,10 @@ class AllPairsPathLengthMapping(RustworkxCustomHashMapIter[int, PathLengthMappin class AllPairsPathMapping(RustworkxCustomHashMapIter[int, PathMapping]): ... @final -class BFSSuccessors(Generic[T_co], RustworkxCustomVecIter[Tuple[T_co, List[T_co]]]): ... +class BFSSuccessors(Generic[T_co], RustworkxCustomVecIter[tuple[T_co, list[T_co]]]): ... @final -class EdgeIndexMap(Generic[T_co], RustworkxCustomHashMapIter[int, Tuple[int, int, T_co]]): ... +class EdgeIndexMap(Generic[T_co], RustworkxCustomHashMapIter[int, tuple[int, int, T_co]]): ... @final class EdgeIndices(RustworkxCustomVecIter[int]): ... @@ -115,7 +109,7 @@ class EdgeIndices(RustworkxCustomVecIter[int]): ... class Chains(RustworkxCustomVecIter[EdgeIndices]): ... @final -class EdgeList(RustworkxCustomVecIter[Tuple[int, int]]): ... +class EdgeList(RustworkxCustomVecIter[tuple[int, int]]): ... @final class NodeMap(RustworkxCustomHashMapIter[int, int]): ... @@ -124,22 +118,22 @@ class NodeMap(RustworkxCustomHashMapIter[int, int]): ... class NodesCountMapping(RustworkxCustomHashMapIter[int, int]): ... @final -class Pos2DMapping(RustworkxCustomHashMapIter[int, Tuple[float, float]]): ... +class Pos2DMapping(RustworkxCustomHashMapIter[int, tuple[float, float]]): ... @final -class WeightedEdgeList(Generic[T_co], RustworkxCustomVecIter[Tuple[int, int, T_co]]): ... +class WeightedEdgeList(Generic[T_co], RustworkxCustomVecIter[tuple[int, int, T_co]]): ... @final class CentralityMapping(RustworkxCustomHashMapIter[int, float]): ... @final -class BiconnectedComponents(RustworkxCustomHashMapIter[Tuple[int, int], int]): ... +class BiconnectedComponents(RustworkxCustomHashMapIter[tuple[int, int], int]): ... @final -class ProductNodeMap(RustworkxCustomHashMapIter[Tuple[int, int], int]): ... +class ProductNodeMap(RustworkxCustomHashMapIter[tuple[int, int], int]): ... @final -class MultiplePathMapping(RustworkxCustomHashMapIter[int, List[List[int]]]): ... +class MultiplePathMapping(RustworkxCustomHashMapIter[int, list[list[int]]]): ... @final class AllPairsMultiplePathMapping(RustworkxCustomHashMapIter[int, MultiplePathMapping]): ... diff --git a/setup.py b/setup.py index f9ba66454..7c0eac95d 100644 --- a/setup.py +++ b/setup.py @@ -18,17 +18,17 @@ def readme(): - with open('README.md') as f: + with open("README.md") as f: return f.read() -mpl_extras = ['matplotlib>=3.0'] -graphviz_extras = ['pillow>=5.4'] +mpl_extras = ["matplotlib>=3.0"] +graphviz_extras = ["pillow>=5.4"] -PKG_NAME = os.getenv('RUSTWORKX_PKG_NAME', "rustworkx") +PKG_NAME = os.getenv("RUSTWORKX_PKG_NAME", "rustworkx") PKG_VERSION = "0.14.0" PKG_PACKAGES = ["rustworkx", "rustworkx.visualization"] -PKG_INSTALL_REQUIRES = ['numpy>=1.16.0'] +PKG_INSTALL_REQUIRES = ["numpy>=1.16.0"] RUST_EXTENSIONS = [RustExtension("rustworkx.rustworkx", "Cargo.toml", binding=Binding.PyO3, debug=rustworkx_debug)] @@ -55,7 +55,7 @@ def readme(): version=PKG_VERSION, description="A python graph library implemented in Rust", long_description=README, - long_description_content_type='text/markdown', + long_description_content_type="text/markdown", author="Matthew Treinish", author_email="mtreinish@kortar.org", license="Apache 2.0", @@ -88,8 +88,8 @@ def readme(): python_requires=">=3.8", install_requires=PKG_INSTALL_REQUIRES, extras_require={ - 'mpl': mpl_extras, - 'graphviz': graphviz_extras, - 'all': mpl_extras + graphviz_extras, + "mpl": mpl_extras, + "graphviz": graphviz_extras, + "all": mpl_extras + graphviz_extras, } ) diff --git a/tests/rustworkx_tests/digraph/test_dot.py b/tests/rustworkx_tests/digraph/test_dot.py index 64957ef04..f2dc98428 100644 --- a/tests/rustworkx_tests/digraph/test_dot.py +++ b/tests/rustworkx_tests/digraph/test_dot.py @@ -50,7 +50,7 @@ def test_digraph_to_dot_to_file(self): res = graph.to_dot(lambda node: node, lambda edge: edge, filename=self.path) self.addCleanup(os.remove, self.path) self.assertIsNone(res) - with open(self.path, "r") as fd: + with open(self.path) as fd: res = fd.read() self.assertEqual(expected, res) diff --git a/tests/rustworkx_tests/digraph/test_edgelist.py b/tests/rustworkx_tests/digraph/test_edgelist.py index d47d9f781..d51a08c29 100644 --- a/tests/rustworkx_tests/digraph/test_edgelist.py +++ b/tests/rustworkx_tests/digraph/test_edgelist.py @@ -152,7 +152,7 @@ def test_write_edge_list_empty_digraph(self): graph = rustworkx.PyDiGraph() graph.write_edge_list(path) self.addCleanup(os.remove, path) - with open(path, "rt") as edge_file: + with open(path) as edge_file: self.assertEqual("", edge_file.read()) def test_write_edge_list_round_trip(self): @@ -184,7 +184,7 @@ def test_custom_delim(self): 2,3 3,4 """ - with open(path, "rt") as edge_file: + with open(path) as edge_file: self.assertEqual(edge_file.read(), expected) def test_invalid_return_type_weight_fn(self): diff --git a/tests/rustworkx_tests/digraph/test_layout.py b/tests/rustworkx_tests/digraph/test_layout.py index 792557556..5d5b1a0b0 100644 --- a/tests/rustworkx_tests/digraph/test_layout.py +++ b/tests/rustworkx_tests/digraph/test_layout.py @@ -24,9 +24,8 @@ def assertLayoutEquiv(self, exp, res): rv = res[k] if abs(ev[0] - rv[0]) > self.thres or abs(ev[1] - rv[1]) > self.thres: self.fail( - "The position for node %s, %s, differs from the expected " - "position, %s by more than the allowed threshold of %s" - % (k, rv, ev, self.thres) + f"The position for node {k}, {rv}, differs from the expected " + f"position, {ev} by more than the allowed threshold of {self.thres}" ) diff --git a/tests/rustworkx_tests/graph/test_dot.py b/tests/rustworkx_tests/graph/test_dot.py index 5ab04d656..63c98804e 100644 --- a/tests/rustworkx_tests/graph/test_dot.py +++ b/tests/rustworkx_tests/graph/test_dot.py @@ -104,7 +104,7 @@ def test_graph_to_dot_to_file(self): res = graph.to_dot(lambda node: node, lambda edge: edge, filename=self.path) self.addCleanup(os.remove, self.path) self.assertIsNone(res) - with open(self.path, "r") as fd: + with open(self.path) as fd: res = fd.read() self.assertEqual(expected, res) diff --git a/tests/rustworkx_tests/graph/test_edgelist.py b/tests/rustworkx_tests/graph/test_edgelist.py index 95063e54f..6b4165e44 100644 --- a/tests/rustworkx_tests/graph/test_edgelist.py +++ b/tests/rustworkx_tests/graph/test_edgelist.py @@ -148,7 +148,7 @@ def test_write_edge_list_empty_digraph(self): graph = rustworkx.PyGraph() graph.write_edge_list(path) self.addCleanup(os.remove, path) - with open(path, "rt") as edge_file: + with open(path) as edge_file: self.assertEqual("", edge_file.read()) def test_write_edge_list_round_trip(self): @@ -180,7 +180,7 @@ def test_custom_delim(self): 2,3 3,4 """ - with open(path, "rt") as edge_file: + with open(path) as edge_file: self.assertEqual(edge_file.read(), expected) def test_invalid_return_type_weight_fn(self): diff --git a/tests/rustworkx_tests/graph/test_layout.py b/tests/rustworkx_tests/graph/test_layout.py index 032857899..c656b7fe5 100644 --- a/tests/rustworkx_tests/graph/test_layout.py +++ b/tests/rustworkx_tests/graph/test_layout.py @@ -24,9 +24,8 @@ def assertLayoutEquiv(self, exp, res): rv = res[k] if abs(ev[0] - rv[0]) > self.thres or abs(ev[1] - rv[1]) > self.thres: self.fail( - "The position for node %s, %s, differs from the expected " - "position, %s by more than the allowed threshold of %s" - % (k, rv, ev, self.thres) + f"The position for node {k}, {rv}, differs from the expected " + f"position, {ev} by more than the allowed threshold of {self.thres}" ) diff --git a/tests/rustworkx_tests/graph/test_max_weight_matching.py b/tests/rustworkx_tests/graph/test_max_weight_matching.py index 29e5a3382..429036649 100644 --- a/tests/rustworkx_tests/graph/test_max_weight_matching.py +++ b/tests/rustworkx_tests/graph/test_max_weight_matching.py @@ -30,9 +30,9 @@ def compare_match_sets(self, rx_match, expected_match): for (u, v) in rx_match: if (u, v) not in expected_match and (v, u) not in expected_match: self.fail( - "Element %s and it's reverse %s not found in " - "expected output.\nrustworkx output: %s\nexpected " - "output: %s" % ((u, v), (v, u), rx_match, expected_match) + f"Element {(u, v)} and it's reverse {(v, u)} not found in " + f"expected output.\nrustworkx output: {rx_match}\nexpected " + f"output: {expected_match}" ) def compare_rx_nx_sets(self, rx_graph, rx_matches, nx_matches, seed, nx_graph): @@ -53,11 +53,10 @@ def get_nx_weight(edge): if (u, v) not in nx_matches: if (v, u) not in nx_matches: print( - "seed %s failed. Element %s and it's " - "reverse %s not found in networkx output.\nrustworkx" - " output: %s\nnetworkx output: %s\nedge list: %s\n" - "falling back to checking for a valid solution" - % ( + "seed {} failed. Element {} and it's " + "reverse {} not found in networkx output.\nrustworkx" + " output: {}\nnetworkx output: {}\nedge list: {}\n" + "falling back to checking for a valid solution".format( seed, (u, v), (v, u), diff --git a/tests/rustworkx_tests/graph/test_substitute_node_with_subgraph.py b/tests/rustworkx_tests/graph/test_substitute_node_with_subgraph.py index 2ddd8bf3e..e76f1f56c 100644 --- a/tests/rustworkx_tests/graph/test_substitute_node_with_subgraph.py +++ b/tests/rustworkx_tests/graph/test_substitute_node_with_subgraph.py @@ -34,7 +34,7 @@ def test_single_node(self): def test_node_filter(self): in_graph = rustworkx.generators.complete_graph(5) res = self.graph.substitute_node_with_subgraph( - 0, in_graph, lambda _, __, ___: 2, node_filter=lambda node: node == None + 0, in_graph, lambda _, __, ___: 2, node_filter=lambda node: node is None ) self.assertEqual(res, {i: i + 5 for i in range(5)}) self.assertEqual( diff --git a/tests/rustworkx_tests/test_custom_return_types.py b/tests/rustworkx_tests/test_custom_return_types.py index 2362f125b..48aeb7c0a 100644 --- a/tests/rustworkx_tests/test_custom_return_types.py +++ b/tests/rustworkx_tests/test_custom_return_types.py @@ -1175,7 +1175,7 @@ def test_index_error(self): def test_keys(self): keys = rustworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn).keys() - self.assertEqual([0, 1], list(sorted((keys)))) + self.assertEqual([0, 1], list(sorted(keys))) def test_values(self): values = rustworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn).values() diff --git a/tox.ini b/tox.ini index 12f6d1ec8..82ee34eaa 100644 --- a/tox.ini +++ b/tox.ini @@ -33,12 +33,12 @@ commands = basepython = python3 deps = black~=22.0 - flake8 + ruff setuptools-rust whitelist_externals=cargo commands = black --check --diff {posargs} '../rustworkx' '../tests' '../retworkx' - flake8 --per-file-ignores='../rustworkx/__init__.py:F405,F403' ../setup.py ../rustworkx ../retworkx . + ruff check ../rustworkx ../retworkx . ../setup.py cargo fmt --all -- --check python {toxinidir}/tools/find_stray_release_notes.py @@ -77,14 +77,3 @@ basepython = python3 deps = mypy==1.0.1 commands = python -m mypy.stubtest --concise --ignore-missing-stub rustworkx.rustworkx - -[flake8] -# E125 is deliberately excluded. See https://github.com/jcrocholl/pep8/issues/126 -# E123 skipped because it is ignored by default in the default pep8 -# E129 skipped because it is too limiting when combined with other rules -# E711 skipped because sqlalchemy filter() requires using == instead of is -# max-line-length, E203, W503 are added for black compatibility -max-line-length = 110 -ignore = E125,E123,E129,E711 -extend-ignore = E203, W503 -exclude = .venv,.git,.tox,dist,doc,*egg,build