Issue #22227: The TarFile iterator is reimplemented using generator.
This implementation is simpler that using class.
This commit is contained in:
parent
de20bad224
commit
a254921cd4
|
@ -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.
|
||||
|
||||
|
|
Loading…
Reference in New Issue