Skip to content

NotebookPath equality/hash and relative_to break for anchored paths #205

Description

@Flerpharos

Problem

NotebookPath.__eq__() compares resolved paths, but __hash__() hashes unresolved internal state. Equal paths can therefore have different hashes, breaking dict/set lookup.

There is also a nearby relative_to() edge case: making one relative path relative to an identical relative path crashes because it calls NotebookPath(*empty_parts) with no required first argument.

Minimum repro: equal paths with different hashes

from labapi import NotebookPath

anchored = NotebookPath("b", parent=NotebookPath("/a"))
absolute = NotebookPath("/a/b")

print(anchored == absolute)
print(hash(anchored) == hash(absolute))
print({anchored: "value"}.get(absolute, "missing"))

Actual:

True
False
missing

Expected: if two paths compare equal, their hashes must also compare equal.

Minimum repro: relative_to identical relative path

from labapi import NotebookPath

NotebookPath("a").relative_to(NotebookPath("a"))

Actual: TypeError: NotebookPath.__init__() missing 1 required positional argument: 'part'.

Expected: return an empty relative path or a documented PathError, not an internal constructor error.

Pointers

  • src/labapi/util/path.py, NotebookPath.__eq__() resolves paths before comparison.
  • src/labapi/util/path.py, NotebookPath.__hash__() hashes unresolved state.
  • src/labapi/util/path.py, relative_to() calls NotebookPath(*self.escape(*self[len(other):])) for relative prefixes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions