Skip to content

Commit

Permalink
Fix access denied error when deleting a stale temporary directory
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoddemus committed Oct 30, 2018
1 parent e6e40db commit 5384436
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 6 deletions.
1 change: 1 addition & 0 deletions changelog/4262.bugfix.rst
@@ -0,0 +1 @@
Fix access denied error when deleting stale directories created by ``tmpdir`` / ``tmp_path``.
13 changes: 7 additions & 6 deletions src/_pytest/pathlib.py
Expand Up @@ -186,19 +186,20 @@ def cleanup_on_exit(lock_path=lock_path, original_pid=pid):


def maybe_delete_a_numbered_dir(path):
"""removes a numbered directory if its lock can be obtained"""
"""removes a numbered directory if its lock can be obtained and it does not seem to be in use"""
try:
create_cleanup_lock(path)
parent = path.parent

garbage = parent.joinpath("garbage-{}".format(uuid.uuid4()))
path.rename(garbage)
rmtree(garbage, force=True)
except (OSError, EnvironmentError):
# known races:
# * other process did a cleanup at the same time
# * deletable folder was found
# * process cwd (Windows)
return
parent = path.parent

garbage = parent.joinpath("garbage-{}".format(uuid.uuid4()))
path.rename(garbage)
rmtree(garbage, force=True)


def ensure_deletable(path, consider_lock_dead_if_created_before):
Expand Down
15 changes: 15 additions & 0 deletions testing/test_paths.py → testing/test_pathlib.py
Expand Up @@ -4,6 +4,8 @@

import pytest
from _pytest.pathlib import fnmatch_ex
from _pytest.pathlib import maybe_delete_a_numbered_dir
from _pytest.pathlib import Path


class TestPort:
Expand Down Expand Up @@ -66,3 +68,16 @@ def test_matching(self, match, pattern, path):
)
def test_not_matching(self, match, pattern, path):
assert not match(pattern, path)


def test_access_denied_during_cleanup(tmp_path, monkeypatch):
"""Ensure that deleting a numbered dir does not fail because of OSErrors (#4262)."""
path = tmp_path / "temp-1"
path.mkdir()

def renamed_failed(*args):
raise OSError("access denied")

monkeypatch.setattr(Path, "rename", renamed_failed)

maybe_delete_a_numbered_dir(path)

0 comments on commit 5384436

Please sign in to comment.