[Python-checkins] cpython: Issue #22227: The TarFile iterator is reimplemented using generator.

serhiy.storchaka python-checkins at python.org
Sat Dec 19 02:43:51 EST 2015


https://hg.python.org/cpython/rev/a8f24e26abc7
changeset:   99630:a8f24e26abc7
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Sat Dec 19 09:43:14 2015 +0200
summary:
  Issue #22227: The TarFile iterator is reimplemented using generator.
This implementation is simpler that using class.

files:
  Lib/tarfile.py |  68 ++++++++++++++-----------------------
  Misc/NEWS      |   3 +
  2 files changed, 29 insertions(+), 42 deletions(-)


diff --git a/Lib/tarfile.py b/Lib/tarfile.py
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -2372,9 +2372,32 @@
         """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 @@
             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
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -109,6 +109,9 @@
 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.
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list