Skip to content

Commit f233d53

Browse files
Remove read-only files upon cleanup (#2501)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 2e0def4 commit f233d53

File tree

4 files changed

+38
-1
lines changed

4 files changed

+38
-1
lines changed

CONTRIBUTORS

+1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ Pierre-Jean Campigotto
107107
Pierre-Luc Tessier Gagné
108108
Prakhar Gurunani
109109
Rahul Bangar
110+
Robert Gomulka
110111
Ronald Evers
111112
Ronny Pfannschmidt
112113
Ryuichi Ohori

docs/changelog/2498.bugfix.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Remove read-only files in ``ensure_empty_dir``.

src/tox/util/path.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,26 @@
1+
import errno
2+
import os
13
import shutil
4+
import stat
25

36
from tox import reporter
47

58

69
def ensure_empty_dir(path):
710
if path.check():
811
reporter.info(" removing {}".format(path))
9-
shutil.rmtree(str(path), ignore_errors=True)
12+
shutil.rmtree(str(path), onerror=_remove_readonly)
1013
path.ensure(dir=1)
14+
15+
16+
def _remove_readonly(func, path, exc_info):
17+
"""Clear the readonly bit and reattempt the removal."""
18+
if isinstance(exc_info[1], OSError):
19+
if exc_info[1].errno == errno.EACCES:
20+
try:
21+
os.chmod(path, stat.S_IWRITE)
22+
func(path)
23+
except Exception:
24+
# when second attempt fails, ignore the problem
25+
# to maintain some level of backward compatibility
26+
pass
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import os
2+
from stat import S_IREAD
3+
4+
from tox.util.path import ensure_empty_dir
5+
6+
7+
def test_remove_read_only(tmpdir):
8+
nested_dir = tmpdir / "nested_dir"
9+
nested_dir.mkdir()
10+
11+
# create read-only file
12+
read_only_file = nested_dir / "tmpfile.txt"
13+
with open(str(read_only_file), "w"):
14+
pass
15+
os.chmod(str(read_only_file), S_IREAD)
16+
17+
ensure_empty_dir(nested_dir)
18+
19+
assert not os.listdir(str(nested_dir))

0 commit comments

Comments
 (0)