Skip to content

test(init): resolve sys.path entries against cwd so the suite is green from a worktree (#454) - #482

Merged
jphein merged 2 commits into
mainfrom
fix/454-init-test-worktree
Sep 11, 2026
Merged

jphein merged 2 commits into
mainfrom
fix/454-init-test-worktree

Conversation

@jphein

@jphein jphein commented Sep 11, 2026 •

Copy link
Copy Markdown
Collaborator

What

tests/test_init.py::test_init_filters_sys_path_from_leaked_pythonpath failed all five sentinel params in any linked worktree. Every lane in tonight's drain wave ran the suite with it deselected and paid a false red before working that out.

Why

The behaviour under test was correct the whole time. The assertion was wrong, and it was wrong in a way that only shows up outside the main tree.

It iterated for p in sys.path if p, which deliberately excludes the empty string — and the empty string is the cwd marker python -c puts on sys.path, which is what actually resolves the child's import. Measured in both trees with PYTHONPATH set to the sentinel, exactly as the test sets it:

main tree   RESOLVED_TO <main>/mempalace/__init__.py    PARENT_ON_SYS_PATH: True
worktree    RESOLVED_TO <wt>/mempalace/__init__.py      PARENT_ON_SYS_PATH: False
both        EMPTY_IN_PATH: True     LOADER: SourceFileLoader

The child imports the tree it was launched from in both cases, via that cwd entry. The absolute-entry match succeeded in the main tree for an incidental reason: the shared venv's editable install adds exactly /home/jp/Projects/memorypalace to sys.path, so the comparison found it there. From a linked worktree the editable entry points at the main tree, the absolute match fails, and the test reports an over-strip that never happened.

So the green in the main tree was luck, not coverage — the assertion was measuring "is this directory the editable install's target?", not "did the filter over-strip?".

How

Normalise each entry with os.path.abspath(p or os.curdir) before comparing, so the cwd marker counts as the entry it actually is.

That is faithful to the assertion's own stated purpose — "the mempalace package itself must remain importable, so its parent directory must survive on sys.path" — because the cwd entry is precisely how it remained importable.

It keeps its teeth. The assertion can now only fail if the filter removed both the cwd marker and any absolute entry providing the package, which is exactly an over-strip. And a child that cannot import mempalace at all still trips the earlier returncode == 0 assertion, so the "unimportable" case is covered twice.

MEMPALACE_IMPORTED_FROM is printed for diagnosis and deliberately not asserted on: which tree the child resolves depends on its cwd, and pinning that would re-introduce the exact coupling this PR removes. I wrote that assertion first and took it back out for that reason.

Positive control, both directions

As requested — a fix that only passes where it was already passing would be worthless:

new test, from a linked worktree      8 passed
new test, cwd = main tree            8 passed
old test, from a linked worktree     5 failed, 3 passed   (the false red, unchanged)

And the payoff: the full suite now runs green from a worktree with no manual deselect — 7026 passed, 82 skipped, 115 deselected (the 115 are the benchmark/stress markers, not a hand-written exclusion).

No behaviour change to shipped code; tests/test_init.py is the only source file touched. Test count unchanged at 7108, since this repairs five existing params rather than adding any.

One note for whoever merges

The changelog entry cites the PR-branch commit and will need re-pointing to the squash sha until #480's commit: HEAD + fork_pr: format lands. Noted in the docs commit message too.

Fixes #454

Summary by CodeRabbit

  • Bug Fixes

    • Fixed an initialization test that could fail in linked worktrees by correctly resolving relative paths against the current working directory.
    • Added diagnostic output to make import-location issues easier to investigate.
  • Documentation

    • Documented the test fix, its behavior, and verification results across changelog and project documentation.

Copilot AI lite review requested due to automatic review settings September 11, 2026 05:28

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 7c1af338-f143-4be1-ade6-a0ea4701ddf3

📥 Commits

Reviewing files that changed from the base of the PR and between 6da8775 and 012bb1c.

📒 Files selected for processing (5)
  • FORK_CHANGELOG.md
  • README.md
  • docs/fork-changes/2026-09-11-init-test-cwd-relative-syspath.yaml
  • tests/test_init.py
  • website/public/llms-full.txt

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The test now normalizes sys.path entries against the child process cwd, including empty entries. It prints MEMPALACE_IMPORTED_FROM for diagnosis without asserting the selected tree. Changelog and fork-change records document the fix and verification results.

Changes

Worktree-safe test fix

Layer / File(s) Summary
Normalize subprocess path assertions
tests/test_init.py
The test resolves relative and empty sys.path entries against cwd, documents the assertion semantics, and prints MEMPALACE_IMPORTED_FROM without asserting it.
Record the worktree fix
FORK_CHANGELOG.md, docs/fork-changes/..., README.md, website/public/llms-full.txt
Project changelog and fork-change indexes document the fix and its 8/8 verification results.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Other · Severity of issue fixed: Medium

Suggested reviewers: igorls

Merge Risk: ⚪ Minimal · up to 012bb

The worktree-specific false failure is addressed without changing shipped behavior. No current merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the test change, the cwd-based sys.path resolution, and the linked-worktree failure it fixes.
Linked Issues check ✅ Passed Issue #454 requires removal of the cwd-dependent false failure in test_init_filters_sys_path_from_leaked_pythonpath while retaining the over-strip guard. tests/test_init.py now normalizes each `sy…
Out of Scope Changes check ✅ Passed The changes stay within issue #454. The source change is limited to the affected test and its diagnostics. The added YAML fork-change entry, FORK_CHANGELOG.md entry, README.md row, and `website/pu…
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 1 files. (4 skipped: 4 …
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/454-init-test-worktree

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

jphein and others added 2 commits September 10, 2026 22:57
`test_init_filters_sys_path_from_leaked_pythonpath` failed all five
sentinel params in any linked worktree, so every lane tonight ran the suite
with it deselected and paid a false red before working that out.

The behaviour under test was fine throughout. The assertion was the problem:
it iterated `for p in sys.path if p`, which deliberately excludes the empty
string — and the empty string is the cwd marker `python -c` puts on the
path, which is what actually makes the child's import resolve. Measured in
both trees with PYTHONPATH set to the sentinel, as the test sets it:

  main tree   RESOLVED_TO <main>/mempalace/__init__.py   PARENT_ON_SYS_PATH True
  worktree    RESOLVED_TO <wt>/mempalace/__init__.py     PARENT_ON_SYS_PATH False
  both        EMPTY_IN_PATH True

The child imports the tree it was launched from, in both cases, via that
cwd entry. The absolute-entry match succeeded in the main tree for an
incidental reason: the shared venv's editable install adds exactly
`/home/jp/Projects/memorypalace` to sys.path, so the comparison found it
there. From a worktree the editable entry points at the main tree, the
absolute match fails, and the test reports an over-strip that never
happened.

Fix: normalise each entry with `os.path.abspath(p or os.curdir)` before
comparing, so the cwd marker counts as the entry it is. That is faithful to
the assertion's stated purpose — "the mempalace package itself must remain
importable, so its parent directory must survive on sys.path" — because the
cwd entry is how it remained importable.

It keeps its teeth for the real failure: the assertion can now only fail if
the filter removed both the cwd marker and any absolute entry providing the
package, which is exactly an over-strip. A child that cannot import
mempalace at all still trips the earlier `returncode == 0` assertion.

`MEMPALACE_IMPORTED_FROM` is printed for diagnosis and deliberately not
asserted on: which tree the child resolves depends on its cwd, and pinning
that would re-introduce the coupling this fixes.

Verified both directions: 8/8 from a linked worktree, and 8/8 with cwd set
to the main tree. The full suite now runs green from a worktree with no
manual deselect — 7026 passed, 82 skipped.

Fixes #454

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
One new file under docs/fork-changes/ per #480's per-entry format, with
`commit: HEAD` and `fork_pr: 482` so the merge step resolves the squash sha
rather than the lane recording a branch sha that goes unreachable. `seq` 139
from `scripts/fork_changes.py --next-seq`.

Renders FORK_CHANGELOG.md, the README table and website/public/llms-full.txt.
No test-count literal: #480 removed it and check-docs derives the count.

Part of #454

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

test_init_filters_sys_path_from_leaked_pythonpath fails in any git worktree (5 cases, every drain lane sees it red)

2 participants