diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2015-12-19 07:43:14 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2015-12-19 07:43:14 (GMT) |
commit | a254921cd4c1ca22d725872601292c48b7caa20a (patch) | |
tree | 6ebe6c4d0b724b2716221bb40e79247a5b41653e | |
parent | de20bad224c61ee68f09bd4281b6bdf5fcac5e1c (diff) | |
download | cpython-a254921cd4c1ca22d725872601292c48b7caa20a.zip cpython-a254921cd4c1ca22d725872601292c48b7caa20a.tar.gz cpython-a254921cd4c1ca22d725872601292c48b7caa20a.tar.bz2 |
Issue #22227: The TarFile iterator is reimplemented using generator.
This implementation is simpler that using class.
-rwxr-xr-x | Lib/tarfile.py | 68 | ||||
-rw-r--r-- | Misc/NEWS | 3 |
2 files changed, 29 insertions, 42 deletions
diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 9d22c8e..80b6e35 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -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 @@ -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. |