Skip to content

fix: raise FileNotFoundError from place_*_file on a missing drive - #639

Open
nk-batman21 wants to merge 1 commit into
tox-dev:mainfrom
nk-batman21:fix/place-file-missing-root
Open

nk-batman21 wants to merge 1 commit into
tox-dev:mainfrom
nk-batman21:fix/place-file-missing-root

Conversation

@nk-batman21

Copy link
Copy Markdown

place_config_file() and the other place_*_file methods create missing parent directories through _make_private_directories, which retries with path.parent whenever mkdir raises FileNotFoundError. When the root itself is missing, as with an unmounted drive letter or an unreachable network share on Windows, the root is its own parent, so the helper keeps calling itself until Python raises RecursionError.

To reproduce on Windows, set WIN_PD_OVERRIDE_LOCAL_APPDATA=Z:\AppData\Local with no Z: drive (the docs suggest these overrides for keeping large data on another drive) and call PlatformDirs("MyApp", "Acme").place_config_file("settings.toml"). On main this raises RecursionError: maximum recursion depth exceeded, while ensure_exists=True on the same setup raises FileNotFoundError: [WinError 3] ... 'Z:\\'. A roaming profile pointing at \\localhost\no-such-share\AppData\Roaming fails the same way. RecursionError is not an OSError, so code that handles directory creation failures with except OSError crashes, and the traceback never names the missing path.

The change re-raises the FileNotFoundError once the path is its own parent, the same check Path.mkdir(parents=True) makes. Both examples now raise FileNotFoundError ([WinError 3] for the drive, [WinError 67] for the share).

Ran: tox -e 3.14 on Windows (2042 passed, 350 skipped, diff coverage 100%) and pytest tests/test_api.py on Linux (Python 3.12). The new test fails on main with RecursionError and passes with the fix.
Ran: the drive and share examples above, before and after the change.
Checked: the ruff, codespell and docstrfmt pre-commit hooks, tox -e type and towncrier check.

_make_private_directories retried with path.parent on FileNotFoundError
without stopping at the root. On Windows a missing drive or network share
fails at its root, which is its own parent, so place_*_file ended in
RecursionError instead of the FileNotFoundError that Path.mkdir(parents=True)
and ensure_exists raise for the same path.

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