Skip to content
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

bdist_wheel typing improvement #4383

Merged
merged 11 commits into from
Aug 8, 2024
2 changes: 1 addition & 1 deletion mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ exclude = (?x)(
| ^.+?/(_vendor|extern)/ # Vendored
| ^setuptools/_distutils/ # Vendored
| ^setuptools/config/_validate_pyproject/ # Auto-generated
| ^setuptools/tests/bdist_wheel_testdata/ # Duplicate module name
| ^setuptools/tests/bdist_wheel_testdata/ # Duplicate module name
abravalheri marked this conversation as resolved.
Show resolved Hide resolved
)

# Ignoring attr-defined because setuptools wraps a lot of distutils classes, adding new attributes,
Expand Down
65 changes: 39 additions & 26 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 ..extern.wheel.metadata import pkginfo_to_metadata
from ..extern.packaging import tags
from ..extern.packaging import version as _packaging_version
from ..extern.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 @@ -295,21 +293,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:
abravalheri marked this conversation as resolved.
Show resolved Hide resolved
plat_name = self.plat_name
elif self.root_is_pure:
plat_name = "any"
else:
Expand Down Expand Up @@ -433,7 +431,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 All @@ -453,7 +451,7 @@ def run(self):

def write_wheelfile(
self, wheelfile_base: str, generator: str = f"setuptools ({__version__})"
):
) -> None:
from email.message import Message

msg = Message()
Expand Down Expand Up @@ -527,7 +525,7 @@ def license_paths(self) -> Iterable[str]:

return files

def egg2dist(self, egginfo_path: str, distinfo_path: str):
def egg2dist(self, egginfo_path: str, distinfo_path: str) -> None:
"""Convert an .egg-info directory into a .dist-info directory"""

def adios(p: str) -> None:
Expand Down Expand Up @@ -597,3 +595,18 @@ 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

try:
if isinstance(self.compression, str):
return self.supported_compressions[self.compression]
except KeyError:
pass
Copy link
Contributor Author

@Avasam Avasam Jun 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be done w/o a try-except.

Suggested change
try:
if isinstance(self.compression, str):
return self.supported_compressions[self.compression]
except KeyError:
pass
if isinstance(self.compression, str):
compression = self.supported_compressions.get(self.compression)
if compression is not None:
return compression

And just for fun, using the walrus operator (Assignment Expressions, which I don't like)

Suggested change
try:
if isinstance(self.compression, str):
return self.supported_compressions[self.compression]
except KeyError:
pass
if isinstance(self.compression, str) and (
compression := self.supported_compressions.get(self.compression)
):
return compression

abravalheri marked this conversation as resolved.
Show resolved Hide resolved

raise ValueError(f"Unsupported compression: {self.compression!r}")
3 changes: 2 additions & 1 deletion tools/vendored.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ def rewrite_wheel(pkg_files: Path):

# Rewrite vendored imports to use setuptools's own vendored libraries
for path in pkg_files.iterdir():
# Upstream issue: https://github.com/jaraco/path/issues/226
if path.suffix == '.py': # type: ignore[attr-defined]
code = path.read_text()
if path.name == 'wheelfile.py':
Expand Down Expand Up @@ -154,7 +155,7 @@ class WheelError(Exception):
code,
flags=re.MULTILINE,
)

# Upstream issue: https://github.com/jaraco/path/issues/226
path.write_text(code) # type: ignore[attr-defined]


Expand Down
Loading