summaryrefslogtreecommitdiffstats
path: root/Lib/os.py
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2016-02-11 11:21:30 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2016-02-11 11:21:30 (GMT)
commitffe96ae10be8a3117fa18c35034fcfc45c3cf7b7 (patch)
tree8bda90834ab525f75a46f6dc26ea9adba141ffe7 /Lib/os.py
parent2feb64258558fc280f1d87bec211d83def48a9f0 (diff)
downloadcpython-ffe96ae10be8a3117fa18c35034fcfc45c3cf7b7.zip
cpython-ffe96ae10be8a3117fa18c35034fcfc45c3cf7b7.tar.gz
cpython-ffe96ae10be8a3117fa18c35034fcfc45c3cf7b7.tar.bz2
Issue #25994: Added the close() method and the support of the context manager
protocol for the os.scandir() iterator.
Diffstat (limited to 'Lib/os.py')
-rw-r--r--Lib/os.py94
1 files changed, 55 insertions, 39 deletions
diff --git a/Lib/os.py b/Lib/os.py
index 674a7d7..c3f674e 100644
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -374,46 +374,47 @@ def walk(top, topdown=True, onerror=None, followlinks=False):
onerror(error)
return
- while True:
- try:
+ with scandir_it:
+ while True:
try:
- entry = next(scandir_it)
- except StopIteration:
- break
- except OSError as error:
- if onerror is not None:
- onerror(error)
- return
-
- try:
- is_dir = entry.is_dir()
- except OSError:
- # If is_dir() raises an OSError, consider that the entry is not
- # a directory, same behaviour than os.path.isdir().
- is_dir = False
-
- if is_dir:
- dirs.append(entry.name)
- else:
- nondirs.append(entry.name)
+ try:
+ entry = next(scandir_it)
+ except StopIteration:
+ break
+ except OSError as error:
+ if onerror is not None:
+ onerror(error)
+ return
- if not topdown and is_dir:
- # Bottom-up: recurse into sub-directory, but exclude symlinks to
- # directories if followlinks is False
- if followlinks:
- walk_into = True
+ try:
+ is_dir = entry.is_dir()
+ except OSError:
+ # If is_dir() raises an OSError, consider that the entry is not
+ # a directory, same behaviour than os.path.isdir().
+ is_dir = False
+
+ if is_dir:
+ dirs.append(entry.name)
else:
- try:
- is_symlink = entry.is_symlink()
- except OSError:
- # If is_symlink() raises an OSError, consider that the
- # entry is not a symbolic link, same behaviour than
- # os.path.islink().
- is_symlink = False
- walk_into = not is_symlink
+ nondirs.append(entry.name)
- if walk_into:
- yield from walk(entry.path, topdown, onerror, followlinks)
+ if not topdown and is_dir:
+ # Bottom-up: recurse into sub-directory, but exclude symlinks to
+ # directories if followlinks is False
+ if followlinks:
+ walk_into = True
+ else:
+ try:
+ is_symlink = entry.is_symlink()
+ except OSError:
+ # If is_symlink() raises an OSError, consider that the
+ # entry is not a symbolic link, same behaviour than
+ # os.path.islink().
+ is_symlink = False
+ walk_into = not is_symlink
+
+ if walk_into:
+ yield from walk(entry.path, topdown, onerror, followlinks)
# Yield before recursion if going top down
if topdown:
@@ -437,15 +438,30 @@ class _DummyDirEntry:
def __init__(self, dir, name):
self.name = name
self.path = path.join(dir, name)
+
def is_dir(self):
return path.isdir(self.path)
+
def is_symlink(self):
return path.islink(self.path)
-def _dummy_scandir(dir):
+class _dummy_scandir:
# listdir-based implementation for bytes patches on Windows
- for name in listdir(dir):
- yield _DummyDirEntry(dir, name)
+ def __init__(self, dir):
+ self.dir = dir
+ self.it = iter(listdir(dir))
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ return _DummyDirEntry(self.dir, next(self.it))
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, *args):
+ self.it = iter(())
__all__.append("walk")