Skip to content

Commit 39fe883

Browse files
committed
Use scandir if available
1 parent 1efaf2b commit 39fe883

3 files changed

Lines changed: 36 additions & 10 deletions

File tree

CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,7 @@
100100

101101
0.5.3:
102102

103+
* Implemented scandir in listdir if available
104+
103105

104106

fs/base.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,14 +1008,14 @@ def listdir(path, *args, **kwargs):
10081008
paths = []
10091009
paths_append = paths.append
10101010
try:
1011-
for filename in listdir(current_path):
1011+
for filename in listdir(current_path, dirs_only=True):
10121012
path = pathcombine(current_path, filename)
1013-
if isdir(path):
1014-
if dir_wildcard(path):
1015-
dirs_append(path)
1016-
else:
1017-
if wildcard(filename):
1018-
paths_append(filename)
1013+
if dir_wildcard(path):
1014+
dirs_append(path)
1015+
for filename in listdir(current_path, files_only=True):
1016+
path = pathcombine(current_path, filename)
1017+
if wildcard(filename):
1018+
paths_append(filename)
10191019
except ResourceNotFoundError:
10201020
# Could happen if another thread / process deletes something whilst we are walking
10211021
pass

fs/osfs/__init__.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@
2323
import io
2424
import shutil
2525

26+
scandir = None
27+
try:
28+
scandir = os.scandir
29+
except AttributeError:
30+
try:
31+
from scandir import scandir
32+
except ImportError:
33+
pass
34+
2635
from fs.base import *
2736
from fs.path import *
2837
from fs.errors import *
@@ -248,9 +257,24 @@ def isfile(self, path):
248257
def listdir(self, path="./", wildcard=None, full=False, absolute=False, dirs_only=False, files_only=False):
249258
_decode_path = self._decode_path
250259
sys_path = self.getsyspath(path)
251-
listing = os.listdir(sys_path)
252-
paths = [_decode_path(p) for p in listing]
253-
return self._listdir_helper(path, paths, wildcard, full, absolute, dirs_only, files_only)
260+
261+
if scandir is None:
262+
listing = os.listdir(sys_path)
263+
paths = [_decode_path(p) for p in listing]
264+
return self._listdir_helper(path, paths, wildcard, full, absolute, dirs_only, files_only)
265+
else:
266+
if dirs_only and files_only:
267+
raise ValueError("dirs_only and files_only can not both be True")
268+
# Use optimized scandir if present
269+
scan = scandir(sys_path)
270+
if dirs_only:
271+
paths = [_decode_path(dir_entry.name) for dir_entry in scan if dir_entry.is_dir()]
272+
elif files_only:
273+
paths = [_decode_path(dir_entry.name) for dir_entry in scan if dir_entry.is_file()]
274+
else:
275+
paths = [_decode_path(dir_entry.name) for dir_entry in scan]
276+
277+
return self._listdir_helper(path, paths, wildcard, full, absolute, False, False)
254278

255279
@convert_os_errors
256280
def makedir(self, path, recursive=False, allow_recreate=False):

0 commit comments

Comments
 (0)