Skip to content

fix: handle curdir tail in makedirs like the real os - #1371

Merged
mrbean-bremen merged 2 commits into
pytest-dev:mainfrom
rahul05ranjan:fix/makedirs-curdir-tail
Nov 10, 2026
Merged

mrbean-bremen merged 2 commits into
pytest-dev:mainfrom
rahul05ranjan:fix/makedirs-curdir-tail

Conversation

@rahul05ranjan

Copy link
Copy Markdown
Contributor

os.makedirs("foo/bar/.") on a fresh path raised FileExistsError under the fake filesystem, while the real os creates foo/bar and returns.

The curdir special case in FakeOsModule.makedirs — copied from os.py — compares the path tail against self.filesystem.cwd instead of the "." literal. With cwd usually being "/", the tail == cdir check never matches, the early return is skipped, and the final mkdir hits the directory the recursion just created:

cdir = self.filesystem.cwd   # "/" — never equals a path tail like "."

Real behavior (checked on CPython 3.13, Linux): a fresh path with a /. tail creates the directory and returns; an already-existing path with a /. tail raises EEXIST (or passes with exist_ok=True). This change restores exactly that by comparing against ".", and keeps everything else untouched.

Fixes #1370.

Verification (system Python 3.13 on a headless host, no installable deps):

  • 4 new tests in pyfakefs/tests/fake_os_test.py (fresh /. tail, existing /. tail raises EEXIST then passes with exist_ok=True, relative ./ form, bytes path): 3 fail on main@f693c54, all pass with this change. These tests run against both the fake and the real filesystem (the FakeOsModuleTest base), so the parity is pinned both ways.
  • fake_os_test.py: 556 passed / 553 skipped (Windows-only skips) with the fix.
  • Also green: fake_filesystem_test.py (295), fake_pathlib_test.py (195), fake_filesystem_vs_real_test.py (28), fake_filesystem_shutil_test.py (36).
  • fake_filesystem_unittest_test.py cannot complete on this host (OOM at ~67% of the module, identical on unpatched main — pre-existing host RAM limitation, not caused by this change).

os.makedirs("foo/bar/.") on a fresh path created foo/bar and then
raised FileExistsError, because the curdir special case copied from
os.py compared the tail against self.filesystem.cwd instead of the
"." literal. With cwd usually being "/" the comparison never
matched, the early return was skipped, and the final mkdir hit the
just-created directory.

Compare against "." (curdir), matching os.py, so a freshly created
path with a /. tail returns cleanly. An already-existing path with a
/. tail keeps raising EEXIST (or passing with exist_ok=True), the
same as the real os.

Fixes pytest-dev#1370

Co-authored-by: rahul05ranjan <11793455+rahul05ranjan@users.noreply.github.com>
Comment thread CHANGES.md
directory with a path ending in `/.` (e.g. `os.makedirs("foo/bar/.")`),
because the curdir special case compared the tail against the current
working directory instead of `"."`
(see [issue #1370](https://github.com/pytest-dev/pyfakefs/issues/1370))

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.

Please make this shorter - no need to re-iterate the reason for the issue here (e.g. just skip the "because..." part)

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.

Done in d2cba47 — dropped the "because..." sentence, the entry is now just the fix and the issue link.

@mrbean-bremen
mrbean-bremen merged commit 0679d7b into pytest-dev:main Nov 10, 2026
100 of 104 checks passed
@rahul05ranjan

Copy link
Copy Markdown
Contributor Author

Thanks for the merge on #1371 ("fix: handle curdir tail in makedirs like the real os").

I'm also exploring my next role right now (Full Stack (PHP, NodeJs, Python) / Data Science / Applied AI / Devtools, based in India) — if you or your network is hiring, I'd love an intro:
LinkedIn: https://www.linkedin.com/in/rahulswt7/ · GitHub: https://github.com/rahul05ranjan

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.

Fake os.makedirs fails on creation of directory ending with /.

2 participants