Skip to content

Return the point from HNSW.setdefault, not the internal _Node#330

Open
chuenchen309 wants to merge 1 commit into
ekzhu:masterfrom
chuenchen309:fix/hnsw-setdefault-returns-point
Open

Return the point from HNSW.setdefault, not the internal _Node#330
chuenchen309 wants to merge 1 commit into
ekzhu:masterfrom
chuenchen309:fix/hnsw-setdefault-returns-point

Conversation

@chuenchen309

Copy link
Copy Markdown

HNSW implements MutableMapping with points as the values, and every accessor returns the point — except setdefault, which returns the private _Node wrapper:

h = HNSW(distance_func=...)
h.insert(1, np.array([1.0, 2.0]))
h.setdefault(1, np.array([9., 9.]))   # -> _Node(...)   expected: array([1., 2.])
h.setdefault(2, np.array([3.0, 4.0])) # -> _Node(...)   expected: array([3., 4.])
h[1]                                   # -> array([1., 2.])   (the sibling accessor is correct)

This violates MutableMapping.setdefault semantics (must return the value, like dict.setdefault), the method's own -> np.ndarray signature, and its docstring ("return its associated point ... return default").

Root cause (datasketch/hnsw.py): setdefault returns self._nodes[key] instead of self._nodes[key].point.

Fix (1 line):

-        return self._nodes[key]
+        return self._nodes[key].point

Verification (re-runnable from the diff): added TestHNSW.test_setdefault covering all three branches (existing non-deleted key returns its point without overwriting; absent key inserts and returns the default; soft-removed key reinserts and returns the default), written type-agnostically so it also runs under the MinHashJaccard/Jaccard/ReversedEdges subclasses. All four variants fail on the current tree (AssertionError: _Node(...)) and pass with the fix. test/test_hnsw.py goes from 40 to 44 passing with no new failures (the 4 pre-existing collection errors are an unrelated flaky-marker/plugin mismatch, identical before and after).


Disclosure: This PR was authored by an AI coding agent (Claude Code) running on this account: the AI found the bug, ran the repro, wrote the test, and wrote this description. The human account holder reviews every change and is accountable for it. The verification above is real and re-runnable from the diff. If this isn't the kind of contribution you want, say so and I'll close it.

`HNSW` implements `MutableMapping` with points as the values, and every other
accessor (`__getitem__`, `get`, `pop`, `popitem`, `items`, `values`) returns
`node.point`. `setdefault` returned `self._nodes[key]` — the private `_Node`
wrapper — violating `MutableMapping.setdefault` semantics, its own
`-> np.ndarray` signature, and its docstring.

Return `.point` like the sibling accessors.
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