]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #26117: The os.scandir() iterator now closes file descriptor not only
authorSerhiy Storchaka <storchaka@gmail.com>
Mon, 8 Feb 2016 15:56:36 +0000 (17:56 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Mon, 8 Feb 2016 15:56:36 +0000 (17:56 +0200)
when the iteration is finished, but when it was failed with error.

Misc/NEWS
Modules/posixmodule.c

index 189ea311dd3b6c43a2f20d0c87f2374fb5b0b1a4..66b8d36124b59efa5fd7ee08e90a87d288881808 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -73,6 +73,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #26117: The os.scandir() iterator now closes file descriptor not only
+  when the iteration is finished, but when it was failed with error.
+
 - Issue #25911: Restored support of bytes paths in os.walk() on Windows.
 
 - Issue #26045: Add UTF-8 suggestion to error message when posting a
index e4b27a79c0e4adac34e0f97d9e4e497cacedd8c4..710bcde812934cfb4baded9e2dd272af0283cf80 100644 (file)
@@ -11942,12 +11942,11 @@ ScandirIterator_iternext(ScandirIterator *iterator)
 {
     WIN32_FIND_DATAW *file_data = &iterator->file_data;
     BOOL success;
+    PyObject *entry;
 
     /* Happens if the iterator is iterated twice */
-    if (iterator->handle == INVALID_HANDLE_VALUE) {
-        PyErr_SetNone(PyExc_StopIteration);
+    if (iterator->handle == INVALID_HANDLE_VALUE)
         return NULL;
-    }
 
     while (1) {
         if (!iterator->first_time) {
@@ -11955,9 +11954,9 @@ ScandirIterator_iternext(ScandirIterator *iterator)
             success = FindNextFileW(iterator->handle, file_data);
             Py_END_ALLOW_THREADS
             if (!success) {
+                /* Error or no more files */
                 if (GetLastError() != ERROR_NO_MORE_FILES)
-                    return path_error(&iterator->path);
-                /* No more files found in directory, stop iterating */
+                    path_error(&iterator->path);
                 break;
             }
         }
@@ -11965,15 +11964,18 @@ ScandirIterator_iternext(ScandirIterator *iterator)
 
         /* Skip over . and .. */
         if (wcscmp(file_data->cFileName, L".") != 0 &&
-                wcscmp(file_data->cFileName, L"..") != 0)
-            return DirEntry_from_find_data(&iterator->path, file_data);
+            wcscmp(file_data->cFileName, L"..") != 0) {
+            entry = DirEntry_from_find_data(&iterator->path, file_data);
+            if (!entry)
+                break;
+            return entry;
+        }
 
         /* Loop till we get a non-dot directory or finish iterating */
     }
 
+    /* Error or no more files */
     ScandirIterator_close(iterator);
-
-    PyErr_SetNone(PyExc_StopIteration);
     return NULL;
 }
 
@@ -11998,12 +12000,11 @@ ScandirIterator_iternext(ScandirIterator *iterator)
     struct dirent *direntp;
     Py_ssize_t name_len;
     int is_dot;
+    PyObject *entry;
 
     /* Happens if the iterator is iterated twice */
-    if (!iterator->dirp) {
-        PyErr_SetNone(PyExc_StopIteration);
+    if (!iterator->dirp)
         return NULL;
-    }
 
     while (1) {
         errno = 0;
@@ -12012,9 +12013,9 @@ ScandirIterator_iternext(ScandirIterator *iterator)
         Py_END_ALLOW_THREADS
 
         if (!direntp) {
+            /* Error or no more files */
             if (errno != 0)
-                return path_error(&iterator->path);
-            /* No more files found in directory, stop iterating */
+                path_error(&iterator->path);
             break;
         }
 
@@ -12023,20 +12024,22 @@ ScandirIterator_iternext(ScandirIterator *iterator)
         is_dot = direntp->d_name[0] == '.' &&
                  (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
         if (!is_dot) {
-            return DirEntry_from_posix_info(&iterator->path, direntp->d_name,
+            entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
                                             name_len, direntp->d_ino
 #ifdef HAVE_DIRENT_D_TYPE
                                             , direntp->d_type
 #endif
                                             );
+            if (!entry)
+                break;
+            return entry;
         }
 
         /* Loop till we get a non-dot directory or finish iterating */
     }
 
+    /* Error or no more files */
     ScandirIterator_close(iterator);
-
-    PyErr_SetNone(PyExc_StopIteration);
     return NULL;
 }