cacheprovider: fix "Directory not empty" crash from cache directory creation
Fix #12381 Test plan: It's possible to write a deterministic test case for this, but somewhat of a hassle so I tested it manually. I reproduced by removing existing `.pytest_cache`, adding a sleep before the rename and running two pytests. I verified that it doesn't reproduce after the fix.
This commit is contained in:
parent
98021838fd
commit
17065cb008
|
@ -0,0 +1 @@
|
||||||
|
Fix possible "Directory not empty" crashes arising from concurent cache dir (``.pytest_cache``) creation. Regressed in pytest 8.2.0.
|
|
@ -4,6 +4,7 @@
|
||||||
# This plugin was not named "cache" to avoid conflicts with the external
|
# This plugin was not named "cache" to avoid conflicts with the external
|
||||||
# pytest-cache version.
|
# pytest-cache version.
|
||||||
import dataclasses
|
import dataclasses
|
||||||
|
import errno
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
@ -227,14 +228,24 @@ class Cache:
|
||||||
with open(path.joinpath("CACHEDIR.TAG"), "xb") as f:
|
with open(path.joinpath("CACHEDIR.TAG"), "xb") as f:
|
||||||
f.write(CACHEDIR_TAG_CONTENT)
|
f.write(CACHEDIR_TAG_CONTENT)
|
||||||
|
|
||||||
path.rename(self._cachedir)
|
try:
|
||||||
# Create a directory in place of the one we just moved so that `TemporaryDirectory`'s
|
path.rename(self._cachedir)
|
||||||
# cleanup doesn't complain.
|
except OSError as e:
|
||||||
#
|
# If 2 concurrent pytests both race to the rename, the loser
|
||||||
# TODO: pass ignore_cleanup_errors=True when we no longer support python < 3.10. See
|
# gets "Directory not empty" from the rename. In this case,
|
||||||
# https://github.com/python/cpython/issues/74168. Note that passing delete=False would
|
# everything is handled so just continue (while letting the
|
||||||
# do the wrong thing in case of errors and isn't supported until python 3.12.
|
# temporary directory be cleaned up).
|
||||||
path.mkdir()
|
if e.errno != errno.ENOTEMPTY:
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
# Create a directory in place of the one we just moved so that
|
||||||
|
# `TemporaryDirectory`'s cleanup doesn't complain.
|
||||||
|
#
|
||||||
|
# TODO: pass ignore_cleanup_errors=True when we no longer support python < 3.10.
|
||||||
|
# See https://github.com/python/cpython/issues/74168. Note that passing
|
||||||
|
# delete=False would do the wrong thing in case of errors and isn't supported
|
||||||
|
# until python 3.12.
|
||||||
|
path.mkdir()
|
||||||
|
|
||||||
|
|
||||||
class LFPluginCollWrapper:
|
class LFPluginCollWrapper:
|
||||||
|
|
Loading…
Reference in New Issue