Skip to content

Commit

Permalink
Merge branch 'main' into Merge-typeshed-return-annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
Avasam authored Nov 20, 2024
2 parents f0f05bd + 2c77cd2 commit b9a1744
Show file tree
Hide file tree
Showing 18 changed files with 228 additions and 146 deletions.
3 changes: 3 additions & 0 deletions newsfragments/4701.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Preserve original ``PKG-INFO`` into ``METADATA`` when creating wheel
(instead of calling ``wheel.metadata.pkginfo_to_metadata``).
This helps to be more compliant with the flow specified in PEP 517.
4 changes: 2 additions & 2 deletions setuptools/build_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@ def patch(cls) -> Iterator[None]:
for the duration of this context.
"""
orig = distutils.core.Distribution
distutils.core.Distribution = cls
distutils.core.Distribution = cls # type: ignore[misc] # monkeypatching
try:
yield
finally:
distutils.core.Distribution = orig
distutils.core.Distribution = orig # type: ignore[misc] # monkeypatching


@contextlib.contextmanager
Expand Down
2 changes: 1 addition & 1 deletion setuptools/command/bdist_egg.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ def zip_safe(self):
log.warn("zip_safe flag not set; analyzing archive contents...")
return analyze_egg(self.bdist_dir, self.stubs)

def gen_header(self) -> str:
def gen_header(self) -> Literal["w"]:
return 'w'

def copy_metadata_to(self, target_dir) -> None:
Expand Down
64 changes: 25 additions & 39 deletions setuptools/command/bdist_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,12 @@
import sysconfig
import warnings
from collections.abc import Iterable, Sequence
from email.generator import BytesGenerator, Generator
from email.policy import EmailPolicy
from email.generator import BytesGenerator
from glob import iglob
from typing import Literal, cast
from zipfile import ZIP_DEFLATED, ZIP_STORED

from packaging import tags, version as _packaging_version
from wheel.metadata import pkginfo_to_metadata
from wheel.wheelfile import WheelFile

from .. import Command, __version__, _shutil
Expand Down Expand Up @@ -220,7 +218,7 @@ class bdist_wheel(Command):

def initialize_options(self) -> None:
self.bdist_dir: str | None = None
self.data_dir: str | None = None
self.data_dir = ""
self.plat_name: str | None = None
self.plat_tag: str | None = None
self.format = "zip"
Expand Down Expand Up @@ -569,42 +567,30 @@ def adios(p: str) -> None:

raise ValueError(err)

if os.path.isfile(egginfo_path):
# .egg-info is a single file
pkg_info = pkginfo_to_metadata(egginfo_path, egginfo_path)
os.mkdir(distinfo_path)
else:
# .egg-info is a directory
pkginfo_path = os.path.join(egginfo_path, "PKG-INFO")
pkg_info = pkginfo_to_metadata(egginfo_path, pkginfo_path)

# ignore common egg metadata that is useless to wheel
shutil.copytree(
egginfo_path,
distinfo_path,
ignore=lambda x, y: {
"PKG-INFO",
"requires.txt",
"SOURCES.txt",
"not-zip-safe",
},
)

# delete dependency_links if it is only whitespace
dependency_links_path = os.path.join(distinfo_path, "dependency_links.txt")
with open(dependency_links_path, encoding="utf-8") as dependency_links_file:
dependency_links = dependency_links_file.read().strip()
if not dependency_links:
adios(dependency_links_path)

pkg_info_path = os.path.join(distinfo_path, "METADATA")
serialization_policy = EmailPolicy(
utf8=True,
mangle_from_=False,
max_line_length=0,
# .egg-info is a directory
pkginfo_path = os.path.join(egginfo_path, "PKG-INFO")

# ignore common egg metadata that is useless to wheel
shutil.copytree(
egginfo_path,
distinfo_path,
ignore=lambda x, y: {
"PKG-INFO",
"requires.txt",
"SOURCES.txt",
"not-zip-safe",
},
)
with open(pkg_info_path, "w", encoding="utf-8") as out:
Generator(out, policy=serialization_policy).flatten(pkg_info)

# delete dependency_links if it is only whitespace
dependency_links_path = os.path.join(distinfo_path, "dependency_links.txt")
with open(dependency_links_path, encoding="utf-8") as dependency_links_file:
dependency_links = dependency_links_file.read().strip()
if not dependency_links:
adios(dependency_links_path)

metadata_path = os.path.join(distinfo_path, "METADATA")
shutil.copy(pkginfo_path, metadata_path)

for license_path in self.license_paths:
filename = os.path.basename(license_path)
Expand Down
4 changes: 2 additions & 2 deletions setuptools/command/build_ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class build_ext(_build_ext):

def run(self) -> None:
"""Build extensions in build directory, then copy if --inplace"""
old_inplace, self.inplace = self.inplace, 0
old_inplace, self.inplace = self.inplace, False
_build_ext.run(self)
self.inplace = old_inplace
if old_inplace:
Expand Down Expand Up @@ -248,7 +248,7 @@ def setup_shlib_compiler(self) -> None:
compiler.set_link_objects(self.link_objects)

# hack so distutils' build_extension() builds a library instead
compiler.link_shared_object = link_shared_object.__get__(compiler)
compiler.link_shared_object = link_shared_object.__get__(compiler) # type: ignore[method-assign]

def get_export_symbols(self, ext):
if isinstance(ext, Library):
Expand Down
21 changes: 8 additions & 13 deletions setuptools/command/build_py.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,14 @@ class build_py(orig.build_py):

distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution
editable_mode: bool = False
existing_egg_info_dir: str | None = None #: Private API, internal use only.
existing_egg_info_dir: StrPath | None = None #: Private API, internal use only.

def finalize_options(self) -> None:
orig.build_py.finalize_options(self)
self.package_data = self.distribution.package_data
self.exclude_package_data = self.distribution.exclude_package_data or {}
if 'data_files' in self.__dict__:
del self.__dict__['data_files']
self.__updated_files = []

def copy_file( # type: ignore[override] # No overload, no bytes support
self,
Expand Down Expand Up @@ -89,12 +88,6 @@ def __getattr__(self, attr: str):
return self.data_files
return orig.build_py.__getattr__(self, attr)

def build_module(self, module, module_file, package):
outfile, copied = orig.build_py.build_module(self, module, module_file, package)
if copied:
self.__updated_files.append(outfile)
return outfile, copied

def _get_data_files(self):
"""Generate list of '(package,src_dir,build_dir,filenames)' tuples"""
self.analyze_manifest()
Expand Down Expand Up @@ -179,16 +172,16 @@ def build_package_data(self) -> None:
make_writable(target)

def analyze_manifest(self) -> None:
self.manifest_files = mf = {}
self.manifest_files: dict[str, list[str]] = {}
if not self.distribution.include_package_data:
return
src_dirs = {}
src_dirs: dict[str, str] = {}
for package in self.packages or ():
# Locate package source directory
src_dirs[assert_relative(self.get_package_dir(package))] = package

if (
getattr(self, 'existing_egg_info_dir', None)
self.existing_egg_info_dir
and Path(self.existing_egg_info_dir, "SOURCES.txt").exists()
):
egg_info_dir = self.existing_egg_info_dir
Expand Down Expand Up @@ -217,9 +210,11 @@ def analyze_manifest(self) -> None:
importable = check.importable_subpackage(src_dirs[d], f)
if importable:
check.warn(importable)
mf.setdefault(src_dirs[d], []).append(path)
self.manifest_files.setdefault(src_dirs[d], []).append(path)

def _filter_build_files(self, files: Iterable[str], egg_info: str) -> Iterator[str]:
def _filter_build_files(
self, files: Iterable[str], egg_info: StrPath
) -> Iterator[str]:
"""
``build_meta`` may try to create egg_info outside of the project directory,
and this can be problematic for certain plugins (reported in issue #3500).
Expand Down
2 changes: 1 addition & 1 deletion setuptools/command/easy_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ def finalize_options(self) -> None: # noqa: C901 # is too complex (25) # FIXM
"No urls, filenames, or requirements specified (see --help)"
)

self.outputs = []
self.outputs: list[str] = []

@staticmethod
def _process_site_dirs(site_dirs):
Expand Down
2 changes: 1 addition & 1 deletion setuptools/command/editable_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ def __init__(self, distribution, installation_dir, editable_name, src_root) -> N
self.src_root = src_root
self.installation_dir = installation_dir
self.editable_name = editable_name
self.outputs = []
self.outputs: list[str] = []
self.dry_run = False

def _get_nspkg_file(self):
Expand Down
3 changes: 2 additions & 1 deletion setuptools/command/egg_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import re
import sys
import time
from collections.abc import Callable

import packaging
import packaging.requirements
Expand Down Expand Up @@ -340,7 +341,7 @@ def process_template_line(self, line) -> None:
# patterns, (dir and patterns), or (dir_pattern).
(action, patterns, dir, dir_pattern) = self._parse_template_line(line)

action_map = {
action_map: dict[str, Callable] = {
'include': self.include,
'exclude': self.exclude,
'global-include': self.global_include,
Expand Down
2 changes: 1 addition & 1 deletion setuptools/command/install_egg_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def finalize_options(self) -> None:
basename = f"{ei_cmd._get_egg_basename()}.egg-info"
self.source = ei_cmd.egg_info
self.target = os.path.join(self.install_dir, basename)
self.outputs = []
self.outputs: list[str] = []

def run(self) -> None:
self.run_command('egg_info')
Expand Down
2 changes: 1 addition & 1 deletion setuptools/command/saveopts.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class saveopts(option_base):

def run(self) -> None:
dist = self.distribution
settings = {}
settings: dict[str, dict[str, str]] = {}

for cmd in dist.command_options:
if cmd == 'saveopts':
Expand Down
4 changes: 2 additions & 2 deletions setuptools/command/sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,10 @@ def read_manifest(self) -> None:
"""
log.info("reading manifest file '%s'", self.manifest)
manifest = open(self.manifest, 'rb')
for line in manifest:
for bytes_line in manifest:
# The manifest must contain UTF-8. See #303.
try:
line = line.decode('UTF-8')
line = bytes_line.decode('UTF-8')
except UnicodeDecodeError:
log.warn("%r not UTF-8 decodable -- skipping" % line)
continue
Expand Down
2 changes: 1 addition & 1 deletion setuptools/command/setopt.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def edit_config(filename, settings, dry_run=False) -> None:
"""
log.debug("Reading configuration from %s", filename)
opts = configparser.RawConfigParser()
opts.optionxform = lambda x: x
opts.optionxform = lambda optionstr: optionstr # type: ignore[method-assign] # overriding method
_cfg_read_utf8_with_fallback(opts, filename)

for section, options in settings.items():
Expand Down
3 changes: 2 additions & 1 deletion setuptools/dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -914,9 +914,10 @@ def get_cmdline_options(self) -> dict[str, dict[str, str | None]]:
Note that options provided by config files are intentionally excluded.
"""

d = {}
d: dict[str, dict[str, str | None]] = {}

for cmd, opts in self.command_options.items():
val: str | None
for opt, (src, val) in opts.items():
if src != "command line":
continue
Expand Down
6 changes: 3 additions & 3 deletions setuptools/monkey.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def patch_all() -> None:
import setuptools

# we can't patch distutils.cmd, alas
distutils.core.Command = setuptools.Command
distutils.core.Command = setuptools.Command # type: ignore[misc,assignment] # monkeypatching

_patch_distribution_metadata()

Expand All @@ -82,8 +82,8 @@ def patch_all() -> None:
module.Distribution = setuptools.dist.Distribution

# Install the patched Extension
distutils.core.Extension = setuptools.extension.Extension
distutils.extension.Extension = setuptools.extension.Extension
distutils.core.Extension = setuptools.extension.Extension # type: ignore[misc,assignment] # monkeypatching
distutils.extension.Extension = setuptools.extension.Extension # type: ignore[misc,assignment] # monkeypatching
if 'distutils.command.build_ext' in sys.modules:
sys.modules[
'distutils.command.build_ext'
Expand Down
4 changes: 2 additions & 2 deletions setuptools/msvc.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ def find_programdata_vs_vers(self) -> dict[float, str]:
dict
float version as key, path as value.
"""
vs_versions = {}
vs_versions: dict[float, str] = {}
instances_dir = r'C:\ProgramData\Microsoft\VisualStudio\Packages\_Instances'

try:
Expand Down Expand Up @@ -622,7 +622,7 @@ def WindowsSdkDir(self) -> str: # noqa: C901 # is too complex (12) # FIXME
str
path
"""
sdkdir = ''
sdkdir: str | None = ''
for ver in self.WindowsSdkVersion:
# Try to get it from registry
loc = os.path.join(self.ri.windows_sdk, 'v%s' % ver)
Expand Down
Loading

0 comments on commit b9a1744

Please sign in to comment.