This commit is contained in:
ton
2024-10-07 10:13:40 +07:00
parent aa1631742f
commit 3a7d696db6
9729 changed files with 1832837 additions and 161742 deletions

View File

@@ -7,11 +7,22 @@ import re
import stat
import time
from io import StringIO, TextIOWrapper
from typing import IO, TYPE_CHECKING, Literal
from zipfile import ZIP_DEFLATED, ZipFile, ZipInfo
from wheel.cli import WheelError
from wheel.util import log, urlsafe_b64decode, urlsafe_b64encode
if TYPE_CHECKING:
from typing import Protocol, Sized, Union
from typing_extensions import Buffer
StrPath = Union[str, os.PathLike[str]]
class SizedBuffer(Sized, Buffer, Protocol): ...
# Non-greedy matching of an optional build number may be too clever (more
# invalid wheel filenames will match). Separate regex for .dist-info?
WHEEL_INFO_RE = re.compile(
@@ -22,7 +33,7 @@ WHEEL_INFO_RE = re.compile(
MINIMUM_TIMESTAMP = 315532800 # 1980-01-01 00:00:00 UTC
def get_zipinfo_datetime(timestamp=None):
def get_zipinfo_datetime(timestamp: float | None = None):
# Some applications need reproducible .whl files, but they can't do this without
# forcing the timestamp of the individual ZipInfo objects. See issue #143.
timestamp = int(os.environ.get("SOURCE_DATE_EPOCH", timestamp or time.time()))
@@ -37,7 +48,12 @@ class WheelFile(ZipFile):
_default_algorithm = hashlib.sha256
def __init__(self, file, mode="r", compression=ZIP_DEFLATED):
def __init__(
self,
file: StrPath,
mode: Literal["r", "w", "x", "a"] = "r",
compression: int = ZIP_DEFLATED,
):
basename = os.path.basename(file)
self.parsed_filename = WHEEL_INFO_RE.match(basename)
if not basename.endswith(".whl") or self.parsed_filename is None:
@@ -49,7 +65,7 @@ class WheelFile(ZipFile):
self.parsed_filename.group("namever")
)
self.record_path = self.dist_info_path + "/RECORD"
self._file_hashes = {}
self._file_hashes: dict[str, tuple[None, None] | tuple[int, bytes]] = {}
self._file_sizes = {}
if mode == "r":
# Ignore RECORD and any embedded wheel signatures
@@ -81,8 +97,8 @@ class WheelFile(ZipFile):
if algorithm.lower() in {"md5", "sha1"}:
raise WheelError(
"Weak hash algorithm ({}) is not permitted by PEP "
"427".format(algorithm)
f"Weak hash algorithm ({algorithm}) is not permitted by "
f"PEP 427"
)
self._file_hashes[path] = (
@@ -90,8 +106,13 @@ class WheelFile(ZipFile):
urlsafe_b64decode(hash_sum.encode("ascii")),
)
def open(self, name_or_info, mode="r", pwd=None):
def _update_crc(newdata):
def open(
self,
name_or_info: str | ZipInfo,
mode: Literal["r", "w"] = "r",
pwd: bytes | None = None,
) -> IO[bytes]:
def _update_crc(newdata: bytes) -> None:
eof = ef._eof
update_crc_orig(newdata)
running_hash.update(newdata)
@@ -119,9 +140,9 @@ class WheelFile(ZipFile):
return ef
def write_files(self, base_dir):
def write_files(self, base_dir: str):
log.info(f"creating '{self.filename}' and adding '{base_dir}' to it")
deferred = []
deferred: list[tuple[str, str]] = []
for root, dirnames, filenames in os.walk(base_dir):
# Sort the directory names so that `os.walk` will walk them in a
# defined order on the next iteration.
@@ -141,7 +162,12 @@ class WheelFile(ZipFile):
for path, arcname in deferred:
self.write(path, arcname)
def write(self, filename, arcname=None, compress_type=None):
def write(
self,
filename: str,
arcname: str | None = None,
compress_type: int | None = None,
) -> None:
with open(filename, "rb") as f:
st = os.fstat(f.fileno())
data = f.read()
@@ -153,7 +179,12 @@ class WheelFile(ZipFile):
zinfo.compress_type = compress_type or self.compression
self.writestr(zinfo, data, compress_type)
def writestr(self, zinfo_or_arcname, data, compress_type=None):
def writestr(
self,
zinfo_or_arcname: str | ZipInfo,
data: SizedBuffer | str,
compress_type: int | None = None,
):
if isinstance(zinfo_or_arcname, str):
zinfo_or_arcname = ZipInfo(
zinfo_or_arcname, date_time=get_zipinfo_datetime()