Skip to content

Fix NotebookPath equality/hash contract for equal relative paths - #330

Open
Flerpharos wants to merge 1 commit into
mainfrom
fix/319-notebookpath-eq-hash
Open

Fix NotebookPath equality/hash contract for equal relative paths#330
Flerpharos wants to merge 1 commit into
mainfrom
fix/319-notebookpath-eq-hash

Conversation

@Flerpharos

Copy link
Copy Markdown
Collaborator

What

Fixes the HIGH audit finding #319. Two equal unanchored relative NotebookPaths compared unequal while hashing equal:

  • __hash__ fell back to (self._absolute, tuple(self._parts)) when resolve() raised PathError (an unanchored relative path can't resolve) — so equal relative paths hashed the same.
  • __eq__ returned False on that same PathError — so they compared unequal.

Result: NotebookPath("foo/bar") == NotebookPath("foo/bar") was False, b in {a} was False, and equal relative paths became distinct dict/set keys.

Fix

Both __eq__ and __hash__ now use a shared _comparison_key() — the resolved path when resolvable, else the raw normalized (absoluteness, segments) state. Since resolve() always yields an absolute path, an unanchored relative path can never key-match an absolute one, so only genuinely equal relative paths compare equal. No other equality changes.

Verification

New test test_notebook_path_equal_relative_paths_are_equal_and_hashable (==, hash, in {…}, set dedup, dict lookup, plus non-equality preserved). Full suite: 431 passed, 1 skipped; ruff/pyright clean.

Fixes #319.

🤖 Generated with Claude Code

Two equal unanchored relative paths compared unequal while hashing equal:
`__hash__` fell back to the raw normalized state on PathError, but `__eq__`
returned False on the same PathError, so `NotebookPath("a/b") == NotebookPath("a/b")`
was False while both hashed equal -- breaking dict/set membership.

Give both a shared `_comparison_key()` (resolved path when resolvable, else
the raw `(absoluteness, segments)` state). Resolvable paths are always
absolute, so an unanchored relative path can never compare equal to an
absolute one; only genuinely equal relative paths now compare equal.

Fixes #319.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Flerpharos

Copy link
Copy Markdown
Collaborator Author

This attempt to fix breaks the fundamental equality system where different paths that go to the same place are equal.

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.

NotebookPath equality/hash contract violated for equal relative paths

1 participant