Unverified Commit 1bc80610 authored by Xintao's avatar Xintao Committed by GitHub
Browse files

support recursive scanndir (#215)

* recursive scanndir

* support python3.5

* update and add tests

* resolve comments

* remove is_str
parent fa84b264
...@@ -38,17 +38,45 @@ def symlink(src, dst, overwrite=True, **kwargs): ...@@ -38,17 +38,45 @@ def symlink(src, dst, overwrite=True, **kwargs):
os.symlink(src, dst, **kwargs) os.symlink(src, dst, **kwargs)
def scandir(dir_path, suffix=None): def scandir(dir_path, suffix=None, recursive=False):
"""Scan a directory to find the interested files.
Args:
dir_path (str | obj:`Path`): Path of the directory.
suffix (str | tuple(str), optional): File suffix that we are
interested in. Default: None.
recursive (bool, optional): If set to True, recursively scan the
directory. Default: False.
Returns:
A generator for all the interested files with relative pathes.
"""
if isinstance(dir_path, (str, Path)):
dir_path = str(dir_path)
else:
raise TypeError('"dir_path" must be a string or Path object')
if (suffix is not None) and not isinstance(suffix, (str, tuple)): if (suffix is not None) and not isinstance(suffix, (str, tuple)):
raise TypeError('"suffix" must be a string or tuple of strings') raise TypeError('"suffix" must be a string or tuple of strings')
for entry in os.scandir(dir_path):
if not entry.is_file(): root = dir_path
continue
filename = entry.name def _scandir(dir_path, suffix, recursive):
if suffix is None: for entry in os.scandir(dir_path):
yield filename if not entry.name.startswith('.') and entry.is_file():
elif filename.endswith(suffix): rel_path = osp.relpath(entry.path, root)
yield filename if suffix is None:
yield rel_path
elif rel_path.endswith(suffix):
yield rel_path
else:
if recursive:
yield from _scandir(
entry.path, suffix=suffix, recursive=recursive)
else:
continue
return _scandir(dir_path, suffix=suffix, recursive=recursive)
def find_vcs_root(path, markers=('.git', )): def find_vcs_root(path, markers=('.git', )):
......
...@@ -28,8 +28,8 @@ def test_check_file_exist(): ...@@ -28,8 +28,8 @@ def test_check_file_exist():
def test_scandir(): def test_scandir():
folder = osp.join(osp.dirname(__file__), 'data/for_scan') folder = osp.join(osp.dirname(__file__), 'data/for_scan')
filenames = ['a.bin', '1.txt', '2.txt', '1.json', '2.json'] filenames = ['a.bin', '1.txt', '2.txt', '1.json', '2.json']
assert set(mmcv.scandir(folder)) == set(filenames) assert set(mmcv.scandir(folder)) == set(filenames)
assert set(mmcv.scandir(Path(folder))) == set(filenames)
assert set(mmcv.scandir(folder, '.txt')) == set( assert set(mmcv.scandir(folder, '.txt')) == set(
[filename for filename in filenames if filename.endswith('.txt')]) [filename for filename in filenames if filename.endswith('.txt')])
assert set(mmcv.scandir(folder, ('.json', '.txt'))) == set([ assert set(mmcv.scandir(folder, ('.json', '.txt'))) == set([
...@@ -37,5 +37,20 @@ def test_scandir(): ...@@ -37,5 +37,20 @@ def test_scandir():
if filename.endswith(('.txt', '.json')) if filename.endswith(('.txt', '.json'))
]) ])
assert set(mmcv.scandir(folder, '.png')) == set() assert set(mmcv.scandir(folder, '.png')) == set()
filenames_recursive = [
'a.bin', '1.txt', '2.txt', '1.json', '2.json', 'sub/1.json',
'sub/1.txt'
]
assert set(mmcv.scandir(folder,
recursive=True)) == set(filenames_recursive)
assert set(mmcv.scandir(Path(folder),
recursive=True)) == set(filenames_recursive)
assert set(mmcv.scandir(folder, '.txt', recursive=True)) == set([
filename for filename in filenames_recursive
if filename.endswith('.txt')
])
with pytest.raises(TypeError):
list(mmcv.scandir(123))
with pytest.raises(TypeError): with pytest.raises(TypeError):
list(mmcv.scandir(folder, 111)) list(mmcv.scandir(folder, 111))
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment