optimize scantree

This commit is contained in:
Prinz23 2023-10-28 09:49:16 +02:00
parent 67d73fa401
commit 54765a5432

View file

@ -1084,7 +1084,11 @@ def scantree(path, # type: AnyStr
follow_symlinks=False, # type: bool
filter_kind=None, # type: Optional[bool]
recurse=True, # type: bool
exclude_folders_with_files=None # type: Optional[List[AnyStr]]
exclude_folders_with_files=None, # type: Optional[List[AnyStr]]
internal_call=False, # type: bool
rc_exc=None, # type: List
rc_exc_dir=None, # type: List
rc_inc=None # type: List
):
# type: (...) -> Generator[DirEntry, None, None]
"""Yield DirEntry objects for given path. Returns without yield if path fails sanity check
@ -1097,19 +1101,24 @@ def scantree(path, # type: AnyStr
:param filter_kind: None to yield everything, True yields directories, False yields files
:param recurse: Recursively scan the tree
:param exclude_folders_with_files: exclude folder that contain the listed file(s)
:param internal_call: internal use
:param rc_exc: internal use
:param rc_exc_dir: internal use
:param rc_inc: internal use
"""
if isinstance(path, string_types) and path and os.path.isdir(path):
rc_exc, rc_exc_dir, rc_inc = [re.compile(rx % '|'.join(
[x for x in (param, ([param], [])[None is param])[not isinstance(param, list)]]))
for rx, param in ((r'(?i)^(?:(?!%s).)*$', exclude), (r'(?i)^(?:(?!%s).)*$', exclude_dirs),
(r'(?i)%s', include))]
if not internal_call:
rc_exc, rc_exc_dir, rc_inc = [re.compile(rx % '|'.join(
[x for x in (param, ([param], [])[None is param])[not isinstance(param, list)]]))
for rx, param in ((r'(?i)^(?:(?!%s).)*$', exclude), (r'(?i)^(?:(?!%s).)*$', exclude_dirs),
(r'(?i)%s', include))]
for entry in scandir(path):
is_dir = entry.is_dir(follow_symlinks=follow_symlinks)
is_file = entry.is_file(follow_symlinks=follow_symlinks)
no_filter = any([None is filter_kind, filter_kind and is_dir, not filter_kind and is_file])
if ((rc_exc.search(entry.name), True)[not exclude]
and (rc_exc_dir.search(entry.name), True)[not exclude_dirs or not is_dir]
and (rc_inc.search(entry.name), True)[not include]
if ((not exclude or rc_exc.search(entry.name))
and (not exclude_dirs or not is_dir or rc_exc_dir.search(entry.name))
and (not include or rc_inc.search(entry.name))
and (no_filter or (not filter_kind and is_dir and recurse))):
if is_dir and exclude_folders_with_files and any(os.path.isfile(os.path.join(entry.path, e_f))
for e_f in exclude_folders_with_files):
@ -1117,8 +1126,11 @@ def scantree(path, # type: AnyStr
f' "{", ".join(exclude_folders_with_files)}"')
continue
if recurse and is_dir:
for subentry in scantree(entry.path, exclude, exclude_dirs, include, follow_symlinks, filter_kind,
recurse):
for subentry in scantree(
path=entry.path, exclude=exclude, exclude_dirs=exclude_dirs, include=include,
follow_symlinks=follow_symlinks, filter_kind=filter_kind, recurse=recurse,
exclude_folders_with_files=exclude_folders_with_files, internal_call=True,
rc_exc=rc_exc, rc_exc_dir=rc_exc_dir, rc_inc=rc_inc):
yield subentry
if no_filter:
yield entry