Skip to content

Commit d9f41fe

Browse files
author
Vasileios Karakasis
authored
Merge pull request #1548 from vkarak/bugfix/sourcesdir-indexerror
[bugfix] Fix `IndexError` crash of `osext.copytree()` when the source directory does not exist
2 parents 6d531e0 + 6c7956c commit d9f41fe

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

reframe/utility/osext.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,20 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=shutil.copy2,
156156
return shutil.copytree(src, dst, symlinks, ignore, copy_function,
157157
ignore_dangling_symlinks)
158158

159-
# dst exists; manually descend into the subdirectories
159+
# dst exists; manually descend into the subdirectories, but do some sanity
160+
# checking first
161+
162+
# We raise the following errors to comply with the copytree()'s behaviour
163+
164+
if not os.path.isdir(dst):
165+
raise FileExistsError(errno.EEXIST, 'File exists', dst)
166+
167+
if not os.path.exists(src):
168+
raise FileNotFoundError(errno.ENOENT, 'No such file or directory', src)
169+
170+
if not os.path.isdir(src):
171+
raise NotADirectoryError(errno.ENOTDIR, 'Not a directory', src)
172+
160173
_, subdirs, files = list(os.walk(src))[0]
161174
ignore_paths = ignore(src, os.listdir(src)) if ignore else {}
162175
for f in files:

unittests/test_utility.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,37 @@ def test_copytree_src_parent_of_dst(tmp_path):
8080
osext.copytree(str(src_path), str(dst_path))
8181

8282

83+
@pytest.fixture(params=['dirs_exist_ok=True', 'dirs_exist_ok=False'])
84+
def dirs_exist_ok(request):
85+
return 'True' in request.param
86+
87+
88+
def test_copytree_dst_notdir(tmp_path, dirs_exist_ok):
89+
dir_src = tmp_path / 'src'
90+
dir_src.mkdir()
91+
dst = tmp_path / 'dst'
92+
dst.touch()
93+
with pytest.raises(FileExistsError, match=fr'{dst}'):
94+
osext.copytree(str(dir_src), str(dst), dirs_exist_ok=dirs_exist_ok)
95+
96+
97+
def test_copytree_src_notdir(tmp_path, dirs_exist_ok):
98+
src = tmp_path / 'src'
99+
src.touch()
100+
dst = tmp_path / 'dst'
101+
dst.mkdir()
102+
with pytest.raises(NotADirectoryError, match=fr'{src}'):
103+
osext.copytree(str(src), str(dst), dirs_exist_ok=dirs_exist_ok)
104+
105+
106+
def test_copytree_src_does_not_exist(tmp_path, dirs_exist_ok):
107+
src = tmp_path / 'src'
108+
dst = tmp_path / 'dst'
109+
dst.mkdir()
110+
with pytest.raises(FileNotFoundError, match=fr'{src}'):
111+
osext.copytree(str(src), str(dst), dirs_exist_ok=dirs_exist_ok)
112+
113+
83114
@pytest.fixture
84115
def rmtree(tmp_path):
85116
testdir = tmp_path / 'test'

0 commit comments

Comments
 (0)