]> granicus.if.org Git - python/commitdiff
Issue #22227: The TarFile iterator is reimplemented using generator.
authorSerhiy Storchaka <storchaka@gmail.com>
Sat, 19 Dec 2015 07:43:14 +0000 (09:43 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Sat, 19 Dec 2015 07:43:14 +0000 (09:43 +0200)
This implementation is simpler that using class.

Lib/tarfile.py
Misc/NEWS

index 9d22c8e37f893cf2ffd9a9de6e38b07d56476be6..80b6e35d42983f3911e30c8957b2304796f67652 100755 (executable)
@@ -2372,9 +2372,32 @@ class TarFile(object):
         """Provide an iterator object.
         """
         if self._loaded:
-            return iter(self.members)
-        else:
-            return TarIter(self)
+            yield from self.members
+            return
+
+        # Yield items using TarFile's next() method.
+        # When all members have been read, set TarFile as _loaded.
+        index = 0
+        # Fix for SF #1100429: Under rare circumstances it can
+        # happen that getmembers() is called during iteration,
+        # which will have already exhausted the next() method.
+        if self.firstmember is not None:
+            tarinfo = self.next()
+            index += 1
+            yield tarinfo
+
+        while True:
+            if index < len(self.members):
+                tarinfo = self.members[index]
+            elif not self._loaded:
+                tarinfo = self.next()
+                if not tarinfo:
+                    self._loaded = True
+                    return
+            else:
+                return
+            index += 1
+            yield tarinfo
 
     def _dbg(self, level, msg):
         """Write debugging output to sys.stderr.
@@ -2395,45 +2418,6 @@ class TarFile(object):
             if not self._extfileobj:
                 self.fileobj.close()
             self.closed = True
-# class TarFile
-
-class TarIter:
-    """Iterator Class.
-
-       for tarinfo in TarFile(...):
-           suite...
-    """
-
-    def __init__(self, tarfile):
-        """Construct a TarIter object.
-        """
-        self.tarfile = tarfile
-        self.index = 0
-    def __iter__(self):
-        """Return iterator object.
-        """
-        return self
-    def __next__(self):
-        """Return the next item using TarFile's next() method.
-           When all members have been read, set TarFile as _loaded.
-        """
-        # Fix for SF #1100429: Under rare circumstances it can
-        # happen that getmembers() is called during iteration,
-        # which will cause TarIter to stop prematurely.
-
-        if self.index == 0 and self.tarfile.firstmember is not None:
-            tarinfo = self.tarfile.next()
-        elif self.index < len(self.tarfile.members):
-            tarinfo = self.tarfile.members[self.index]
-        elif not self.tarfile._loaded:
-            tarinfo = self.tarfile.next()
-            if not tarinfo:
-                self.tarfile._loaded = True
-                raise StopIteration
-        else:
-            raise StopIteration
-        self.index += 1
-        return tarinfo
 
 #--------------------
 # exported functions
index b57dbf1d0e61aca83e61413e818a6dc894c80255..92572fa1ce3bc6ab3c61ffc737b429fad6bdaee2 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -109,6 +109,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #22227: The TarFile iterator is reimplemented using generator.
+  This implementation is simpler that using class.
+
 - Issue #25638: Optimized ElementTree.iterparse(); it is now 2x faster.
   Optimized ElementTree parsing; it is now 10% faster.