Skip to content

fix(test): networkx HITS test used a degenerate cycle graph (scipy-version flaky) - #1686

Merged
lmeyerov merged 2 commits into
masterfrom
fix/networkx-hits-degenerate-graph
Jul 5, 2026
Merged

fix(test): networkx HITS test used a degenerate cycle graph (scipy-version flaky)#1686
lmeyerov merged 2 commits into
masterfrom
fix/networkx-hits-degenerate-graph

Conversation

@lmeyerov

@lmeyerov lmeyerov commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Problem

test_compute_networkx_hits_outputs_hubs_and_authorities fails on the CI test-networkx-scipy-policy (nx-upper-scipy, py3.12) job:

assert math.isclose(sum(hubs.values()), 1.0)
  where nan = sum(dict_values([inf, inf, -inf]))
RuntimeWarning: divide by zero encountered in divide  (networkx hits_alg.py: h /= h.sum())

Root cause — degenerate test input, not a code regression

The test graph was a pure directed 3-cycle a→b→c→a. A cycle's adjacency is a permutation matrix, so all its singular values are equal — the singular space is fully degenerate. networkx's HITS computes scores via scipy.sparse.linalg.svds(A, k=1), which then returns an arbitrary vector from that degenerate space. When the returned vector's components sum to ~0, HITS's normalization h /= h.sum() blows up to inf/nan.

Which vector svds returns depends on the scipy/LAPACK version, so the test passed on the pinned scipy but fails on the nx-upper-scipy profile's newer scipy. It's a latent flake exposed by dependency drift, independent of any product code.

Fix

Use a graph with a well-defined hub/authority structure (a→b, a→c, b→c). Its dominant singular vector is unique (Perron-Frobenius), so HITS scores are stable and version-independent:

hubs {a: 0.618, b: 0.382, c: 0.0}   authorities {a: 0.0, b: 0.382, c: 0.618}

Test-only change; all 12 networkx tests pass. This unblocks CI on the default branch (it will otherwise fail any PR whose fresh lockfile pulls the newer scipy).

🤖 Generated with Claude Code

https://claude.ai/code/session_01W5vkD2ZCyv3bmecBYoYYQy

…rsion flaky)

test_compute_networkx_hits_outputs_hubs_and_authorities used a pure directed
3-cycle a->b->c->a. A cycle's adjacency is a permutation matrix (all singular
values equal), so networkx HITS via scipy `svds(k=1)` returns an ARBITRARY
vector from the fully-degenerate singular space. Its components can sum to ~0,
so HITS's `h /= h.sum()` normalization blows up to inf/nan. Which vector svds
returns is scipy/LAPACK-version dependent, so the test passed on the pinned
scipy but failed on the `nx-upper-scipy` CI profile's newer scipy -- a latent
flake, not a code regression.

Use a graph with a well-defined hub/authority structure (a->b, a->c, b->c):
its dominant singular vector is unique (Perron-Frobenius), so HITS scores are
stable and version-independent. All 12 networkx tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@lmeyerov
lmeyerov merged commit bbc4082 into master Jul 5, 2026
67 of 68 checks passed
@lmeyerov
lmeyerov deleted the fix/networkx-hits-degenerate-graph branch July 5, 2026 21:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant