Skip to content

Commit 4753d90

Browse files
committed
Suppress errors while removing tmpdir's lock files
Fix #5456
1 parent 0821c5c commit 4753d90

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

changelog/5456.bugfix.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a possible race condition when trying to remove lock files used to control access to folders
2+
created by ``tmp_path`` and ``tmpdir``.

src/_pytest/pathlib.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import atexit
2+
import contextlib
23
import fnmatch
34
import itertools
45
import os
@@ -290,10 +291,10 @@ def ensure_deletable(path: Path, consider_lock_dead_if_created_before: float) ->
290291
return False
291292
else:
292293
if lock_time < consider_lock_dead_if_created_before:
293-
lock.unlink()
294-
return True
295-
else:
296-
return False
294+
with contextlib.suppress(OSError):
295+
lock.unlink()
296+
return True
297+
return False
297298

298299

299300
def try_cleanup(path: Path, consider_lock_dead_if_created_before: float) -> None:

testing/test_pathlib.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import os.path
22
import sys
3+
import unittest.mock
34

45
import py
56

67
import pytest
8+
from _pytest.pathlib import ensure_deletable
79
from _pytest.pathlib import fnmatch_ex
810
from _pytest.pathlib import get_extended_length_path_str
911
from _pytest.pathlib import get_lock_path
@@ -113,3 +115,22 @@ def test_get_extended_length_path_str():
113115
assert get_extended_length_path_str(r"\\share\foo") == r"\\?\UNC\share\foo"
114116
assert get_extended_length_path_str(r"\\?\UNC\share\foo") == r"\\?\UNC\share\foo"
115117
assert get_extended_length_path_str(r"\\?\c:\foo") == r"\\?\c:\foo"
118+
119+
120+
def test_suppress_error_removing_lock(tmp_path):
121+
"""ensure_deletable should not raise an exception if the lock file cannot be removed (#5456)"""
122+
path = tmp_path / "dir"
123+
path.mkdir()
124+
lock = get_lock_path(path)
125+
lock.touch()
126+
mtime = lock.stat().st_mtime
127+
128+
with unittest.mock.patch.object(Path, "unlink", side_effect=OSError):
129+
assert not ensure_deletable(
130+
path, consider_lock_dead_if_created_before=mtime + 30
131+
)
132+
assert lock.is_file()
133+
134+
# check now that we can remove the lock file in normal circumstances
135+
assert ensure_deletable(path, consider_lock_dead_if_created_before=mtime + 30)
136+
assert not lock.is_file()

0 commit comments

Comments
 (0)