Skip to content

Preserve real POSIX path cache semantics across patching - #1360

Open
sunxiuguo wants to merge 1 commit into
pytest-dev:mainfrom
sunxiuguo:fix-real-path-cache-1359
Open

sunxiuguo wants to merge 1 commit into
pytest-dev:mainfrom
sunxiuguo:fix-real-path-cache-1359

Conversation

@sunxiuguo

Copy link
Copy Markdown

Describe the changes

Addresses #1359.

Keep the original posixpath reference in pathlib and pathlib._local. Python 3.13+ uses that reference as an identity marker when computing a real path's normalized case. Replacing it makes a real POSIX path cache a lowercase value even though its parser remains the original module.

This fixes the cache contamination in both orders: a real path first used inside a fake filesystem, and a path cached before patching whose children are created during patching. It preserves equality, hashes, dictionary lookup, parents and relative_to between real paths across pause/resume, teardown and subsequent sessions.

The guard is restricted to these two stdlib modules. Other modules' posixpath imports remain patched, and existing real paths still use the fake filesystem for operations such as iterdir(). It does not rewrite original parser classes, clear arbitrary object caches or change fake/real class equality.

Scope limitation

The report's exact reverse-order example also compares the real path returned by relative_to with a newly created fake Path("src"). That final mixed real/fake equality remains false because their parser identities differ. An independent lowercase-only probe reproduces this on both unchanged main and this patch, on Python 3.12 and 3.13, without cache contamination.

The two exact reported pytest examples therefore improve from 2 passed / 2 failed to 3 passed / 1 failed on Python 3.13: the original relative_to exception is resolved, but the mixed-type comparison remains. Comparing with type(ROOT)("src") instead makes all four tests pass. This PR deliberately does not claim to resolve that separate equality behavior or automatically close the issue.

Validation

Against main 45d460c7b93ffd0ddfb29e37b5f7e0930f7c91e4, on Linux:

  • Five added regression methods pass on CPython 3.12.14 and 3.13.5. They include 12 fake-OS/cache-order combinations, real-path directory iteration, pause/resume, repeated sessions, unchanged real Windows-path case behavior, and ordinary posixpath patch/restoration.
  • The same regression tests against unmodified main on 3.13 produce 13 assertion failures and the reported relative_to ValueError; the two compatibility tests pass.
  • python -bb -m pyfakefs.tests.all_tests: Python 3.12 runs 2,503 tests, OK (1,045 skipped, 2 expected failures); Python 3.13 runs 2,499 tests, OK (1,039 skipped, 2 expected failures).
  • Existing pytest suite with pytest 9.1.1 on Python 3.13: 33 passed, 3 skipped, 2 xpassed. The pyfakefs plugin was loaded explicitly; unrelated auto-loaded plugins were disabled.
  • Changed-file Ruff 0.17.1 lint and format checks pass.
  • A separate review independently checked 36 real-path configurations across four lifecycle stages on each of 3.12 and 3.13, plus fake file reads/writes/glob and the exact integrated regressions.
  • Official CPython 3.14.0 source has the same identity check, but no local Python 3.14 runtime was available. Native Windows/macOS, other Python versions, optional-package and real-filesystem CI configurations, and the complete pre-commit hook set remain for CI.

Tasks

  • Unit tests added that reproduce the issue or prove feature is working
  • Fix or feature added
  • Entry to release notes added
  • Pre-commit CI shows no errors (local Ruff checks pass; CI pending)
  • Unit tests passing in CI (local results and limits above)
  • For documentation changes: The Read the Docs preview builds and looks as expected (not applicable)

AI assistance: this patch and its tests were developed with OpenAI Codex. A separate Codex review independently executed the regression and compatibility probes described above.

Keep pathlib's posixpath identity marker unchanged while other module imports remain faked. Add lifecycle, cache-order and fake-I/O regressions for pytest-dev#1359.

This branch has not been deployed

No deployments
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.

1 participant