Skip to content

Commit 67a8ce9

Browse files
committed
Patch OSFS.scandir so it properly closes the scandir iterator
1 parent b88f432 commit 67a8ce9

File tree

2 files changed

+46
-32
lines changed

2 files changed

+46
-32
lines changed

fs/osfs.py

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -483,39 +483,44 @@ def _scandir(self, path, namespaces=None):
483483
else:
484484
sys_path = self._to_sys_path(_path) # type: ignore
485485
with convert_os_errors("scandir", path, directory=True):
486-
for dir_entry in scandir(sys_path):
487-
info = {
488-
"basic": {
489-
"name": fsdecode(dir_entry.name),
490-
"is_dir": dir_entry.is_dir(),
491-
}
492-
}
493-
if "details" in namespaces:
494-
stat_result = dir_entry.stat()
495-
info["details"] = self._make_details_from_stat(stat_result)
496-
if "stat" in namespaces:
497-
stat_result = dir_entry.stat()
498-
info["stat"] = {
499-
k: getattr(stat_result, k)
500-
for k in dir(stat_result)
501-
if k.startswith("st_")
502-
}
503-
if "lstat" in namespaces:
504-
lstat_result = dir_entry.stat(follow_symlinks=False)
505-
info["lstat"] = {
506-
k: getattr(lstat_result, k)
507-
for k in dir(lstat_result)
508-
if k.startswith("st_")
486+
scandir_iter = scandir(sys_path)
487+
try:
488+
for dir_entry in scandir_iter:
489+
info = {
490+
"basic": {
491+
"name": fsdecode(dir_entry.name),
492+
"is_dir": dir_entry.is_dir(),
493+
}
509494
}
510-
if "link" in namespaces:
511-
info["link"] = self._make_link_info(
512-
os.path.join(sys_path, dir_entry.name)
513-
)
514-
if "access" in namespaces:
515-
stat_result = dir_entry.stat()
516-
info["access"] = self._make_access_from_stat(stat_result)
517-
518-
yield Info(info)
495+
if "details" in namespaces:
496+
stat_result = dir_entry.stat()
497+
info["details"] = self._make_details_from_stat(stat_result)
498+
if "stat" in namespaces:
499+
stat_result = dir_entry.stat()
500+
info["stat"] = {
501+
k: getattr(stat_result, k)
502+
for k in dir(stat_result)
503+
if k.startswith("st_")
504+
}
505+
if "lstat" in namespaces:
506+
lstat_result = dir_entry.stat(follow_symlinks=False)
507+
info["lstat"] = {
508+
k: getattr(lstat_result, k)
509+
for k in dir(lstat_result)
510+
if k.startswith("st_")
511+
}
512+
if "link" in namespaces:
513+
info["link"] = self._make_link_info(
514+
os.path.join(sys_path, dir_entry.name)
515+
)
516+
if "access" in namespaces:
517+
stat_result = dir_entry.stat()
518+
info["access"] = self._make_access_from_stat(stat_result)
519+
520+
yield Info(info)
521+
finally:
522+
if sys.version_info >= (3, 6):
523+
scandir_iter.close()
519524

520525
else:
521526

tests/test_osfs.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import tempfile
99
import sys
1010
import unittest
11+
import warnings
1112

1213
from fs import osfs, open_fs
1314
from fs.path import relpath, dirname
@@ -25,6 +26,14 @@
2526
class TestOSFS(FSTestCases, unittest.TestCase):
2627
"""Test OSFS implementation."""
2728

29+
@classmethod
30+
def setUpClass(cls):
31+
warnings.simplefilter("error")
32+
33+
@classmethod
34+
def tearDownClass(cls):
35+
warnings.simplefilter(warnings.defaultaction)
36+
2837
def make_fs(self):
2938
temp_dir = tempfile.mkdtemp("fstestosfs")
3039
return osfs.OSFS(temp_dir)

0 commit comments

Comments
 (0)