Skip to content

Commit

Permalink
bdist_wheel typing improvement (#4383)
Browse files Browse the repository at this point in the history
* bdist_wheel typing improvement
* Extract compression conversion logic to _zip_compression
* Add newsfragment
* Update mypy.ini
  • Loading branch information
Avasam authored Aug 8, 2024
1 parent 896be01 commit ab8290c
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 25 deletions.
1 change: 0 additions & 1 deletion mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ exclude = (?x)(
| ^setuptools/_vendor/ # Vendored
| ^setuptools/_distutils/ # Vendored
| ^setuptools/config/_validate_pyproject/ # Auto-generated
| ^setuptools/tests/bdist_wheel_testdata/ # Duplicate module name
)
# Too many false-positives
disable_error_code = overload-overlap
Expand Down
1 change: 1 addition & 0 deletions newsfragments/4383.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Prevent an error in ``bdist_wheel`` if ``compression`` is set to a `str` (even if valid) after finalizing options but before running the command. -- by :user:`Avasam`
59 changes: 35 additions & 24 deletions setuptools/command/bdist_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@
from zipfile import ZIP_DEFLATED, ZIP_STORED

from .. import Command, __version__
from .egg_info import egg_info as egg_info_cls
from wheel.metadata import pkginfo_to_metadata
from packaging import tags
from packaging import version as _packaging_version
from wheel.wheelfile import WheelFile

if TYPE_CHECKING:
import types
from _typeshed import ExcInfo


def safe_name(name: str) -> str:
Expand Down Expand Up @@ -152,12 +153,14 @@ def safer_version(version: str) -> str:
def remove_readonly(
func: Callable[..., object],
path: str,
excinfo: tuple[type[Exception], Exception, types.TracebackType],
excinfo: ExcInfo,
) -> None:
remove_readonly_exc(func, path, excinfo[1])


def remove_readonly_exc(func: Callable[..., object], path: str, exc: Exception) -> None:
def remove_readonly_exc(
func: Callable[..., object], path: str, exc: BaseException
) -> None:
os.chmod(path, stat.S_IWRITE)
func(path)

Expand Down Expand Up @@ -232,40 +235,35 @@ class bdist_wheel(Command):

def initialize_options(self) -> None:
self.bdist_dir: str | None = None
self.data_dir = None
self.data_dir: str | None = None
self.plat_name: str | None = None
self.plat_tag = None
self.plat_tag: str | None = None
self.format = "zip"
self.keep_temp = False
self.dist_dir: str | None = None
self.egginfo_dir = None
self.egginfo_dir: str | None = None
self.root_is_pure: bool | None = None
self.skip_build = None
self.skip_build = False
self.relative = False
self.owner = None
self.group = None
self.universal: bool = False
self.compression: str | int = "deflated"
self.compression: int | str = "deflated"
self.python_tag: str = python_tag()
self.build_number: str | None = None
self.py_limited_api: str | Literal[False] = False
self.plat_name_supplied = False

def finalize_options(self):
if self.bdist_dir is None:
def finalize_options(self) -> None:
if not self.bdist_dir:
bdist_base = self.get_finalized_command("bdist").bdist_base
self.bdist_dir = os.path.join(bdist_base, "wheel")

egg_info = self.distribution.get_command_obj("egg_info")
egg_info = cast(egg_info_cls, self.distribution.get_command_obj("egg_info"))
egg_info.ensure_finalized() # needed for correct `wheel_dist_name`

self.data_dir = self.wheel_dist_name + ".data"
self.plat_name_supplied = self.plat_name is not None

try:
self.compression = self.supported_compressions[self.compression]
except KeyError:
raise ValueError(f"Unsupported compression: {self.compression}") from None
self.plat_name_supplied = bool(self.plat_name)

need_options = ("dist_dir", "plat_name", "skip_build")

Expand Down Expand Up @@ -293,21 +291,21 @@ def finalize_options(self):
raise ValueError("Build tag (build-number) must start with a digit.")

@property
def wheel_dist_name(self):
def wheel_dist_name(self) -> str:
"""Return distribution full name with - replaced with _"""
components = (
components = [
safer_name(self.distribution.get_name()),
safer_version(self.distribution.get_version()),
)
]
if self.build_number:
components += (self.build_number,)
components.append(self.build_number)
return "-".join(components)

def get_tag(self) -> tuple[str, str, str]:
# bdist sets self.plat_name if unset, we should only use it for purepy
# wheels if the user supplied it.
if self.plat_name_supplied:
plat_name = cast(str, self.plat_name)
if self.plat_name_supplied and self.plat_name:
plat_name = self.plat_name
elif self.root_is_pure:
plat_name = "any"
else:
Expand Down Expand Up @@ -431,7 +429,7 @@ def run(self):
os.makedirs(self.dist_dir)

wheel_path = os.path.join(self.dist_dir, archive_basename + ".whl")
with WheelFile(wheel_path, "w", self.compression) as wf:
with WheelFile(wheel_path, "w", self._zip_compression()) as wf:
wf.write_files(archive_root)

# Add to 'Distribution.dist_files' so that the "upload" command works
Expand Down Expand Up @@ -595,3 +593,16 @@ def adios(p: str) -> None:
shutil.copy(license_path, os.path.join(distinfo_path, filename))

adios(egginfo_path)

def _zip_compression(self) -> int:
if (
isinstance(self.compression, int)
and self.compression in self.supported_compressions.values()
):
return self.compression

compression = self.supported_compressions.get(str(self.compression))
if compression is not None:
return compression

raise ValueError(f"Unsupported compression: {self.compression!r}")

0 comments on commit ab8290c

Please sign in to comment.