Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 12 additions & 18 deletions Lib/tarfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,21 +513,10 @@ def seek(self, pos=0):
raise StreamError("seeking backwards is not allowed")
return self.pos

def read(self, size=None):
"""Return the next size number of bytes from the stream.
If size is not defined, return all bytes of the stream
up to EOF.
"""
if size is None:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have only one question. Why this branch was removed?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This issue is follow up of bpo-34010, (GH-8020).
See also, https://bugs.python.org/issue34010#msg321040

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. Instances of _Stream are never leaked to the end user? Then this change LGTM.

@methane methane Jul 6, 2018

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be accessed via TarFile.fileobj.
But using it directly is not pragramatic, and TarFile.fileobj.read() caused TypeError because of "".join() bug.
So it must not used for previous versions.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw that the class is private, but I didn't notice that TarFile.fileobj is public. Maybe just replace the assertion with a regular if/raise, just in case? Maybe raise a NotImplementedError?

t = []
while True:
buf = self._read(self.bufsize)
if not buf:
break
t.append(buf)
buf = b"".join(t)
else:
buf = self._read(size)
def read(self, size):
"""Return the next size number of bytes from the stream."""
assert size is not None
buf = self._read(size)
self.pos += len(buf)
return buf

Expand All @@ -540,9 +529,14 @@ def _read(self, size):
c = len(self.dbuf)
t = [self.dbuf]
while c < size:
buf = self.__read(self.bufsize)
if not buf:
break
# Skip underlying buffer to avoid unaligned double buffering.
if self.buf:
buf = self.buf
self.buf = b""
else:
buf = self.fileobj.read(self.bufsize)
if not buf:
break
try:
buf = self.cmp.decompress(buf)
except self.exception:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Optimize tarfile uncompress performance about 15% when gzip is used.