From 60e0df19bcb3816acc2a18102318a3171fe68ca7 Mon Sep 17 00:00:00 2001 From: Erik Welch Date: Tue, 27 Feb 2024 10:18:22 -0600 Subject: [PATCH 1/2] Update to support NetworkX 3.3 (dev), and other maintenance --- .github/workflows/lint.yml | 4 ++-- .github/workflows/publish_pypi.yml | 6 ++--- .github/workflows/test.yml | 4 ++-- .pre-commit-config.yaml | 20 ++++++++-------- README.md | 2 +- graphblas_algorithms/algorithms/_bfs.py | 2 +- graphblas_algorithms/algorithms/_helpers.py | 2 +- .../algorithms/shortest_paths/weighted.py | 3 ++- graphblas_algorithms/classes/_utils.py | 4 ++-- graphblas_algorithms/classes/digraph.py | 24 +++++++++---------- graphblas_algorithms/classes/graph.py | 18 +++++++------- graphblas_algorithms/conftest.py | 2 +- graphblas_algorithms/nxapi/_utils.py | 4 ++-- graphblas_algorithms/tests/test_match_nx.py | 3 ++- pyproject.toml | 18 ++++++++------ scripts/bench.py | 2 +- 16 files changed, 62 insertions(+), 56 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e094502..d0182dd 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.10" - - uses: pre-commit/action@v3.0.0 + - uses: pre-commit/action@v3.0.1 diff --git a/.github/workflows/publish_pypi.yml b/.github/workflows/publish_pypi.yml index d9889a1..f848ad6 100644 --- a/.github/workflows/publish_pypi.yml +++ b/.github/workflows/publish_pypi.yml @@ -18,7 +18,7 @@ jobs: with: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: "3.10" - name: Install build dependencies @@ -27,7 +27,7 @@ jobs: python -m pip install build twine - name: Build wheel and sdist run: python -m build --sdist --wheel - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: releases path: dist @@ -35,7 +35,7 @@ jobs: - name: Check with twine run: python -m twine check --strict dist/* - name: Publish to PyPI - uses: pypa/gh-action-pypi-publish@v1.8.10 + uses: pypa/gh-action-pypi-publish@v1.8.11 with: user: __token__ password: ${{ secrets.PYPI_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8be0379..47ca7bc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,7 +22,7 @@ jobs: with: fetch-depth: 0 - name: Setup mamba - uses: conda-incubator/setup-miniconda@v2 + uses: conda-incubator/setup-miniconda@v3 id: setup_mamba continue-on-error: true with: @@ -35,7 +35,7 @@ jobs: activate-environment: graphblas auto-activate-base: false - name: Setup conda - uses: conda-incubator/setup-miniconda@v2 + uses: conda-incubator/setup-miniconda@v3 id: setup_conda if: steps.setup_mamba.outcome == 'failure' continue-on-error: false diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c9e708b..4256495 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,22 +33,22 @@ repos: - id: name-tests-test args: ["--pytest-test-first"] - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.15 + rev: v0.16 hooks: - id: validate-pyproject name: Validate pyproject.toml # I don't yet trust ruff to do what autoflake does - repo: https://github.com/PyCQA/autoflake - rev: v2.2.1 + rev: v2.3.0 hooks: - id: autoflake args: [--in-place] - repo: https://github.com/pycqa/isort - rev: 5.13.1 + rev: 5.13.2 hooks: - id: isort - repo: https://github.com/asottile/pyupgrade - rev: v3.15.0 + rev: v3.15.1 hooks: - id: pyupgrade args: [--py310-plus] @@ -58,23 +58,23 @@ repos: - id: auto-walrus args: [--line-length, "100"] - repo: https://github.com/psf/black - rev: 23.12.0 + rev: 24.2.0 hooks: - id: black # - id: black-jupyter - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.7 + rev: v0.2.2 hooks: - id: ruff args: [--fix-only, --show-fixes] - repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 + rev: 7.0.0 hooks: - id: flake8 additional_dependencies: &flake8_dependencies # These versions need updated manually - - flake8==6.1.0 - - flake8-bugbear==23.12.2 + - flake8==7.0.0 + - flake8-bugbear==24.2.6 - flake8-simplify==0.21.0 - repo: https://github.com/asottile/yesqa rev: v1.5.0 @@ -89,7 +89,7 @@ repos: additional_dependencies: [tomli] files: ^(graphblas_algorithms|docs)/ - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.7 + rev: v0.2.2 hooks: - id: ruff # `pyroma` may help keep our package standards up to date if best practices change. diff --git a/README.md b/README.md index ed66df3..b761a71 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/graphblas-algorithms)](https://pypi.python.org/pypi/graphblas-algorithms/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/python-graphblas/graphblas-algorithms/blob/main/LICENSE)
-[![Tests](https://github.com/python-graphblas/graphblas-algorithms/workflows/Tests/badge.svg?branch=main)](https://github.com/python-graphblas/graphblas-algorithms/actions) +[![Tests](https://github.com/python-graphblas/graphblas-algorithms/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/python-graphblas/graphblas-algorithms/actions) [![Coverage](https://codecov.io/gh/python-graphblas/graphblas-algorithms/branch/main/graph/badge.svg)](https://codecov.io/gh/python-graphblas/graphblas-algorithms) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.7329185.svg)](https://doi.org/10.5281/zenodo.7329185) [![Discord](https://img.shields.io/badge/Chat-Discord-blue)](https://discord.com/invite/vur45CbwMz) diff --git a/graphblas_algorithms/algorithms/_bfs.py b/graphblas_algorithms/algorithms/_bfs.py index 8189aae..996aee0 100644 --- a/graphblas_algorithms/algorithms/_bfs.py +++ b/graphblas_algorithms/algorithms/_bfs.py @@ -1,4 +1,4 @@ -"""BFS routines used by other algorithms""" +"""BFS routines used by other algorithms.""" import numpy as np from graphblas import Matrix, Vector, binary, indexunary, replace, semiring, unary diff --git a/graphblas_algorithms/algorithms/_helpers.py b/graphblas_algorithms/algorithms/_helpers.py index 2c0a820..6b6f2e8 100644 --- a/graphblas_algorithms/algorithms/_helpers.py +++ b/graphblas_algorithms/algorithms/_helpers.py @@ -19,7 +19,7 @@ def normalize(x, how): def is_converged(xprev, x, tol): - """Check convergence, L1 norm: err = sum(abs(xprev - x)); err < N * tol + """Check convergence, L1 norm: ``err = sum(abs(xprev - x)); err < N * tol``. This modifies `xprev`. """ diff --git a/graphblas_algorithms/algorithms/shortest_paths/weighted.py b/graphblas_algorithms/algorithms/shortest_paths/weighted.py index a83a060..591ca6a 100644 --- a/graphblas_algorithms/algorithms/shortest_paths/weighted.py +++ b/graphblas_algorithms/algorithms/shortest_paths/weighted.py @@ -116,13 +116,14 @@ def bellman_ford_path_length(G, source, target): def bellman_ford_path_lengths(G, nodes=None, *, expand_output=False): - """Extra parameter: expand_output + """Extra parameter: expand_output. Parameters ---------- expand_output : bool, default False When False, the returned Matrix has one row per node in nodes. When True, the returned Matrix has the same shape as the input Matrix. + """ # Same algorithms as in `single_source_bellman_ford_path_length`, but with # `Cur` as a Matrix with each row corresponding to a source node. diff --git a/graphblas_algorithms/classes/_utils.py b/graphblas_algorithms/classes/_utils.py index ecf66d9..6638f9f 100644 --- a/graphblas_algorithms/classes/_utils.py +++ b/graphblas_algorithms/classes/_utils.py @@ -177,7 +177,7 @@ def matrix_to_vectornodemap(self, A): def matrix_to_dicts(self, A, *, use_row_index=False, use_column_index=False, values_are_keys=False): - """Convert a Matrix to a dict of dicts of the form ``{row: {col: val}}`` + """Convert a Matrix to a dict of dicts of the form ``{row: {col: val}}``. Use ``use_row_index=True`` to return the row index as keys in the dict, and likewise for `use_column_index=True``. @@ -256,7 +256,7 @@ def _cacheit(self, key, func, *args, **kwargs): def renumber_key_to_id(self, indices): - """Create `key_to_id` for e.g. a subgraph with node ids from `indices`""" + """Create `key_to_id` for e.g. a subgraph with node ids from `indices`.""" id_to_key = self.id_to_key return {id_to_key[index]: i for i, index in enumerate(indices)} # Alternative (about the same performance) diff --git a/graphblas_algorithms/classes/digraph.py b/graphblas_algorithms/classes/digraph.py index 1e9fe5f..5f7c89a 100644 --- a/graphblas_algorithms/classes/digraph.py +++ b/graphblas_algorithms/classes/digraph.py @@ -22,7 +22,7 @@ def get_AT(G, mask=None): - """A.T""" + """``A.T``.""" A = G._A cache = G._cache if "AT" not in cache: @@ -31,7 +31,7 @@ def get_AT(G, mask=None): def get_Up(G, mask=None): - """select.triu(A)""" + """``select.triu(A)``.""" A = G._A cache = G._cache if "U+" not in cache: @@ -50,7 +50,7 @@ def get_Up(G, mask=None): def get_Lp(G, mask=None): - """select.tril(A)""" + """``select.tril(A)``.""" A = G._A cache = G._cache if "L+" not in cache: @@ -69,7 +69,7 @@ def get_Lp(G, mask=None): def get_Um(G, mask=None): - """select.triu(A, 1)""" + """``select.triu(A, 1)``.""" A = G._A cache = G._cache if "U-" not in cache: @@ -93,7 +93,7 @@ def get_Um(G, mask=None): def get_Lm(G, mask=None): - """select.tril(A, -1)""" + """``select.tril(A, -1)``.""" A = G._A cache = G._cache if "L-" not in cache: @@ -117,7 +117,7 @@ def get_Lm(G, mask=None): def get_recip_degreesp(G, mask=None): - """pair(A & A.T).reduce_rowwise()""" + """``pair(A & A.T).reduce_rowwise()``.""" A = G._A cache = G._cache AT = cache.get("AT", A.T) @@ -159,7 +159,7 @@ def get_recip_degreesp(G, mask=None): def get_recip_degreesm(G, mask=None): - """C = select.offdiag(A) ; pair(C & C.T).reduce_rowwise()""" + """``C = select.offdiag(A) ; pair(C & C.T).reduce_rowwise()``.""" A = G._A cache = G._cache if "AT" in cache: @@ -236,7 +236,7 @@ def get_recip_degreesm(G, mask=None): def get_total_degreesp(G, mask=None): - """A.reduce_rowwise(agg.count) + A.reduce_columnwise(agg.count)""" + """``A.reduce_rowwise(agg.count) + A.reduce_columnwise(agg.count)``.""" cache = G._cache if mask is not None: if "total_degrees+" in cache: @@ -266,7 +266,7 @@ def get_total_degreesp(G, mask=None): def get_total_degreesm(G, mask=None): - """C = select.offdiag(A) ; C.reduce_rowwise(agg.count) + C.reduce_columnwise(agg.count)""" + """``C = select.offdiag(A) ; C.reduce_rowwise(agg.count) + C.reduce_columnwise(agg.count)``.""" cache = G._cache if mask is not None: if "total_degrees-" in cache: @@ -296,7 +296,7 @@ def get_total_degreesm(G, mask=None): def get_total_recipp(G, mask=None): - """pair(A & A.T).reduce_scalar()""" + """``pair(A & A.T).reduce_scalar()``.""" A = G._A cache = G._cache if "total_recip+" not in cache: @@ -315,7 +315,7 @@ def get_total_recipp(G, mask=None): def get_total_recipm(G, mask=None): - """C = select.offdiag(A) ; pair(C & C.T).reduce_scalar()""" + """``C = select.offdiag(A) ; pair(C & C.T).reduce_scalar()``.""" cache = G._cache if "total_recip-" not in cache: if "total_recip+" in cache and cache.get("has_self_edges") is False: @@ -330,7 +330,7 @@ def get_total_recipm(G, mask=None): def has_self_edges(G, mask=None): - """A.diag().nvals > 0""" + """``A.diag().nvals > 0``.""" A = G._A cache = G._cache if "has_self_edges" not in cache: diff --git a/graphblas_algorithms/classes/graph.py b/graphblas_algorithms/classes/graph.py index f3e2239..1c5e429 100644 --- a/graphblas_algorithms/classes/graph.py +++ b/graphblas_algorithms/classes/graph.py @@ -10,19 +10,19 @@ def get_A(G, mask=None): - """A""" + """``A``.""" return G._A def get_AT(G, mask=None): - """A.T""" + """``A.T``.""" A = G._A G._cache["AT"] = A return A def get_offdiag(G, mask=None): - """select.offdiag(A)""" + """``select.offdiag(A)``.""" A = G._A cache = G._cache if "offdiag" not in cache: @@ -38,7 +38,7 @@ def get_offdiag(G, mask=None): def get_Up(G, mask=None): - """select.triu(A)""" + """``select.triu(A)``.""" A = G._A cache = G._cache if "U+" not in cache: @@ -54,7 +54,7 @@ def get_Up(G, mask=None): def get_Lp(G, mask=None): - """select.tril(A)""" + """``select.tril(A)``.""" A = G._A cache = G._cache if "L+" not in cache: @@ -70,7 +70,7 @@ def get_Lp(G, mask=None): def get_Um(G, mask=None): - """select.triu(A, 1)""" + """``select.triu(A, 1)``.""" A = G._A cache = G._cache if "U-" not in cache: @@ -91,7 +91,7 @@ def get_Um(G, mask=None): def get_Lm(G, mask=None): - """select.tril(A, -1)""" + """``select.tril(A, -1)``.""" A = G._A cache = G._cache if "L-" not in cache: @@ -112,7 +112,7 @@ def get_Lm(G, mask=None): def get_diag(G, mask=None): - """A.diag()""" + """``A.diag()``.""" A = G._A cache = G._cache if "diag" not in cache: @@ -193,7 +193,7 @@ def has_negative_edgesm(G, mask=None): def has_self_edges(G, mask=None): - """A.diag().nvals > 0""" + """``A.diag().nvals > 0``.""" A = G._A cache = G._cache if "has_self_edges" not in cache: diff --git a/graphblas_algorithms/conftest.py b/graphblas_algorithms/conftest.py index 8d42a7d..8db8040 100644 --- a/graphblas_algorithms/conftest.py +++ b/graphblas_algorithms/conftest.py @@ -3,7 +3,7 @@ @pytest.fixture(scope="session", autouse=True) def ic(): - """Make `ic` available everywhere during testing for easier debugging""" + """Make `ic` available everywhere during testing for easier debugging.""" try: import icecream except ImportError: diff --git a/graphblas_algorithms/nxapi/_utils.py b/graphblas_algorithms/nxapi/_utils.py index 0bb9617..76cc9e6 100644 --- a/graphblas_algorithms/nxapi/_utils.py +++ b/graphblas_algorithms/nxapi/_utils.py @@ -88,7 +88,7 @@ def normalize_chunksize(chunksize, itemsize=1, N=None): def partition(chunksize, L, *, evenly=True): - """Partition a list into chunks""" + """Partition a list into chunks.""" N = len(L) if N == 0: return @@ -109,7 +109,7 @@ def partition(chunksize, L, *, evenly=True): def split_evenly(k, L): - """Split a list into approximately-equal parts""" + """Split a list into approximately-equal parts.""" N = len(L) if N == 0: return diff --git a/graphblas_algorithms/tests/test_match_nx.py b/graphblas_algorithms/tests/test_match_nx.py index 1924ff7..f985fd3 100644 --- a/graphblas_algorithms/tests/test_match_nx.py +++ b/graphblas_algorithms/tests/test_match_nx.py @@ -9,6 +9,7 @@ For now, though, let's try to match and stay up-to-date with NetworkX! """ + import sys from collections import namedtuple from pathlib import Path @@ -49,7 +50,7 @@ def isdispatched(func): def dispatchname(func): - """The dispatched name of the dispatchable NetworkX function""" + """The dispatched name of the dispatchable NetworkX function.""" # Haha, there should be a better way to get this if not isdispatched(func): raise ValueError(f"Function is not dispatched in NetworkX: {func.__name__}") diff --git a/pyproject.toml b/pyproject.toml index b1625c6..bbdaef1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -177,8 +177,10 @@ exclude_lines = [ # https://github.com/charliermarsh/ruff/ line-length = 100 target-version = "py310" +[tool.ruff.lint] unfixable = [ - "F841" # unused-variable (Note: can leave useless expression) + "F841", # unused-variable (Note: can leave useless expression) + "B905", # zip-without-explicit-strict (Note: prefer `zip(x, y, strict=True)`) ] select = [ "ALL", @@ -194,9 +196,9 @@ ignore = [ "D103", # Missing docstring in public function "D104", # Missing docstring in public package "D105", # Missing docstring in magic method - # "D107", # Missing docstring in `__init__` + "D107", # Missing docstring in `__init__` "D401", # First line of docstring should be in imperative mood: - # "D417", # Missing argument description in the docstring: + "D417", # D417 Missing argument description in the docstring for ...: ... "PLE0605", # Invalid format for `__all__`, must be `tuple` or `list` (Note: broken in v0.0.237) # Maybe consider @@ -209,6 +211,7 @@ ignore = [ # Intentionally ignored "COM812", # Trailing comma missing "D203", # 1 blank line required before class docstring (Note: conflicts with D211, which is preferred) + "D213", # (Note: conflicts with D212, which is preferred) "D400", # First line should end with a period (Note: prefer D415, which also allows "?" and "!") "F403", # `from .classes import *` used; unable to detect undefined names (Note: used to match networkx) "N802", # Function name ... should be lowercase @@ -232,6 +235,7 @@ ignore = [ "SIM105", # Use contextlib.suppress(...) instead of try-except-pass (Note: try-except-pass is much faster) "SIM108", # Use ternary operator ... instead of if-else-block (Note: if-else better for coverage and sometimes clearer) "TRY003", # Avoid specifying long messages outside the exception class (Note: why?) + "UP038", # Use `X | Y` in `isinstance` call instead of `(X, Y)` (Note: using `|` is slower atm) "FIX001", "FIX002", "FIX003", "FIX004", # flake8-fixme (like flake8-todos) # Ignored categories @@ -253,19 +257,19 @@ ignore = [ "PD", # pandas-vet (Intended for scripts that use pandas, not libraries) ] -[tool.ruff.per-file-ignores] +[tool.ruff.lint.per-file-ignores] "__init__.py" = ["F401"] # Allow unused imports (w/o defining `__all__`) "graphblas_algorithms/**/tests/*py" = ["S101", "T201", "D103", "D100"] # Allow assert, print, and no docstring "graphblas_algorithms/interface.py" = ["PIE794"] # Allow us to use `mod = nxapi.` repeatedly "graphblas_algorithms/nxapi/exception.py" = ["F401"] # Allow unused imports (w/o defining `__all__`) "scripts/*.py" = ["INP001", "S101", "T201"] # Not a package, allow assert, allow print -[tool.ruff.flake8-builtins] +[tool.ruff.lint.flake8-builtins] builtins-ignorelist = ["copyright"] -[tool.ruff.flake8-pytest-style] +[tool.ruff.lint.flake8-pytest-style] fixture-parentheses = false mark-parentheses = false -[tool.ruff.pydocstyle] +[tool.lint.ruff.pydocstyle] convention = "numpy" diff --git a/scripts/bench.py b/scripts/bench.py index 3b3f4dc..2e432b8 100755 --- a/scripts/bench.py +++ b/scripts/bench.py @@ -67,7 +67,7 @@ def readfile(filepath, is_symmetric, backend): def best_units(num): - """Returns scale factor and prefix such that 1 <= num*scale < 1000""" + """Returns scale factor and prefix such that ``1 <= num*scale < 1000``.""" if num < 1e-12: return 1e15, "f" if num < 1e-9: From c71148efad7c413c0f4e1389d5528a47e46057e6 Mon Sep 17 00:00:00 2001 From: Erik Welch Date: Sat, 29 Jun 2024 08:58:30 +0200 Subject: [PATCH 2/2] bump linting again --- .pre-commit-config.yaml | 25 +++++++++++++------------ README.md | 2 +- pyproject.toml | 11 ++++++++++- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4256495..c0f8cef 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ default_language_version: python: python3 repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: check-added-large-files - id: check-case-conflict @@ -33,13 +33,13 @@ repos: - id: name-tests-test args: ["--pytest-test-first"] - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.16 + rev: v0.18 hooks: - id: validate-pyproject name: Validate pyproject.toml # I don't yet trust ruff to do what autoflake does - repo: https://github.com/PyCQA/autoflake - rev: v2.3.0 + rev: v2.3.1 hooks: - id: autoflake args: [--in-place] @@ -48,32 +48,33 @@ repos: hooks: - id: isort - repo: https://github.com/asottile/pyupgrade - rev: v3.15.1 + rev: v3.16.0 hooks: - id: pyupgrade args: [--py310-plus] - repo: https://github.com/MarcoGorelli/auto-walrus - rev: v0.2.2 + rev: 0.3.4 hooks: - id: auto-walrus + additional_dependencies: [tomli] args: [--line-length, "100"] - repo: https://github.com/psf/black - rev: 24.2.0 + rev: 24.4.2 hooks: - id: black # - id: black-jupyter - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.2.2 + rev: v0.5.0 hooks: - id: ruff args: [--fix-only, --show-fixes] - repo: https://github.com/PyCQA/flake8 - rev: 7.0.0 + rev: 7.1.0 hooks: - id: flake8 additional_dependencies: &flake8_dependencies # These versions need updated manually - - flake8==7.0.0 + - flake8==7.1.0 - flake8-bugbear==24.2.6 - flake8-simplify==0.21.0 - repo: https://github.com/asottile/yesqa @@ -82,14 +83,14 @@ repos: - id: yesqa additional_dependencies: *flake8_dependencies - repo: https://github.com/codespell-project/codespell - rev: v2.2.6 + rev: v2.3.0 hooks: - id: codespell types_or: [python, rst, markdown] additional_dependencies: [tomli] files: ^(graphblas_algorithms|docs)/ - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.2.2 + rev: v0.5.0 hooks: - id: ruff # `pyroma` may help keep our package standards up to date if best practices change. @@ -100,6 +101,6 @@ repos: - id: pyroma args: [-n, "10", .] - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: no-commit-to-branch # no commit directly to main diff --git a/README.md b/README.md index b761a71..b6c7e1b 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ T5 = nx.k_truss(G2, 5) ``` `G2` is not a `nx.Graph`, but it does have an attribute -`__networkx_plugin__ = "graphblas"`. This tells NetworkX to +`__networkx_backend__ = "graphblas"`. This tells NetworkX to dispatch the k_truss call to graphblas-algorithms. This link connection exists because graphblas-algorithms registers itself as a "networkx.plugin" entry point. diff --git a/pyproject.toml b/pyproject.toml index bbdaef1..110d51f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,9 +61,14 @@ dependencies = [ "python-graphblas >=2023.1.0", ] +# nx < 3.2 [project.entry-points."networkx.plugins"] graphblas = "graphblas_algorithms.interface:Dispatcher" +[project.entry-points."networkx.plugins_info"] +graphblas = "_nx_graphblas:get_info" + +# nx >= 3.2 [project.entry-points."networkx.backends"] graphblas = "graphblas_algorithms.interface:Dispatcher" @@ -202,6 +207,10 @@ ignore = [ "PLE0605", # Invalid format for `__all__`, must be `tuple` or `list` (Note: broken in v0.0.237) # Maybe consider + "E721", # Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks + "FURB177", # Prefer `Path.cwd()` over `Path().resolve()` for current-directory lookups + "S113", # Probable use of requests call without timeout + "SIM103", # Return the condition `bool(mask.reduce(monoid.lor))` directly # "SIM300", # Yoda conditions are discouraged, use ... instead (Note: we're not this picky) # "SIM401", # Use dict.get ... instead of if-else-block (Note: if-else better for coverage and sometimes clearer) # "TRY004", # Prefer `TypeError` exception for invalid type (Note: good advice, but not worth the nuisance) @@ -271,5 +280,5 @@ builtins-ignorelist = ["copyright"] fixture-parentheses = false mark-parentheses = false -[tool.lint.ruff.pydocstyle] +[tool.ruff.lint.pydocstyle] convention = "numpy" pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy