Skip to content

Fix pathlib glob case sensitivity under macOS simulation - #1351

Merged
mrbean-bremen merged 2 commits into
pytest-dev:mainfrom
anshurajbisoyi98-ctrl:fix-1347-macos-pathlib-glob
Oct 18, 2026
Merged

mrbean-bremen merged 2 commits into
pytest-dev:mainfrom
anshurajbisoyi98-ctrl:fix-1347-macos-pathlib-glob

Conversation

@anshurajbisoyi98-ctrl

@anshurajbisoyi98-ctrl anshurajbisoyi98-ctrl commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Describe the changes

Fixes #1347.

Since Python 3.13, Path.glob() without case_sensitive matches wildcards case-sensitively under Posix but looks up literal parts in the filesystem, so on macOS glob("b.txt") finds B.TXT while glob("*.txt") doesn't. The pyfakefs override for 3.14 always passed case_sensitive=True, which disabled that lookup. It now follows CPython's default code path when no argument is given; explicit arguments are unchanged. The new tests run against both the fake and the real filesystem.

Also adapts the fake os.path.realpath() to Python 3.13.16/3.14.8 (CPython gh-102475): under Windows, a path relative to another drive now resolves against that drive's root (x:test -> X:\test), which made test_resolve_relative_windows_path_with_invalid_drive fail on the current Windows runners.

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
  • Unit tests passing
  • For documentation changes: The Read the Docs preview builds and looks as expected

Verification

  • The new glob test fails with the code from main and passes with the fix.
  • Real macOS (Python 3.13 and 3.14): glob("b.txt") finds B.TXT; glob("*.txt") and glob("b.txt", case_sensitive=True) don't.
  • CI: the Windows real-fs test passes on 3.13.16 (new behavior) and 3.14.7 (old behavior).

AI assistance

Codex assisted with investigation and generated the implementation,
regression tests, changelog and performed focused verification; I ran the broader test suites listed above.

Comment thread pyfakefs/tests/fake_pathlib_test.py Outdated

def test_glob_case_posix(self):
self.check_posix_only()
self.check_case_sensitive_fs()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This just disables the real OS test for macOS - if it doesn't pass in the real fs, it it is probably not the correct fix. I'm not yet convinced that the behavior is wrong anyway.

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.

You’re right, disabling the real-fs test was wrong. It hid the fact that my change made wildcard matching case-insensitive, which real pathlib doesn’t do on macOS.

I’ve removed that line, so test_glob_case_posix runs against the real filesystem on macOS again, and it passes with the reworked fix.

On whether the behavior is wrong: I checked on a real macOS filesystem (Python 3.14.8). There, Path.glob("b.txt") finds B.TXT, because CPython looks up literal pattern parts in the filesystem, while glob("*.txt") doesn’t match it. pyfakefs under macOS simulation currently returns nothing for glob("b.txt"), so it differs from the real OS for literal patterns only. The new tests check this against both the real and the fake filesystem, and they pass on both.

Comment thread pyfakefs/tests/fake_pathlib_test.py Outdated
return True


@unittest.skipIf(sys.version_info < (3, 14), "Python 3.14 glob implementation")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So what has changed in the glob implementation in Python 3.14? I didn't find anything in the documentation.
Also again, this only tests the fake fs.

@anshurajbisoyi98-ctrl anshurajbisoyi98-ctrl Oct 15, 2026 •

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.

Correction: the literal lookup has existed since 3.13 (case_pedantic=False when case_sensitive isn't given). What changed in 3.14 is the default detection: it checks self.parser is posixpath, which is false for the fake module. pyfakefs therefore overrides glob() for 3.14 and passed case_sensitive=True, which also disabled the literal lookup, so the problem only shows up in 3.14. The fix follows the default code path when no argument is given.

I removed the fake-only test class; the new tests now run against both the fake and the real fs.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks - that sounds good! I will have a closer look hopefully at the weekend, a bit full at the moment (and also caught a cold).

@mrbean-bremen mrbean-bremen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for taking the time to investigate this! That explains why I haven't seen the issue, but is also a quite unexpected behavior. I've thought about how to handle this in a cleaner way, but didn't come up with anything really better, so your fix seems fine to me.

Since Python 3.13, Path.glob() without an explicit case_sensitive
argument matches wildcard parts case-sensitively under Posix, but checks
literal pattern parts by looking them up in the filesystem
(case_pedantic=False), so they are found in a case-insensitive
filesystem like macOS.
Python 3.13.16 and 3.14.8 changed os.path.realpath under Windows to
use abspath() for relative paths (CPython gh-102475, also in 3.15.1).
A path relative to a drive other than the current one is now resolved
against the root of that drive, e.g. "x:test" becomes "X:\test".

This made test_resolve_relative_windows_path_with_invalid_drive fail
for the real filesystem on the current Windows CI runners. Emulate the
new behavior in the fake os.path.realpath for these versions and adapt
the test expectation.

Signed-off-by: anshurajbisoyi98-ctrl <anshurajbisoyi98@gmail.com>
@mrbean-bremen
mrbean-bremen force-pushed the fix-1347-macos-pathlib-glob branch from fa3a42a to 05e5419 Compare October 18, 2026 07:23
@mrbean-bremen
mrbean-bremen merged commit 231a76d into pytest-dev:main Oct 18, 2026
104 checks passed
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.

Path.glob doesn't find a file whose name differs only in case from a literal pattern under macOS simulation

2 participants