|
| 1 | +diff --git a/wheel/wheelfile.py b/wheel/wheelfile.py |
| 2 | +index 6440e90..7ef7528 100644 |
| 3 | +--- a/wheel/wheelfile.py |
| 4 | ++++ b/wheel/wheelfile.py |
| 5 | +@@ -144,7 +144,9 @@ class WheelFile(ZipFile): |
| 6 | + def write(self, filename, arcname=None, compress_type=None): |
| 7 | + with open(filename, "rb") as f: |
| 8 | + st = os.fstat(f.fileno()) |
| 9 | +- data = f.read() |
| 10 | ++ data = [] |
| 11 | ++ while chunk := f.read(4194304): |
| 12 | ++ data.append(chunk) |
| 13 | + |
| 14 | + zinfo = ZipInfo( |
| 15 | + arcname or filename, date_time=get_zipinfo_datetime(st.st_mtime) |
| 16 | +@@ -164,7 +166,10 @@ class WheelFile(ZipFile): |
| 17 | + if isinstance(data, str): |
| 18 | + data = data.encode("utf-8") |
| 19 | + |
| 20 | +- ZipFile.writestr(self, zinfo_or_arcname, data, compress_type) |
| 21 | ++ # GraalPy change |
| 22 | ++ if not isinstance(data, list): |
| 23 | ++ data = [data] |
| 24 | ++ self.writestr_list(zinfo_or_arcname, data, compress_type) |
| 25 | + fname = ( |
| 26 | + zinfo_or_arcname.filename |
| 27 | + if isinstance(zinfo_or_arcname, ZipInfo) |
| 28 | +@@ -172,12 +177,52 @@ class WheelFile(ZipFile): |
| 29 | + ) |
| 30 | + log.info(f"adding '{fname}'") |
| 31 | + if fname != self.record_path: |
| 32 | +- hash_ = self._default_algorithm(data) |
| 33 | ++ hash_ = self._default_algorithm() |
| 34 | ++ for chunk in data: |
| 35 | ++ hash_.update(chunk) |
| 36 | + self._file_hashes[fname] = ( |
| 37 | + hash_.name, |
| 38 | + urlsafe_b64encode(hash_.digest()).decode("ascii"), |
| 39 | + ) |
| 40 | +- self._file_sizes[fname] = len(data) |
| 41 | ++ self._file_sizes[fname] = sum(map(len, data)) |
| 42 | ++ |
| 43 | ++ # GraalPy change: version that accepts data as a list of bytes chunks, to |
| 44 | ++ # avoid running into the 2GB limit for bytes object size |
| 45 | ++ def writestr_list(self, zinfo_or_arcname, data, |
| 46 | ++ compress_type=None, compresslevel=None): |
| 47 | ++ if not isinstance(zinfo_or_arcname, ZipInfo): |
| 48 | ++ zinfo = ZipInfo(filename=zinfo_or_arcname, |
| 49 | ++ date_time=time.localtime(time.time())[:6]) |
| 50 | ++ zinfo.compress_type = self.compression |
| 51 | ++ zinfo._compresslevel = self.compresslevel |
| 52 | ++ if zinfo.filename[-1] == '/': |
| 53 | ++ zinfo.external_attr = 0o40775 << 16 # drwxrwxr-x |
| 54 | ++ zinfo.external_attr |= 0x10 # MS-DOS directory flag |
| 55 | ++ else: |
| 56 | ++ zinfo.external_attr = 0o600 << 16 # ?rw------- |
| 57 | ++ else: |
| 58 | ++ zinfo = zinfo_or_arcname |
| 59 | ++ |
| 60 | ++ if not self.fp: |
| 61 | ++ raise ValueError( |
| 62 | ++ "Attempt to write to ZIP archive that was already closed") |
| 63 | ++ if self._writing: |
| 64 | ++ raise ValueError( |
| 65 | ++ "Can't write to ZIP archive while an open writing handle exists." |
| 66 | ++ ) |
| 67 | ++ |
| 68 | ++ if compress_type is not None: |
| 69 | ++ zinfo.compress_type = compress_type |
| 70 | ++ |
| 71 | ++ if compresslevel is not None: |
| 72 | ++ zinfo._compresslevel = compresslevel |
| 73 | ++ |
| 74 | ++ zinfo.file_size = sum(map(len, data)) # Uncompressed size |
| 75 | ++ with self._lock: |
| 76 | ++ with self.open(zinfo, mode='w') as dest: |
| 77 | ++ for chunk in data: |
| 78 | ++ dest.write(chunk) |
| 79 | ++ |
| 80 | + |
| 81 | + def close(self): |
| 82 | + # Write RECORD |
0 commit comments