8000 Update gzip & tarfile & xmlrpc & pydoc + associated tests to 3.12.7 by arihant2math · Pull Request #5480 · RustPython/RustPython · GitHub
[go: up one dir, main page]

Skip to content

Update gzip & tarfile & xmlrpc & pydoc + associated tests to 3.12.7 #5480

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter 8000

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
82 changes: 54 additions & 28 deletions Lib/gzip.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
_COMPRESS_LEVEL_TRADEOFF = 6
_COMPRESS_LEVEL_BEST = 9

READ_BUFFER_SIZE = 128 * 1024
_WRITE_BUFFER_SIZE = 4 * io.DEFAULT_BUFFER_SIZE


def open(filename, mode="rb", compresslevel=_COMPRESS_LEVEL_BEST,
encoding=None, errors=None, newline=None):
Expand Down Expand Up @@ -94,7 +97,7 @@ def read(self, size):
read = self._read
self._read = None
return self._buffer[read:] + \
self.file.read(size-self._length+read)
self.file.read(size-self._length+read)

def prepend(self, prepend=b''):
if self._read is None:
Expand All @@ -118,6 +121,21 @@ class BadGzipFile(OSError):
"""Exception raised in some cases for invalid gzip files."""


class _WriteBufferStream(io.RawIOBase):
"""Minimal object to pass WriteBuffer flushes into GzipFile"""
def __init__(self, gzip_file):
self.gzip_file = gzip_file

def write(self, data):
return self.gzip_file._write_raw(data)

def seekable(self):
return False

def writable(self):
return True


class GzipFile(_compression.BaseStream):
"""The GzipFile class simulates most of the methods of a file object with
the exception of the truncate() method.
Expand Down Expand Up @@ -182,6 +200,7 @@ def __init__(self, filename=None, mode=None,
if mode is None:
mode = getattr(fileobj, 'mode', 'rb')


if mode.startswith('r'):
self.mode = READ
raw = _GzipReader(fileobj)
Expand All @@ -204,6 +223,9 @@ def __init__(self, filename=None, mode=None,
zlib.DEF_MEM_LEVEL,
0)
self._write_mtime = mtime
self._buffer_size = _WRITE_BUFFER_SIZE
self._buffer = io.BufferedWriter(_WriteBufferStream(self),
buffer_size=self._buffer_size)
else:
raise ValueError("Invalid mode: {!r}".format(mode))

Expand All @@ -212,14 +234,6 @@ def __init__(self, filename=None, mode=None,
if self.mode == WRITE:
self._write_gzip_header(compresslevel)

@property
def filename(self):
import warnings
warnings.warn("use the name attribute", DeprecationWarning, 2)
if self.mode == WRITE and self.name[-3:] != ".gz":
return self.name + ".gz"
return self.name

@property
def mtime(self):
"""Last modification time read from stream, or None"""
Expand All @@ -237,6 +251,11 @@ def _init_write(self, filename):
self.bufsize = 0
self.offset = 0 # Current file offset for seek(), tell(), etc

def tell(self):
self._check_not_closed()
self._buffer.flush()
return super().tell()

def _write_gzip_header(self, compresslevel):
self.fileobj.write(b'\037\213') # magic header
self.fileobj.write(b'\010') # compression method
Expand Down Expand Up @@ -278,6 +297,10 @@ def write(self,data):
if self.fileobj is None:
raise ValueError("write() on closed GzipFile object")

return self._buffer.write(data)

def _write_raw(self, data):
# Called by our self._buffer underlying WriteBufferStream.
if isinstance(data, (bytes, bytearray)):
length = len(data)
else:
Expand Down Expand Up @@ -328,16 +351,17 @@ def close(self):
fileobj = self.fileobj
if fileobj is None:
return
self.fileobj = None
try:
if self.mode == WRITE:
self._buffer.flush()
fileobj.write(self.compress.flush())
write32u(fileobj, self.crc)
# self.size may exceed 2 GiB, or even 4 GiB
write32u(fileobj, self.size & 0xffffffff)
elif self.mode == READ:
self._buffer.close()
finally:
self.fileobj = None
myfileobj = self.myfileobj
if myfileobj:
self.myfileobj = None
Expand All @@ -346,6 +370,7 @@ def close(self):
def flush(self,zlib_mode=zlib.Z_SYNC_FLUSH):
self._check_not_closed()
if self.mode == WRITE:
self._buffer.flush()
# Ensure the compressor's buffer is flushed
self.fileobj.write(self.compress.flush(zlib_mode))
self.fileobj.flush()
Expand Down Expand Up @@ -376,6 +401,9 @@ def seekable(self):

def seek(self, offset, whence=io.SEEK_SET):
if self.mode == WRITE:
self._check_not_closed()
# Flush buffer to ensure validity of self.offset
self._buffer.flush()
if whence != io.SEEK_SET:
if whence == io.SEEK_CUR:
offset = self.offset + offset
Expand All @@ -384,10 +412,10 @@ def seek(self, offset, whence=io.SEEK_SET):
if offset < self.offset:
raise OSError('Negative seek in write mode')
count = offset - self.offset
chunk = b'\0' * 1024
for i in range(count // 1024):
chunk = b'\0' * self._buffer_size
for i in range(count // self._buffer_size):
self.write(chunk)
self.write(b'\0' * (count % 1024))
self.write(b'\0' * (count % self._buffer_size))
elif self.mode == READ:
self._check_not_closed()
return self._buffer.seek(offset, whence)
Expand Down Expand Up @@ -454,7 +482,7 @@ def _read_gzip_header(fp):

class _GzipReader(_compression.DecompressReader):
def __init__(self, fp):
super().__init__(_PaddedFile(fp), zlib.decompressobj,
super().__init__(_PaddedFile(fp), zlib._ZlibDecompressor,
wbits=-zlib.MAX_WBITS)
# Set flag indicating start of a new member
self._new_member = True
Expand Down Expand Up @@ -502,12 +530,13 @@ def read(self, size=-1):
self._new_member = False

# Read a chunk of data from the file
buf = self._fp.read(io.DEFAULT_BUFFER_SIZE)
if self._decompressor.needs_input:
buf = self._fp.read(READ_BUFFER_SIZE)
uncompress = self._decompressor.decompress(buf, size)
else:
uncompress = self._decompressor.decompress(b"", size)

uncompress = self._decompressor.decompress(buf, size)
if self._decompressor.unconsumed_tail != b"":
self._fp.prepend(self._decompressor.unconsumed_tail)
elif self._decompressor.unused_data != b"":
if self._decompressor.unused_data != b"":
# Prepend the already read bytes to the fileobj so they can
# be seen by _read_eof() and _read_gzip_header()
self._fp.prepend(self._decompressor.unused_data)
Expand All @@ -518,14 +547,11 @@ def read(self, size=-1):
raise EOFError("Compressed file ended before the "
"end-of-stream marker was reached")

self._add_read_data( uncompress )
self._crc = zlib.crc32(uncompress, self._crc)
self._stream_size += len(uncompress)
self._pos += len(uncompress)
return uncompress

def _add_read_data(self, data):
self._crc = zlib.crc32(data, self._crc)
self._stream_size = self._stream_size + len(data)

def _read_eof(self):
# We've read to the end of the file
# We check that the computed CRC and size of the
Expand Down Expand Up @@ -619,13 +645,13 @@ def decompress(data):
def main():
from argparse import ArgumentParser
parser = ArgumentParser(description=
"A simple command line interface for the gzip module: act like gzip, "
"but do not delete the input file.")
"A simple command line interface for the gzip module: act like gzip, "
"but do not delete the input file.")
group = parser.add_mutually_exclusive_group()
group.add_argument('--fast', action='store_true', help='compress faster')
group.add_argument('--best', action='store_true', help='compress better')
group.add_argument("-d", "--decompress", action="store_true",
help="act like gunzip instead of gzip")
help="act like gunzip instead of gzip")

parser.add_argument("args", nargs="*", default=["-"], metavar='file')
args = parser.parse_args()
Expand Down Expand Up @@ -655,7 +681,7 @@ def main():
f = builtins.open(arg, "rb")
g = open(arg + ".gz", "wb")
while True:
chunk = f.read(io.DEFAULT_BUFFER_SIZE)
chunk = f.read(READ_BUFFER_SIZE)
if not chunk:
break
g.write(chunk)
Expand Down
Loading
Loading
0