Skip to content

Commit e7c42ae

Browse files
nicoddemusbluetech
andauthored
Inaccessible lock files now imply temporary directories can't be removed
Fix #7500 Co-authored-by: Ran Benita <[email protected]>
1 parent 41c40ef commit e7c42ae

File tree

3 files changed

+20
-5
lines changed

3 files changed

+20
-5
lines changed

changelog/7491.bugfix.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:fixture:`tmpdir` and :fixture:`tmp_path` no longer raise an error if the lock to check for
2+
stale temporary directories is not accessible.

src/_pytest/pathlib.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,12 +286,17 @@ def maybe_delete_a_numbered_dir(path: Path) -> None:
286286

287287

288288
def ensure_deletable(path: Path, consider_lock_dead_if_created_before: float) -> bool:
289-
"""checks if a lock exists and breaks it if its considered dead"""
289+
"""checks if `path` is deletable based on whether the lock file is expired"""
290290
if path.is_symlink():
291291
return False
292292
lock = get_lock_path(path)
293-
if not lock.exists():
294-
return True
293+
try:
294+
if not lock.is_file():
295+
return True
296+
except OSError:
297+
# we might not have access to the lock file at all, in this case assume
298+
# we don't have access to the entire directory (#7491).
299+
return False
295300
try:
296301
lock_time = lock.stat().st_mtime
297302
except Exception:

testing/test_pathlib.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,17 +358,25 @@ def test_get_extended_length_path_str():
358358

359359

360360
def test_suppress_error_removing_lock(tmp_path):
361-
"""ensure_deletable should not raise an exception if the lock file cannot be removed (#5456)"""
361+
"""ensure_deletable should be resilient if lock file cannot be removed (#5456, #7491)"""
362362
path = tmp_path / "dir"
363363
path.mkdir()
364364
lock = get_lock_path(path)
365365
lock.touch()
366366
mtime = lock.stat().st_mtime
367367

368-
with unittest.mock.patch.object(Path, "unlink", side_effect=OSError):
368+
with unittest.mock.patch.object(Path, "unlink", side_effect=OSError) as m:
369369
assert not ensure_deletable(
370370
path, consider_lock_dead_if_created_before=mtime + 30
371371
)
372+
assert m.call_count == 1
373+
assert lock.is_file()
374+
375+
with unittest.mock.patch.object(Path, "is_file", side_effect=OSError) as m:
376+
assert not ensure_deletable(
377+
path, consider_lock_dead_if_created_before=mtime + 30
378+
)
379+
assert m.call_count == 1
372380
assert lock.is_file()
373381

374382
# check now that we can remove the lock file in normal circumstances

0 commit comments

Comments
 (0)