Fix flaky editable install tests: stale .pyc due to integer-second mtime race - #5253
Conversation
…le pyc Python's .pyc validation uses integer-second mtimes. When tests write to source files within the same wall-clock second that the .pyc was compiled, the cached bytecode is reused silently. Add _advance_mtime() helper that bumps mtime by 2 s via os.utime, and call it on .py files after each in-test write. Remove the darwin-only xfail markers that were masking the failures. Closes #4328.
|
I was wondering about a different approach, but Claude convinced me the proposed approach is preferable. Details
I'll look at the issue to ground my answer in the actual context. Let me look at the actual test code involved to give a grounded answer. Good question — and having looked at the actual test, I think the two options are not as symmetric as they first appear. Here's how I'd weigh them. What the test is actually doingIn (project / "src/mypkg/mod.py").write_text("x = 42", encoding="utf-8")
assert venv.run(cmd).strip() == "3.14159.post0 foobar 42"The first The asymmetries that matter1. Coverage — purging removes the thing the test exercises. 2. Locatability — 3. Fidelity — the bump is the more realistic scenario, not the more artificial one. Where purge would winPurging is conceptually cleaner — it removes the confound entirely instead of adding a compensating nudge, and it can't be defeated by any future mtime-resolution weirdness. If this were a test whose subject had nothing to do with bytecode caching, "just delete the stale cache" would be the tidier fix. But that's not this test. My recommendationKeep the
The one case where I'd flip to purge: if the bump turns out flaky on some CI filesystem (coarse mtime granularity, or a mount that clamps mtime) — then removing the cache sidesteps the timestamp game entirely, at the cost of the coverage point above. |
9b62841 to
45c53ba
Compare
|
Tick the box to add this pull request to the merge queue (same as
|
Some editable-mode tests (
test_editable_with_pyproject,TestOverallBehaviour.test_editable_install) were intermittently failing on fast machines (macOS ARM64, modern Ubuntu) with strict editable installs, producing stale values after source-file modifications.Root cause: CPython stores
.pycsource mtimes as 4-byte integers (seconds). When a test rewrites a source file within the same wall-clock second that its.pycwas compiled, the stored mtime matches the current mtime and the stale bytecode is reused silently.Changes
_advance_mtime(path)— new test helper that bumps a file's mtime by 2 s viaos.utime. Two seconds (vs. one) guards against rounding at second boundaries.test_editable_with_pyproject— call_advance_mtimeonmod.pyafter the in-test write; remove@pytest.mark.xfail(sys.platform == "darwin")workaround.TestOverallBehaviour.test_editable_install— call_advance_mtimeonmod1.pyandmod2.pyafter their writes; remove the samexfail(darwin)marker.No changes to production code — the link tree in strict mode is correct; the race was purely in test timing.
Pull Request Checklist
newsfragments/.(See documentation for details)