Skip to content

fix(project): classify a path through a regular file as absent on every platform - #501

Merged
e54-bot merged 2 commits into
mainfrom
fix/default-entry-notdir-497
Oct 9, 2026
Merged

e54-bot merged 2 commits into
mainfrom
fix/default-entry-notdir-497

Conversation

@e54-bot

@e54-bot e54-bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Completes #497's cross-platform consistency clause on top of #511 (which landed the default_entry half).

Change

A shared is_absent classification (NotFound | NotADirectory) now covers every I/O classification site, so a path through a regular file reports the same "absent" answer on Unix (ENOTDIR) and Windows (NotFound):

  • FilesystemProject::load canonicalize: file.opy/child.opy → EntryNotFound (was EntryUnreadable on Unix; Windows already classified it not-found).
  • FilesystemProjectError::is_entry_not_found: an EntryNotFound carrying an ENOTDIR cause reports not-found.
  • Provider validate_target_kind: same unification for the entryNotFound/targetNotFound reasons.

Test plan

  • file_named_src_is_default_entry_not_found + empty_directory_is_default_entry_not_found baseline parity
  • entry_inside_a_file_is_entry_not_found — the platform-unified classification (comment states verified platform)
  • New LPP test: directory target with file src reports targetNotFound through the provider
  • cargo test --workspace --all-targets, cargo fmt, cargo clippy -D warnings clean

@e54-bot

e54-bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor Author

CI classification for the Compiler compatibility gate failure (job 113779799435): it fails on unknown-spelling default:Map.GRIMSVOTN in probe_builtins.py, but this run executed at 2026-10-09 10:33 — about an hour before #503 (test(compat): record the pinned-oracle gap for Map.GRIMSVOTN) merged that exact gap recording onto main. The failure looks like a stale base, not the change itself: this branch's head 7c4f4ef predates #503. Re-running the job on a fresh merge ref (or updating the branch to current main) should turn the gate green; main passes this job.

A directory whose 'src' is a regular file made the src/main.opy
default-entry probe fail ENOTDIR, which the #484 classification mapped
to EntryUnreadable and the provider to targetUnreadable. An absent
intermediate directory names an entry that does not exist, the same as
an empty directory, so NotADirectory now joins NotFound in the absent
classification: the probe reports DefaultEntryNotFound/targetNotFound.

A direct entry path through a regular file (file.opy/child.opy) now
carries the not-found reason as well. Windows already reports a
not-found error for such paths, so classifying NotADirectory as absent
keeps the reason consistent across platforms.
@e54-bot
e54-bot force-pushed the fix/default-entry-notdir-497 branch from 7c4f4ef to 8f3e2a4 Compare October 9, 2026 23:34
@e54-bot e54-bot changed the title fix(project): treat a path through a regular file as absent fix(project): classify a path through a regular file as absent on every platform Oct 9, 2026

@e54-bot e54-bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 8f3e2a4 (worktree wt-501-absent-io). Verdict: approve-equivalent — semantics are correct, scoped narrowly, and platform consistency holds.

Semantics: file.opy/child.opy names an entry that cannot exist — an intermediate regular file makes the path unresolvable at lookup, indistinguishable from a missing component — so EntryNotFound/entryNotFound is the right answer to #497's open question, and the commit message states the reason as the issue asked. Cross-platform consistency is robust: on Windows a path through a file surfaces as ERROR_PATH_NOT_FOUND → NotFound, and even if an API returns ERROR_DIRECTORY (267), current Rust maps it to NotADirectory — is_absent covers both, so platforms agree whichever error kind Windows reports.

No over-reach: is_absent (project.rs:70-72) admits only NotFound | NotADirectory. ELOOP → FilesystemLoop and PermissionDenied remain non-absent: unresolvable_entry_is_not_classified_as_missing, unresolvable_default_entry_is_not_classified_as_missing, and unreadable_entry_reports_unreadable still assert EntryUnreadable and pass. is_entry_not_found (project.rs:120-126) still reports the real category for an EntryNotFound carrying a non-absent cause constructed through the public fields.

Coverage: all three classification sites now share is_absent (load canonicalize, default_entry probe, is_entry_not_found); the provider mirrors it in validate_target_kind (main.rs:1113-1116). entry_inside_a_file_is_entry_not_found flips correctly, empty_directory_is_default_entry_not_found pins the parity baseline, and test comments state the verified platform per #497's second criterion. New LPP test asserts targetNotFound end-to-end.

Verification: cargo test -p opy-rs --lib project → 20/20 pass; cargo test -p opy-provider --test lpp (new test + unresolvable_entry_reports_unreadable_reason + contract test) → 3/3 pass.

One low-severity observation, not a blocker: the new LPP test exercises the default_entry path already fixed by #511, so it would pass on #511 alone; the #501-specific provider delta — a file-kind target through a regular file hitting validate_target_kind's NotADirectory arm → entryNotFound — is covered only by the entry_inside_a_file_is_entry_not_found unit test at the load layer, not end-to-end. Fine to leave as-is given the arm is a four-line match, but an LPP case for file.opy/child.opy would close the loop.

The review noted the prior LPP test exercised only the default_entry path; a file-kind entry addressed through a regular file now verifies entryNotFound end to end.
@e54-bot

e54-bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor Author

Review note addressed: the new LPP test file_entry_through_a_regular_file_reports_not_found covers the validate_target_kind file-kind arm (file.opy/child.opy → entryNotFound) end to end.

@e54-bot
e54-bot merged commit 4bbb8d3 into main Oct 9, 2026
6 checks passed
@e54-bot
e54-bot deleted the fix/default-entry-notdir-497 branch October 9, 2026 23:54
This was referenced Oct 9, 2026
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.

2 participants