diff --git a/setuptools/__init__.py b/setuptools/__init__.py index f1b9bfe9b8..b3e78edab6 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -108,11 +108,13 @@ def _fetch_build_eggs(dist: Distribution): raise -def setup(**attrs): +def setup(**attrs) -> Distribution: logging.configure() # Make sure we have any requirements needed to interpret 'attrs'. _install_setup_requires(attrs) - return distutils.core.setup(**attrs) + # Override return type of distutils.core.Distribution with setuptools.dist.Distribution + # (implicitly implemented via `setuptools.monkey.patch_all`). + return distutils.core.setup(**attrs) # type: ignore[return-value] setup.__doc__ = distutils.core.setup.__doc__ @@ -176,14 +178,14 @@ def __init__(self, dist: Distribution, **kw) -> None: @overload def reinitialize_command( self, command: str, reinit_subcommands: bool = False, **kw - ) -> _Command: ... + ) -> Command: ... # override distutils.cmd.Command with setuptools.Command @overload def reinitialize_command( self, command: _CommandT, reinit_subcommands: bool = False, **kw ) -> _CommandT: ... def reinitialize_command( self, command: str | _Command, reinit_subcommands: bool = False, **kw - ) -> _Command: + ) -> Command | _Command: cmd = _Command.reinitialize_command(self, command, reinit_subcommands) vars(cmd).update(kw) return cmd # pyright: ignore[reportReturnType] # pypa/distutils#307 diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index 8f2e930c73..0dc04f6cbb 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -39,7 +39,7 @@ import warnings from collections.abc import Iterable, Iterator, Mapping from pathlib import Path -from typing import TYPE_CHECKING, Union +from typing import TYPE_CHECKING, NoReturn, Union import setuptools @@ -74,14 +74,14 @@ def __init__(self, specifiers) -> None: class Distribution(setuptools.dist.Distribution): - def fetch_build_eggs(self, specifiers): + def fetch_build_eggs(self, specifiers) -> NoReturn: specifier_list = list(parse_strings(specifiers)) raise SetupRequirementsError(specifier_list) @classmethod @contextlib.contextmanager - def patch(cls): + def patch(cls) -> Iterator[None]: """ Replace distutils.dist.Distribution with this class @@ -304,7 +304,7 @@ def _get_build_requires( return requirements - def run_setup(self, setup_script: str = 'setup.py'): + def run_setup(self, setup_script: str = 'setup.py') -> None: # Note that we can reuse our build directory between calls # Correctness comes first, then optimization later __file__ = os.path.abspath(setup_script) @@ -327,10 +327,14 @@ def run_setup(self, setup_script: str = 'setup.py'): "setup-py-deprecated.html", ) - def get_requires_for_build_wheel(self, config_settings: _ConfigSettings = None): + def get_requires_for_build_wheel( + self, config_settings: _ConfigSettings = None + ) -> list[str]: return self._get_build_requires(config_settings, requirements=[]) - def get_requires_for_build_sdist(self, config_settings: _ConfigSettings = None): + def get_requires_for_build_sdist( + self, config_settings: _ConfigSettings = None + ) -> list[str]: return self._get_build_requires(config_settings, requirements=[]) def _bubble_up_info_directory( @@ -361,7 +365,7 @@ def _find_info_directory(self, metadata_directory: StrPath, suffix: str) -> Path def prepare_metadata_for_build_wheel( self, metadata_directory: StrPath, config_settings: _ConfigSettings = None - ): + ) -> str: sys.argv = [ *sys.argv[:1], *self._global_args(config_settings), @@ -417,7 +421,7 @@ def build_wheel( wheel_directory: StrPath, config_settings: _ConfigSettings = None, metadata_directory: StrPath | None = None, - ): + ) -> str: def _build(cmd: list[str]): with suppress_known_deprecation(): return self._build_with_temp_dir( @@ -442,7 +446,7 @@ def _build(cmd: list[str]): def build_sdist( self, sdist_directory: StrPath, config_settings: _ConfigSettings = None - ): + ) -> str: return self._build_with_temp_dir( ['sdist', '--formats', 'gztar'], '.tar.gz', sdist_directory, config_settings ) @@ -459,7 +463,7 @@ def build_editable( wheel_directory: StrPath, config_settings: _ConfigSettings = None, metadata_directory: StrPath | None = None, - ): + ) -> str: # XXX can or should we hide our editable_wheel command normally? info_dir = self._get_dist_info_dir(metadata_directory) opts = ["--dist-info-dir", info_dir] if info_dir else [] @@ -469,12 +473,14 @@ def build_editable( cmd, ".whl", wheel_directory, config_settings ) - def get_requires_for_build_editable(self, config_settings: _ConfigSettings = None): + def get_requires_for_build_editable( + self, config_settings: _ConfigSettings = None + ) -> list[str]: return self.get_requires_for_build_wheel(config_settings) def prepare_metadata_for_build_editable( self, metadata_directory: StrPath, config_settings: _ConfigSettings = None - ): + ) -> str: return self.prepare_metadata_for_build_wheel( metadata_directory, config_settings ) @@ -492,7 +498,7 @@ class _BuildMetaLegacyBackend(_BuildMetaBackend): and will eventually be removed. """ - def run_setup(self, setup_script: str = 'setup.py'): + def run_setup(self, setup_script: str = 'setup.py') -> None: # In order to maintain compatibility with scripts assuming that # the setup.py script is in a directory on the PYTHONPATH, inject # '' into sys.path. (pypa/setuptools#1642) diff --git a/setuptools/command/bdist_egg.py b/setuptools/command/bdist_egg.py index b66020c863..40aa0d4e87 100644 --- a/setuptools/command/bdist_egg.py +++ b/setuptools/command/bdist_egg.py @@ -9,19 +9,21 @@ import re import sys import textwrap +from collections.abc import Iterator from sysconfig import get_path, get_platform, get_python_version from types import CodeType -from typing import TYPE_CHECKING, Literal +from typing import TYPE_CHECKING, AnyStr, Literal from setuptools import Command from setuptools.extension import Library -from .._path import StrPathT, ensure_directory +from .._path import StrPath, StrPathT, ensure_directory from distutils import log from distutils.dir_util import mkpath, remove_tree if TYPE_CHECKING: + from _typeshed import GenericPath from typing_extensions import TypeAlias # Same as zipfile._ZipFileMode from typeshed @@ -40,7 +42,9 @@ def strip_module(filename): return filename -def sorted_walk(dir): +def sorted_walk( + dir: GenericPath[AnyStr], +) -> Iterator[tuple[AnyStr, list[AnyStr], list[AnyStr]]]: """Do os.walk in a reproducible way, independent of indeterministic filesystem readdir order """ @@ -161,7 +165,7 @@ def call_command(self, cmdname, **kw): self.run_command(cmdname) return cmd - def run(self): # noqa: C901 # is too complex (14) # FIXME + def run(self) -> None: # noqa: C901 # is too complex (14) # FIXME # Generate metadata first self.run_command("egg_info") # We run install_lib before install_data, because some data hacks @@ -232,7 +236,7 @@ def run(self): # noqa: C901 # is too complex (14) # FIXME self.egg_output, archive_root, verbose=self.verbose, - dry_run=self.dry_run, + dry_run=self.dry_run, # type: ignore[arg-type] # Is an actual boolean in vendored _distutils mode=self.gen_header(), ) if not self.keep_temp: @@ -245,7 +249,7 @@ def run(self): # noqa: C901 # is too complex (14) # FIXME self.egg_output, )) - def zap_pyfiles(self): + def zap_pyfiles(self) -> None: log.info("Removing .py files from temporary directory") for base, dirs, files in walk_egg(self.bdist_dir): for name in files: @@ -260,6 +264,8 @@ def zap_pyfiles(self): pattern = r'(?P.+)\.(?P[^.]+)\.pyc' m = re.match(pattern, name) + # We shouldn't find any non-pyc files in __pycache__ + assert m is not None path_new = os.path.join(base, os.pardir, m.group('name') + '.pyc') log.info(f"Renaming file from [{path_old}] to [{path_new}]") try: @@ -323,7 +329,7 @@ def get_ext_outputs(self): NATIVE_EXTENSIONS: dict[str, None] = dict.fromkeys('.dll .so .dylib .pyd'.split()) -def walk_egg(egg_dir): +def walk_egg(egg_dir: StrPath) -> Iterator[tuple[str, list[str], list[str]]]: """Walk an unpacked egg's contents, skipping the metadata directory""" walker = sorted_walk(egg_dir) base, dirs, files = next(walker) @@ -409,7 +415,7 @@ def scan_module(egg_dir, base, name, stubs): return safe -def iter_symbols(code): +def iter_symbols(code: CodeType) -> Iterator[str]: """Yield names and strings used by `code` and its nested code objects""" yield from code.co_names for const in code.co_consts: diff --git a/setuptools/command/build_ext.py b/setuptools/command/build_ext.py index af73fff7a5..f2f38e9f72 100644 --- a/setuptools/command/build_ext.py +++ b/setuptools/command/build_ext.py @@ -90,7 +90,7 @@ class build_ext(_build_ext): editable_mode = False inplace = False - def run(self): + def run(self) -> None: """Build extensions in build directory, then copy if --inplace""" old_inplace, self.inplace = self.inplace, False _build_ext.run(self) @@ -220,7 +220,7 @@ def finalize_options(self) -> None: if self.editable_mode: self.inplace = True - def setup_shlib_compiler(self): + def setup_shlib_compiler(self) -> None: compiler = self.shlib_compiler = new_compiler( compiler=self.compiler, dry_run=self.dry_run, force=self.force ) diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index 2f6fcb7cdc..339699dbbc 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -41,7 +41,7 @@ class build_py(orig.build_py): editable_mode: bool = False existing_egg_info_dir: StrPath | None = None #: Private API, internal use only. - def finalize_options(self): + 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 {} @@ -93,7 +93,7 @@ def _get_data_files(self): self.analyze_manifest() return list(map(self._get_pkg_data_files, self.packages or ())) - def get_data_files_without_manifest(self): + def get_data_files_without_manifest(self) -> list[tuple[str, str, str, list[str]]]: """ Generate list of ``(package,src_dir,build_dir,filenames)`` tuples, but without triggering any attempt to analyze or build the manifest. @@ -103,7 +103,7 @@ def get_data_files_without_manifest(self): self.__dict__.setdefault('manifest_files', {}) return list(map(self._get_pkg_data_files, self.packages or ())) - def _get_pkg_data_files(self, package): + def _get_pkg_data_files(self, package: str) -> tuple[str, str, str, list[str]]: # Locate package source directory src_dir = self.get_package_dir(package) @@ -272,7 +272,7 @@ def initialize_options(self): self.editable_mode = False self.existing_egg_info_dir = None - def get_package_dir(self, package): + def get_package_dir(self, package: str) -> str: res = orig.build_py.get_package_dir(self, package) if self.distribution.src_root is not None: return os.path.join(self.distribution.src_root, res) diff --git a/setuptools/command/develop.py b/setuptools/command/develop.py index 1f704fcee8..2d468845e5 100644 --- a/setuptools/command/develop.py +++ b/setuptools/command/develop.py @@ -1,6 +1,7 @@ import site import subprocess import sys +from typing import cast from setuptools import Command from setuptools.warnings import SetuptoolsDeprecationWarning @@ -27,18 +28,20 @@ class develop(Command): prefix = None index_url = None - def run(self): - cmd = ( + def run(self) -> None: + # Casting because mypy doesn't understand bool mult conditionals + cmd = cast( + list[str], [sys.executable, '-m', 'pip', 'install', '-e', '.', '--use-pep517'] + ['--target', self.install_dir] * bool(self.install_dir) + ['--no-deps'] * self.no_deps + ['--user'] * self.user + ['--prefix', self.prefix] * bool(self.prefix) - + ['--index-url', self.index_url] * bool(self.index_url) + + ['--index-url', self.index_url] * bool(self.index_url), ) subprocess.check_call(cmd) - def initialize_options(self): + def initialize_options(self) -> None: DevelopDeprecationWarning.emit() def finalize_options(self) -> None: diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 7e00ae2cea..2e40fcf06c 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -2,6 +2,8 @@ Create a distribution's .egg-info directory and contents""" +from __future__ import annotations + import functools import os import re @@ -196,11 +198,11 @@ def initialize_options(self): # allow the 'tag_svn_revision' to be detected and # set, supporting sdists built on older Setuptools. @property - def tag_svn_revision(self) -> None: + def tag_svn_revision(self) -> int | None: pass @tag_svn_revision.setter - def tag_svn_revision(self, value): + def tag_svn_revision(self, value) -> None: pass #################################### diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py index 1aed1d5e4e..17279ac421 100644 --- a/setuptools/command/sdist.py +++ b/setuptools/command/sdist.py @@ -3,6 +3,7 @@ import contextlib import os import re +from collections.abc import Iterator from itertools import chain from typing import ClassVar @@ -16,7 +17,7 @@ _default_revctrl = list -def walk_revctrl(dirname=''): +def walk_revctrl(dirname='') -> Iterator: """Find all files under revision control""" for ep in metadata.entry_points(group='setuptools.file_finders'): yield from ep.load()(dirname) @@ -195,7 +196,7 @@ def _manifest_is_not_generated(self): first_line = fp.readline() return first_line != b'# file GENERATED by distutils, do NOT edit\n' - def read_manifest(self): + def read_manifest(self) -> None: """Read the manifest file (named by 'self.manifest') and use it to fill in 'self.filelist', the list of files to include in the source distribution. diff --git a/setuptools/command/setopt.py b/setuptools/command/setopt.py index 678a0593d6..43cb593999 100644 --- a/setuptools/command/setopt.py +++ b/setuptools/command/setopt.py @@ -27,7 +27,7 @@ def config_file(kind="local"): raise ValueError("config_file() type must be 'local', 'global', or 'user'", kind) -def edit_config(filename, settings, dry_run=False): +def edit_config(filename, settings, dry_run=False) -> None: """Edit a configuration file to include `settings` `settings` is a dictionary of dictionaries or ``None`` values, keyed by @@ -88,7 +88,7 @@ def initialize_options(self): self.user_config = None self.filename = None - def finalize_options(self): + def finalize_options(self) -> None: filenames = [] if self.global_config: filenames.append(config_file('global')) diff --git a/setuptools/command/test.py b/setuptools/command/test.py index 341b11a20e..5d03c91102 100644 --- a/setuptools/command/test.py +++ b/setuptools/command/test.py @@ -1,5 +1,7 @@ from __future__ import annotations +from typing import NoReturn + from setuptools import Command from setuptools.warnings import SetuptoolsDeprecationWarning @@ -35,11 +37,11 @@ class _test(Command): ('test-runner=', 'r', "Test runner to use"), ] - def initialize_options(self): + def initialize_options(self) -> None: pass - def finalize_options(self): + def finalize_options(self) -> None: pass - def run(self): + def run(self) -> NoReturn: raise RuntimeError("Support for the test command was removed in Setuptools 72") diff --git a/setuptools/config/expand.py b/setuptools/config/expand.py index 531f965013..dc066d9427 100644 --- a/setuptools/config/expand.py +++ b/setuptools/config/expand.py @@ -390,7 +390,7 @@ def __init__(self, distribution: Distribution) -> None: self._dist = distribution self._called = False - def __call__(self): + def __call__(self) -> None: """Trigger the automatic package discovery, if it is still necessary.""" if not self._called: self._called = True @@ -404,7 +404,7 @@ def __exit__( exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None, - ): + ) -> None: if self._called: self._dist.set_defaults.analyse_name() # Now we can set a default name diff --git a/setuptools/config/setupcfg.py b/setuptools/config/setupcfg.py index 633aa9d45d..121a0febda 100644 --- a/setuptools/config/setupcfg.py +++ b/setuptools/config/setupcfg.py @@ -14,6 +14,7 @@ import contextlib import functools import os +from abc import abstractmethod from collections import defaultdict from collections.abc import Iterable, Iterator from functools import partial, wraps @@ -269,7 +270,8 @@ def _section_options( yield name.lstrip('.'), value @property - def parsers(self): + @abstractmethod + def parsers(self) -> dict[str, Callable]: """Metadata item name to parser function mapping.""" raise NotImplementedError( f'{self.__class__.__name__} must provide .parsers property' @@ -547,7 +549,7 @@ def __init__( self.root_dir = root_dir @property - def parsers(self): + def parsers(self) -> dict[str, Callable]: """Metadata item name to parser function mapping.""" parse_list_static = self._get_parser_compound(self._parse_list, _static.List) parse_dict_static = self._get_parser_compound(self._parse_dict, _static.Dict) @@ -631,7 +633,7 @@ def _parse_requirements_list(self, label: str, value: str): # ^-- Use `_static.List` to mark a non-`Dynamic` Core Metadata @property - def parsers(self): + def parsers(self) -> dict[str, Callable]: """Metadata item name to parser function mapping.""" parse_list = self._parse_list parse_bool = self._parse_bool diff --git a/setuptools/dist.py b/setuptools/dist.py index 6474f54122..b0ae193256 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -809,7 +809,7 @@ def _finalize_setup_keywords(self): if value is not None: ep.load()(self, ep.name, value) - def get_egg_cache_dir(self): + def get_egg_cache_dir(self) -> str: from . import windows_support egg_cache_dir = os.path.join(os.curdir, '.eggs') @@ -1056,7 +1056,7 @@ def get_cmdline_options(self) -> dict[str, dict[str, str | None]]: return d - def iter_distribution_names(self): + def iter_distribution_names(self) -> Iterator[str]: """Yield all packages, modules, and extension names in distribution""" yield from self.packages or () diff --git a/setuptools/extension.py b/setuptools/extension.py index 76e03d9d6b..3e63cbe12a 100644 --- a/setuptools/extension.py +++ b/setuptools/extension.py @@ -2,6 +2,7 @@ import functools import re +from collections.abc import Iterable from typing import TYPE_CHECKING from setuptools._path import StrPath @@ -13,7 +14,7 @@ import distutils.extension -def _have_cython(): +def _have_cython() -> bool: """ Return True if Cython can be imported. """ @@ -52,8 +53,9 @@ class Extension(_Extension): the full name of the extension, including any packages -- ie. *not* a filename or pathname, but Python dotted name - :arg list[str|os.PathLike[str]] sources: - list of source filenames, relative to the distribution root + :arg Iterable[str | os.PathLike[str]] sources: + iterable of source filenames, (except strings, which could be misinterpreted + as a single filename), relative to the distribution root (where the setup script lives), in Unix form (slash-separated) for portability. Source files may be C, C++, SWIG (.i), platform-specific resource files, or whatever else is recognized @@ -143,7 +145,7 @@ class Extension(_Extension): def __init__( self, name: str, - sources: list[StrPath], + sources: Iterable[StrPath], *args, py_limited_api: bool = False, **kw, diff --git a/setuptools/installer.py b/setuptools/installer.py index 2c26e3a1f4..36a8b09227 100644 --- a/setuptools/installer.py +++ b/setuptools/installer.py @@ -27,7 +27,7 @@ def _fixup_find_links(find_links): return find_links -def fetch_build_egg(dist, req): +def fetch_build_egg(dist, req) -> metadata.Distribution | metadata.PathDistribution: """Fetch an egg needed for building. Use pip/wheel to fetch/build a wheel.""" @@ -127,7 +127,7 @@ def _fetch_build_egg_no_warn(dist, req): # noqa: C901 # is too complex (16) # return metadata.Distribution.at(dist_location + '/EGG-INFO') -def strip_marker(req): +def strip_marker(req) -> packaging.requirements.Requirement: """ Return a new requirement without the environment marker to avoid calling pip with something like `babel; extra == "i18n"`, which diff --git a/setuptools/monkey.py b/setuptools/monkey.py index 6ad1abac29..24bb8180f9 100644 --- a/setuptools/monkey.py +++ b/setuptools/monkey.py @@ -69,7 +69,7 @@ def get_unpatched_class(cls: type[_T]) -> type[_T]: return base -def patch_all(): +def patch_all() -> None: import setuptools # we can't patch distutils.cmd, alas @@ -105,7 +105,7 @@ def _patch_distribution_metadata(): setattr(distutils.dist.DistributionMetadata, attr, new_val) -def patch_func(replacement, target_mod, func_name): +def patch_func(replacement, target_mod, func_name) -> None: """ Patch func_name in target_mod with replacement diff --git a/setuptools/msvc.py b/setuptools/msvc.py index 698b23d7af..8790c92442 100644 --- a/setuptools/msvc.py +++ b/setuptools/msvc.py @@ -13,7 +13,7 @@ import os import os.path import platform -from typing import TYPE_CHECKING, TypedDict +from typing import TYPE_CHECKING, TypedDict, overload from more_itertools import unique_everseen @@ -53,11 +53,11 @@ class PlatformInfo: current_cpu = environ.get('processor_architecture', '').lower() - def __init__(self, arch) -> None: + def __init__(self, arch: str) -> None: self.arch = arch.lower().replace('x64', 'amd64') @property - def target_cpu(self): + def target_cpu(self) -> str: """ Return Target CPU architecture. @@ -68,7 +68,7 @@ def target_cpu(self): """ return self.arch[self.arch.find('_') + 1 :] - def target_is_x86(self): + def target_is_x86(self) -> bool: """ Return True if target CPU is x86 32 bits.. @@ -79,7 +79,7 @@ def target_is_x86(self): """ return self.target_cpu == 'x86' - def current_is_x86(self): + def current_is_x86(self) -> bool: """ Return True if current CPU is x86 32 bits.. @@ -179,11 +179,11 @@ class RegistryInfo: winreg.HKEY_CLASSES_ROOT, ) - def __init__(self, platform_info) -> None: + def __init__(self, platform_info: PlatformInfo) -> None: self.pi = platform_info @property - def visualstudio(self) -> str: + def visualstudio(self) -> LiteralString: """ Microsoft Visual Studio root registry key. @@ -195,7 +195,7 @@ def visualstudio(self) -> str: return 'VisualStudio' @property - def sxs(self): + def sxs(self) -> LiteralString: """ Microsoft Visual Studio SxS registry key. @@ -207,7 +207,7 @@ def sxs(self): return os.path.join(self.visualstudio, 'SxS') @property - def vc(self): + def vc(self) -> LiteralString: """ Microsoft Visual C++ VC7 registry key. @@ -219,7 +219,7 @@ def vc(self): return os.path.join(self.sxs, 'VC7') @property - def vs(self): + def vs(self) -> LiteralString: """ Microsoft Visual Studio VS7 registry key. @@ -231,7 +231,7 @@ def vs(self): return os.path.join(self.sxs, 'VS7') @property - def vc_for_python(self) -> str: + def vc_for_python(self) -> LiteralString: """ Microsoft Visual C++ for Python registry key. @@ -243,7 +243,7 @@ def vc_for_python(self) -> str: return r'DevDiv\VCForPython' @property - def microsoft_sdk(self) -> str: + def microsoft_sdk(self) -> LiteralString: """ Microsoft SDK registry key. @@ -255,7 +255,7 @@ def microsoft_sdk(self) -> str: return 'Microsoft SDKs' @property - def windows_sdk(self): + def windows_sdk(self) -> LiteralString: """ Microsoft Windows/Platform SDK registry key. @@ -267,7 +267,7 @@ def windows_sdk(self): return os.path.join(self.microsoft_sdk, 'Windows') @property - def netfx_sdk(self): + def netfx_sdk(self) -> LiteralString: """ Microsoft .NET Framework SDK registry key. @@ -279,7 +279,7 @@ def netfx_sdk(self): return os.path.join(self.microsoft_sdk, 'NETFXSDK') @property - def windows_kits_roots(self) -> str: + def windows_kits_roots(self) -> LiteralString: """ Microsoft Windows Kits Roots registry key. @@ -290,7 +290,11 @@ def windows_kits_roots(self) -> str: """ return r'Windows Kits\Installed Roots' - def microsoft(self, key, x86=False): + @overload + def microsoft(self, key: LiteralString, x86: bool = False) -> LiteralString: ... + @overload + def microsoft(self, key: str, x86: bool = False) -> str: ... # type: ignore[misc] + def microsoft(self, key: str, x86: bool = False) -> str: """ Return key in Microsoft software registry. @@ -298,7 +302,7 @@ def microsoft(self, key, x86=False): ---------- key: str Registry key path where look. - x86: str + x86: bool Force x86 software registry. Return @@ -369,7 +373,9 @@ class SystemInfo: ProgramFiles = environ.get('ProgramFiles', '') ProgramFilesx86 = environ.get('ProgramFiles(x86)', ProgramFiles) - def __init__(self, registry_info: RegistryInfo, vc_ver=None) -> None: + def __init__( + self, registry_info: RegistryInfo, vc_ver: float | None = None + ) -> None: self.ri = registry_info self.pi = self.ri.pi @@ -398,7 +404,7 @@ def _find_latest_available_vs_ver(self): vc_vers.update(self.known_vs_paths) return sorted(vc_vers)[-1] - def find_reg_vs_vers(self): + def find_reg_vs_vers(self) -> list[float]: """ Find Microsoft Visual Studio versions available in registry. @@ -599,7 +605,7 @@ def WindowsSdkVersion(self) -> tuple[LiteralString, ...]: return () @property - def WindowsSdkLastVersion(self): + def WindowsSdkLastVersion(self) -> str: """ Microsoft Windows SDK last version. @@ -741,7 +747,7 @@ def UniversalCRTSdkLastVersion(self) -> str: raise @property - def NetFxSdkVersion(self): + def NetFxSdkVersion(self) -> tuple[LiteralString, ...]: """ Microsoft .NET Framework SDK versions. diff --git a/setuptools/wheel.py b/setuptools/wheel.py index 124e01ad2f..9366303154 100644 --- a/setuptools/wheel.py +++ b/setuptools/wheel.py @@ -8,6 +8,7 @@ import posixpath import re import zipfile +from collections.abc import Iterator from packaging.requirements import Requirement from packaging.tags import sys_tags @@ -65,7 +66,7 @@ def unpack(src_dir, dst_dir) -> None: @contextlib.contextmanager -def disable_info_traces(): +def disable_info_traces() -> Iterator[None]: """ Temporarily disable info traces. """