update
This commit is contained in:
@@ -14,25 +14,25 @@ class WheelError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def unpack_f(args):
|
||||
def unpack_f(args: argparse.Namespace) -> None:
|
||||
from .unpack import unpack
|
||||
|
||||
unpack(args.wheelfile, args.dest)
|
||||
|
||||
|
||||
def pack_f(args):
|
||||
def pack_f(args: argparse.Namespace) -> None:
|
||||
from .pack import pack
|
||||
|
||||
pack(args.directory, args.dest_dir, args.build_number)
|
||||
|
||||
|
||||
def convert_f(args):
|
||||
def convert_f(args: argparse.Namespace) -> None:
|
||||
from .convert import convert
|
||||
|
||||
convert(args.files, args.dest_dir, args.verbose)
|
||||
|
||||
|
||||
def tags_f(args):
|
||||
def tags_f(args: argparse.Namespace) -> None:
|
||||
from .tags import tags
|
||||
|
||||
names = (
|
||||
@@ -51,14 +51,14 @@ def tags_f(args):
|
||||
print(name)
|
||||
|
||||
|
||||
def version_f(args):
|
||||
def version_f(args: argparse.Namespace) -> None:
|
||||
from .. import __version__
|
||||
|
||||
print("wheel %s" % __version__)
|
||||
print(f"wheel {__version__}")
|
||||
|
||||
|
||||
def parse_build_tag(build_tag: str) -> str:
|
||||
if not build_tag[0].isdigit():
|
||||
if build_tag and not build_tag[0].isdigit():
|
||||
raise ArgumentTypeError("build tag must begin with a digit")
|
||||
elif "-" in build_tag:
|
||||
raise ArgumentTypeError("invalid character ('-') in build tag")
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -7,7 +7,7 @@ import tempfile
|
||||
import zipfile
|
||||
from glob import iglob
|
||||
|
||||
from ..bdist_wheel import bdist_wheel
|
||||
from .._bdist_wheel import bdist_wheel
|
||||
from ..wheelfile import WheelFile
|
||||
from . import WheelError
|
||||
|
||||
@@ -42,7 +42,7 @@ class _bdist_wheel_tag(bdist_wheel):
|
||||
return bdist_wheel.get_tag(self)
|
||||
|
||||
|
||||
def egg2wheel(egg_path: str, dest_dir: str):
|
||||
def egg2wheel(egg_path: str, dest_dir: str) -> None:
|
||||
filename = os.path.basename(egg_path)
|
||||
match = egg_info_re.match(filename)
|
||||
if not match:
|
||||
@@ -96,7 +96,7 @@ def egg2wheel(egg_path: str, dest_dir: str):
|
||||
shutil.rmtree(dir)
|
||||
|
||||
|
||||
def parse_wininst_info(wininfo_name, egginfo_name):
|
||||
def parse_wininst_info(wininfo_name: str, egginfo_name: str | None):
|
||||
"""Extract metadata from filenames.
|
||||
|
||||
Extracts the 4 metadataitems needed (name, version, pyversion, arch) from
|
||||
@@ -167,7 +167,7 @@ def parse_wininst_info(wininfo_name, egginfo_name):
|
||||
return {"name": w_name, "ver": w_ver, "arch": w_arch, "pyver": w_pyver}
|
||||
|
||||
|
||||
def wininst2wheel(path, dest_dir):
|
||||
def wininst2wheel(path: str, dest_dir: str) -> None:
|
||||
with zipfile.ZipFile(path) as bdw:
|
||||
# Search for egg-info in the archive
|
||||
egginfo_name = None
|
||||
@@ -189,11 +189,11 @@ def wininst2wheel(path, dest_dir):
|
||||
paths = {"platlib": ""}
|
||||
|
||||
dist_info = "{name}-{ver}".format(**info)
|
||||
datadir = "%s.data/" % dist_info
|
||||
datadir = f"{dist_info}.data/"
|
||||
|
||||
# rewrite paths to trick ZipFile into extracting an egg
|
||||
# XXX grab wininst .ini - between .exe, padding, and first zip file.
|
||||
members = []
|
||||
members: list[str] = []
|
||||
egginfo_name = ""
|
||||
for zipinfo in bdw.infolist():
|
||||
key, basename = zipinfo.filename.split("/", 1)
|
||||
@@ -246,7 +246,7 @@ def wininst2wheel(path, dest_dir):
|
||||
bw.full_tag_supplied = True
|
||||
bw.full_tag = (pyver, abi, arch)
|
||||
|
||||
dist_info_dir = os.path.join(dir, "%s.dist-info" % dist_info)
|
||||
dist_info_dir = os.path.join(dir, f"{dist_info}.dist-info")
|
||||
bw.egg2dist(os.path.join(dir, egginfo_name), dist_info_dir)
|
||||
bw.write_wheelfile(dist_info_dir, generator="wininst2wheel")
|
||||
|
||||
@@ -257,7 +257,7 @@ def wininst2wheel(path, dest_dir):
|
||||
shutil.rmtree(dir)
|
||||
|
||||
|
||||
def convert(files, dest_dir, verbose):
|
||||
def convert(files: list[str], dest_dir: str, verbose: bool) -> None:
|
||||
for pat in files:
|
||||
for installer in iglob(pat):
|
||||
if os.path.splitext(installer)[1] == ".egg":
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import email.policy
|
||||
import os.path
|
||||
import re
|
||||
from email.generator import BytesGenerator
|
||||
from email.parser import BytesParser
|
||||
|
||||
from wheel.cli import WheelError
|
||||
from wheel.wheelfile import WheelFile
|
||||
|
||||
DIST_INFO_RE = re.compile(r"^(?P<namever>(?P<name>.+?)-(?P<ver>\d.*?))\.dist-info$")
|
||||
BUILD_NUM_RE = re.compile(rb"Build: (\d\w*)$")
|
||||
|
||||
|
||||
def pack(directory: str, dest_dir: str, build_number: str | None):
|
||||
def pack(directory: str, dest_dir: str, build_number: str | None) -> None:
|
||||
"""Repack a previously unpacked wheel directory into a new wheel file.
|
||||
|
||||
The .dist-info/WHEEL file must contain one or more tags so that the target
|
||||
@@ -35,31 +37,29 @@ def pack(directory: str, dest_dir: str, build_number: str | None):
|
||||
name_version = DIST_INFO_RE.match(dist_info_dir).group("namever")
|
||||
|
||||
# Read the tags and the existing build number from .dist-info/WHEEL
|
||||
existing_build_number = None
|
||||
wheel_file_path = os.path.join(directory, dist_info_dir, "WHEEL")
|
||||
with open(wheel_file_path, "rb") as f:
|
||||
tags, existing_build_number = read_tags(f.read())
|
||||
info = BytesParser(policy=email.policy.compat32).parse(f)
|
||||
tags: list[str] = info.get_all("Tag", [])
|
||||
existing_build_number = info.get("Build")
|
||||
|
||||
if not tags:
|
||||
raise WheelError(
|
||||
"No tags present in {}/WHEEL; cannot determine target wheel "
|
||||
"filename".format(dist_info_dir)
|
||||
f"No tags present in {dist_info_dir}/WHEEL; cannot determine target "
|
||||
f"wheel filename"
|
||||
)
|
||||
|
||||
# Set the wheel file name and add/replace/remove the Build tag in .dist-info/WHEEL
|
||||
build_number = build_number if build_number is not None else existing_build_number
|
||||
if build_number is not None:
|
||||
del info["Build"]
|
||||
if build_number:
|
||||
info["Build"] = build_number
|
||||
name_version += "-" + build_number
|
||||
|
||||
if build_number != existing_build_number:
|
||||
with open(wheel_file_path, "rb+") as f:
|
||||
wheel_file_content = f.read()
|
||||
wheel_file_content = set_build_number(wheel_file_content, build_number)
|
||||
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
f.write(wheel_file_content)
|
||||
with open(wheel_file_path, "wb") as f:
|
||||
BytesGenerator(f, maxheaderlen=0).flatten(info)
|
||||
|
||||
# Reassemble the tags for the wheel file
|
||||
tagline = compute_tagline(tags)
|
||||
@@ -73,45 +73,6 @@ def pack(directory: str, dest_dir: str, build_number: str | None):
|
||||
print("OK")
|
||||
|
||||
|
||||
def read_tags(input_str: bytes) -> tuple[list[str], str | None]:
|
||||
"""Read tags from a string.
|
||||
|
||||
:param input_str: A string containing one or more tags, separated by spaces
|
||||
:return: A list of tags and a list of build tags
|
||||
"""
|
||||
|
||||
tags = []
|
||||
existing_build_number = None
|
||||
for line in input_str.splitlines():
|
||||
if line.startswith(b"Tag: "):
|
||||
tags.append(line.split(b" ")[1].rstrip().decode("ascii"))
|
||||
elif line.startswith(b"Build: "):
|
||||
existing_build_number = line.split(b" ")[1].rstrip().decode("ascii")
|
||||
|
||||
return tags, existing_build_number
|
||||
|
||||
|
||||
def set_build_number(wheel_file_content: bytes, build_number: str | None) -> bytes:
|
||||
"""Compute a build tag and add/replace/remove as necessary.
|
||||
|
||||
:param wheel_file_content: The contents of .dist-info/WHEEL
|
||||
:param build_number: The build tags present in .dist-info/WHEEL
|
||||
:return: The (modified) contents of .dist-info/WHEEL
|
||||
"""
|
||||
replacement = (
|
||||
("Build: %s\r\n" % build_number).encode("ascii") if build_number else b""
|
||||
)
|
||||
|
||||
wheel_file_content, num_replaced = BUILD_NUM_RE.subn(
|
||||
replacement, wheel_file_content
|
||||
)
|
||||
|
||||
if not num_replaced:
|
||||
wheel_file_content += replacement
|
||||
|
||||
return wheel_file_content
|
||||
|
||||
|
||||
def compute_tagline(tags: list[str]) -> str:
|
||||
"""Compute a tagline from a list of tags.
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import email.policy
|
||||
import itertools
|
||||
import os
|
||||
from collections.abc import Iterable
|
||||
from email.parser import BytesParser
|
||||
|
||||
from ..wheelfile import WheelFile
|
||||
from .pack import read_tags, set_build_number
|
||||
|
||||
|
||||
def _compute_tags(original_tags: Iterable[str], new_tags: str | None) -> set[str]:
|
||||
@@ -48,6 +49,7 @@ def tags(
|
||||
assert f.filename, f"{f.filename} must be available"
|
||||
|
||||
wheel_info = f.read(f.dist_info_path + "/WHEEL")
|
||||
info = BytesParser(policy=email.policy.compat32).parsebytes(wheel_info)
|
||||
|
||||
original_wheel_name = os.path.basename(f.filename)
|
||||
namever = f.parsed_filename.group("namever")
|
||||
@@ -56,7 +58,8 @@ def tags(
|
||||
original_abi_tags = f.parsed_filename.group("abi").split(".")
|
||||
original_plat_tags = f.parsed_filename.group("plat").split(".")
|
||||
|
||||
tags, existing_build_tag = read_tags(wheel_info)
|
||||
tags: list[str] = info.get_all("Tag", [])
|
||||
existing_build_tag = info.get("Build")
|
||||
|
||||
impls = {tag.split("-")[0] for tag in tags}
|
||||
abivers = {tag.split("-")[1] for tag in tags}
|
||||
@@ -103,12 +106,13 @@ def tags(
|
||||
final_wheel_name = "-".join(final_tags) + ".whl"
|
||||
|
||||
if original_wheel_name != final_wheel_name:
|
||||
tags = [
|
||||
f"{a}-{b}-{c}"
|
||||
for a, b, c in itertools.product(
|
||||
final_python_tags, final_abi_tags, final_plat_tags
|
||||
)
|
||||
]
|
||||
del info["Tag"], info["Build"]
|
||||
for a, b, c in itertools.product(
|
||||
final_python_tags, final_abi_tags, final_plat_tags
|
||||
):
|
||||
info["Tag"] = f"{a}-{b}-{c}"
|
||||
if build:
|
||||
info["Build"] = build
|
||||
|
||||
original_wheel_path = os.path.join(
|
||||
os.path.dirname(f.filename), original_wheel_name
|
||||
@@ -125,10 +129,7 @@ def tags(
|
||||
if item.filename == f.dist_info_path + "/RECORD":
|
||||
continue
|
||||
if item.filename == f.dist_info_path + "/WHEEL":
|
||||
content = fin.read(item)
|
||||
content = set_tags(content, tags)
|
||||
content = set_build_number(content, build)
|
||||
fout.writestr(item, content)
|
||||
fout.writestr(item, info.as_bytes())
|
||||
else:
|
||||
fout.writestr(item, fin.read(item))
|
||||
|
||||
@@ -136,18 +137,3 @@ def tags(
|
||||
os.remove(original_wheel_path)
|
||||
|
||||
return final_wheel_name
|
||||
|
||||
|
||||
def set_tags(in_string: bytes, tags: Iterable[str]) -> bytes:
|
||||
"""Set the tags in the .dist-info/WHEEL file contents.
|
||||
|
||||
:param in_string: The string to modify.
|
||||
:param tags: The tags to set.
|
||||
"""
|
||||
|
||||
lines = [line for line in in_string.splitlines() if not line.startswith(b"Tag:")]
|
||||
for tag in tags:
|
||||
lines.append(b"Tag: " + tag.encode("ascii"))
|
||||
in_string = b"\r\n".join(lines) + b"\r\n"
|
||||
|
||||
return in_string
|
||||
|
||||
Reference in New Issue
Block a user