From b82e7285440db7dce57e819a5eb57fecd7af183a Mon Sep 17 00:00:00 2001 From: Erik Welch Date: Mon, 3 Aug 2026 14:51:10 -0500 Subject: [PATCH 1/2] Test the fmm engine guards, string weights, and config key completions Three behaviors had no test at all in the fast tier. Asking for the deprecated "fmm"/"fast_matrix_market" Matrix Market engine when fast_matrix_market is not installed must warn about the deprecation before it fails, and then fail with an ImportError naming the engine; neither read nor write had coverage for that, since the existing engine tests skip themselves when the package is missing. String edge weights in from_networkx infer a 1-D ]` in IPython, was never called. Each test was checked by perturbing the line it covers and confirming it goes red. --- graphblas/core/ss/config.py | 2 +- graphblas/tests/test_io.py | 33 ++++++++++++++++++++++++++++++++ graphblas/tests/test_ss_utils.py | 16 ++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/graphblas/core/ss/config.py b/graphblas/core/ss/config.py index 70a7dd196..e1ccd15a0 100644 --- a/graphblas/core/ss/config.py +++ b/graphblas/core/ss/config.py @@ -210,5 +210,5 @@ def __repr__(self): + "})" ) - def _ipython_key_completions_(self): # pragma: no cover (ipython) + def _ipython_key_completions_(self): return list(self) diff --git a/graphblas/tests/test_io.py b/graphblas/tests/test_io.py index d2e57cebe..3553815d1 100644 --- a/graphblas/tests/test_io.py +++ b/graphblas/tests/test_io.py @@ -192,6 +192,21 @@ def test_from_networkx_rejects_array_weights(graph_cls): gb.io.from_networkx(G) +@pytest.mark.skipif("not nx or not ss") +@pytest.mark.parametrize( + "graph_cls", [nx.Graph, nx.DiGraph, nx.MultiGraph, nx.MultiDiGraph] if nx else [] +) +def test_from_networkx_rejects_string_weights(graph_cls): + # String weights infer a 1-D ]`, so they must be the keys that + # actually resolve, not the attributes of the mapping object. + config = gb.ss.config + completions = config._ipython_key_completions_() + assert set(completions) == set(config._options) + for key in completions: + config[key] + # About aliases the same hook onto its own __iter__ (gb.ss.about[]) + about = gb.ss.about + completions = about._ipython_key_completions_() + assert set(completions) == set(about) + for key in completions: + about[key] + + @pytest.mark.skipif("gb.core.ss._IS_SSGB7") def test_context(): context = gb.ss.Context() From 7da2c6f813924c2cb250071cc5a5612a9d797a0d Mon Sep 17 00:00:00 2001 From: Erik Welch Date: Tue, 4 Aug 2026 16:57:30 -0700 Subject: [PATCH 2/2] Cover the NetworkXError wrapping in the string-weight fallback --- graphblas/tests/test_io.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/graphblas/tests/test_io.py b/graphblas/tests/test_io.py index 3553815d1..e5eb0020d 100644 --- a/graphblas/tests/test_io.py +++ b/graphblas/tests/test_io.py @@ -207,6 +207,26 @@ def test_from_networkx_rejects_string_weights(graph_cls): gb.io.from_networkx(G) +@pytest.mark.skipif("not nx") +def test_from_networkx_unsupported_dtype_is_valueerror(monkeypatch): + # scipy < 1.15 builds a string-dtype coo array happily and only fails converting + # it to csr, and networkx re-raises that failure as a NetworkXError blaming the + # sparse format. from_networkx restates it as the ValueError newer scipy raises + # directly, which is what the caller can act on; monkeypatching the fallback + # exercises the old behavior on any scipy. + import graphblas.io._networkx as _gnx + + def _raise_networkx_error(*args, **kwargs): + raise nx.NetworkXError("Unknown sparse matrix format: csr") + + monkeypatch.setattr(_gnx, "_from_networkx_via_scipy", _raise_networkx_error) + G = nx.Graph() + G.add_edge(0, 1, weight="a") + G.add_edge(1, 2, weight="b") + with pytest.raises(ValueError, match="does not support dtype"): + gb.io.from_networkx(G) + + @pytest.mark.skipif("not nx or not ss") @pytest.mark.parametrize( "graph_cls", [nx.Graph, nx.DiGraph, nx.MultiGraph, nx.MultiDiGraph] if nx else []