From fb5487b4a58271b96a94cb790264df15e8069bd2 Mon Sep 17 00:00:00 2001 From: Avasam Date: Sun, 10 Nov 2024 18:07:21 -0500 Subject: [PATCH 1/7] Merge typeshed return annotations --- setuptools/__init__.py | 9 +-- setuptools/build_meta.py | 30 +++++----- setuptools/command/bdist_egg.py | 18 +++--- setuptools/command/bdist_wheel.py | 2 +- setuptools/command/build_ext.py | 4 +- setuptools/command/build_py.py | 10 ++-- setuptools/command/develop.py | 2 +- setuptools/command/easy_install.py | 4 +- setuptools/command/editable_wheel.py | 2 +- setuptools/command/egg_info.py | 8 ++- setuptools/command/install_egg_info.py | 2 +- setuptools/command/saveopts.py | 2 +- setuptools/command/sdist.py | 5 +- setuptools/command/setopt.py | 4 +- setuptools/command/test.py | 8 ++- setuptools/config/expand.py | 6 +- setuptools/config/setupcfg.py | 8 ++- setuptools/dist.py | 8 +-- setuptools/extension.py | 2 +- setuptools/monkey.py | 4 +- setuptools/msvc.py | 79 ++++++++++++++------------ setuptools/package_index.py | 17 +++--- setuptools/sandbox.py | 4 +- setuptools/wheel.py | 3 +- 24 files changed, 133 insertions(+), 108 deletions(-) diff --git a/setuptools/__init__.py b/setuptools/__init__.py index 4f5c01708a..82c8d0179f 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -110,11 +110,12 @@ 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 + return distutils.core.setup(**attrs) # type: ignore[return-value] setup.__doc__ = distutils.core.setup.__doc__ @@ -216,14 +217,14 @@ def ensure_string_list(self, option: str) -> 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 23471accb6..fd3e00d46e 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 @@ -77,14 +77,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 @@ -307,7 +307,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) @@ -330,10 +330,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( @@ -364,7 +368,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), @@ -420,7 +424,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( @@ -445,7 +449,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 ) @@ -467,7 +471,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 [] @@ -479,12 +483,12 @@ def build_editable( 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 ) @@ -502,7 +506,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 04d7e945bc..bcfabe292d 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_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 """ @@ -163,7 +167,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 @@ -247,7 +251,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: @@ -325,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) @@ -411,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/bdist_wheel.py b/setuptools/command/bdist_wheel.py index 8cf91538f9..ff83ceeb79 100644 --- a/setuptools/command/bdist_wheel.py +++ b/setuptools/command/bdist_wheel.py @@ -391,7 +391,7 @@ def get_tag(self) -> tuple[str, str, str]: ) return tag - def run(self): + def run(self) -> None: build_scripts = self.reinitialize_command("build_scripts") build_scripts.executable = "python" build_scripts.force = True diff --git a/setuptools/command/build_ext.py b/setuptools/command/build_ext.py index f098246b9b..9bf51e05e0 100644 --- a/setuptools/command/build_ext.py +++ b/setuptools/command/build_ext.py @@ -93,7 +93,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, 0 _build_ext.run(self) @@ -223,7 +223,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 f8c9b11676..52569c5d3c 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: str | 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 {} @@ -100,7 +100,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. @@ -110,7 +110,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) @@ -178,7 +178,7 @@ def build_package_data(self) -> None: _outf, _copied = self.copy_file(srcfile, target) make_writable(target) - def analyze_manifest(self): + def analyze_manifest(self) -> None: self.manifest_files = mf = {} if not self.distribution.include_package_data: return @@ -277,7 +277,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 7eee29d491..f16c14dfb3 100644 --- a/setuptools/command/develop.py +++ b/setuptools/command/develop.py @@ -26,7 +26,7 @@ class develop(namespaces.DevelopInstaller, easy_install): command_consumes_arguments = False # override base - def run(self): + def run(self) -> None: if self.uninstall: self.multi_version = True self.uninstall_link() diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 21e6f008d7..e2acad23b9 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -239,7 +239,7 @@ def _render_version(): print(f'setuptools {dist.version} from {dist.location} (Python {ver})') raise SystemExit - def finalize_options(self): # noqa: C901 # is too complex (25) # FIXME + def finalize_options(self) -> None: # noqa: C901 # is too complex (25) # FIXME self.version and self._render_version() py_version = sys.version.split()[0] @@ -748,7 +748,7 @@ def install_item( return dist return None - def select_scheme(self, name): + def select_scheme(self, name) -> None: try: install._select_scheme(self, name) except AttributeError: diff --git a/setuptools/command/editable_wheel.py b/setuptools/command/editable_wheel.py index 30570e092a..d4ef24038d 100644 --- a/setuptools/command/editable_wheel.py +++ b/setuptools/command/editable_wheel.py @@ -779,7 +779,7 @@ def _empty_dir(dir_: _P) -> _P: class _NamespaceInstaller(namespaces.Installer): - def __init__(self, distribution, installation_dir, editable_name, src_root): + def __init__(self, distribution, installation_dir, editable_name, src_root) -> None: self.distribution = distribution self.src_root = src_root self.installation_dir = installation_dir diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 1411ac3d89..2a24f310ef 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 @@ -195,11 +197,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 #################################### @@ -330,7 +332,7 @@ def __init__( super().__init__(warn, debug_print) self.ignore_egg_info_dir = ignore_egg_info_dir - def process_template_line(self, line): + def process_template_line(self, line) -> None: # Parse the line: split it up, make sure the right number of words # is there, and return the relevant words. 'action' is always # defined: it's the first word of the line. Which of the other diff --git a/setuptools/command/install_egg_info.py b/setuptools/command/install_egg_info.py index be4dd7b229..597a04228e 100644 --- a/setuptools/command/install_egg_info.py +++ b/setuptools/command/install_egg_info.py @@ -20,7 +20,7 @@ class install_egg_info(namespaces.Installer, Command): def initialize_options(self): self.install_dir = None - def finalize_options(self): + def finalize_options(self) -> None: self.set_undefined_options('install_lib', ('install_dir', 'install_dir')) ei_cmd = self.get_finalized_command("egg_info") basename = f"{ei_cmd._get_egg_basename()}.egg-info" diff --git a/setuptools/command/saveopts.py b/setuptools/command/saveopts.py index f175de1015..48dcd3bc4b 100644 --- a/setuptools/command/saveopts.py +++ b/setuptools/command/saveopts.py @@ -6,7 +6,7 @@ class saveopts(option_base): description = "save supplied options to setup.cfg or other config file" - def run(self): + def run(self) -> None: dist = self.distribution settings = {} diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py index be69b33500..246a01e46b 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 75393f32f0..1c07e34f14 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 54c68bed4f..1c48961fd5 100644 --- a/setuptools/config/expand.py +++ b/setuptools/config/expand.py @@ -387,7 +387,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 @@ -401,7 +401,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 @@ -411,7 +411,7 @@ def _get_package_dir(self) -> Mapping[str, str]: return {} if pkg_dir is None else pkg_dir @property - def package_dir(self) -> Mapping[str, str]: + def package_dir(self) -> LazyMappingProxy[str, str]: """Proxy to ``package_dir`` that may trigger auto-discovery when used.""" return LazyMappingProxy(self._get_package_dir) diff --git a/setuptools/config/setupcfg.py b/setuptools/config/setupcfg.py index b35d0b00cd..1a6830dda4 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( '%s must provide .parsers property' % self.__class__.__name__ @@ -546,7 +548,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 = self._parse_list parse_file = partial(self._parse_file, root_dir=self.root_dir) @@ -623,7 +625,7 @@ def _parse_requirements_list(self, label: str, value: str): return [line for line in parsed if not line.startswith("#")] @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 6062c4f868..fde9d0dd94 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -6,7 +6,7 @@ import os import re import sys -from collections.abc import Iterable, MutableMapping, Sequence +from collections.abc import Iterable, Iterator, MutableMapping, Sequence from glob import iglob from pathlib import Path from typing import TYPE_CHECKING, Any, Union @@ -696,7 +696,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') @@ -904,7 +904,7 @@ def _parse_command_opts(self, parser, args): return nargs - def get_cmdline_options(self): + def get_cmdline_options(self) -> dict[str, dict[str, str | None]]: """Return a '{cmd: {opt:val}}' map of all command-line options Option names are all long, but do not include the leading '--', and @@ -942,7 +942,7 @@ def get_cmdline_options(self): 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..98e819a4ae 100644 --- a/setuptools/extension.py +++ b/setuptools/extension.py @@ -13,7 +13,7 @@ import distutils.extension -def _have_cython(): +def _have_cython() -> bool: """ Return True if Cython can be imported. """ diff --git a/setuptools/monkey.py b/setuptools/monkey.py index 07919722b8..7bea2374a2 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 6492d3be9d..a8b74a6503 100644 --- a/setuptools/msvc.py +++ b/setuptools/msvc.py @@ -13,14 +13,14 @@ 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 import distutils.errors if TYPE_CHECKING: - from typing_extensions import NotRequired + from typing_extensions import LiteralString, NotRequired # https://github.com/python/mypy/issues/8166 if not TYPE_CHECKING and platform.system() == 'Windows': @@ -50,11 +50,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. @@ -65,7 +65,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.. @@ -76,7 +76,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.. @@ -135,7 +135,7 @@ def target_dir(self, hidex86=False, x64=False) -> str: else r'\%s' % self.target_cpu ) - def cross_dir(self, forcex86=False): + def cross_dir(self, forcex86=False) -> str: r""" Cross platform specific subfolder. @@ -180,7 +180,7 @@ def __init__(self, platform_info) -> None: self.pi = platform_info @property - def visualstudio(self) -> str: + def visualstudio(self) -> LiteralString: """ Microsoft Visual Studio root registry key. @@ -192,7 +192,7 @@ def visualstudio(self) -> str: return 'VisualStudio' @property - def sxs(self): + def sxs(self) -> LiteralString: """ Microsoft Visual Studio SxS registry key. @@ -204,7 +204,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. @@ -216,7 +216,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. @@ -228,7 +228,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. @@ -240,7 +240,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. @@ -252,7 +252,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. @@ -264,7 +264,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. @@ -276,7 +276,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. @@ -287,7 +287,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. @@ -306,7 +310,7 @@ def microsoft(self, key, x86=False): node64 = '' if self.pi.current_is_x86() or x86 else 'Wow6432Node' return os.path.join('Software', node64, 'Microsoft', key) - def lookup(self, key, name): + def lookup(self, key: str, name: str) -> str | None: """ Look for values in registry in Microsoft software registry. @@ -366,7 +370,9 @@ class SystemInfo: ProgramFiles = environ.get('ProgramFiles', '') ProgramFilesx86 = environ.get('ProgramFiles(x86)', ProgramFiles) - def __init__(self, registry_info, 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 @@ -395,7 +401,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. @@ -426,7 +432,7 @@ def find_reg_vs_vers(self): vs_vers.append(ver) return sorted(vs_vers) - def find_programdata_vs_vers(self): + def find_programdata_vs_vers(self) -> dict[float, str]: r""" Find Visual studio 2017+ versions from information in "C:\ProgramData\Microsoft\VisualStudio\Packages\_Instances". @@ -486,7 +492,7 @@ def _as_float_version(version): return float('.'.join(version.split('.')[:2])) @property - def VSInstallDir(self): + def VSInstallDir(self) -> str: """ Microsoft Visual Studio directory. @@ -504,7 +510,7 @@ def VSInstallDir(self): return self.ri.lookup(self.ri.vs, '%0.1f' % self.vs_ver) or default @property - def VCInstallDir(self): + def VCInstallDir(self) -> str: """ Microsoft Visual C++ directory. @@ -573,7 +579,7 @@ def _guess_vc_legacy(self): return self.ri.lookup(self.ri.vc, '%0.1f' % self.vs_ver) or default_vc @property - def WindowsSdkVersion(self): + def WindowsSdkVersion(self) -> tuple[LiteralString, ...] | None: """ Microsoft Windows SDK versions for specified MSVC++ version. @@ -595,7 +601,7 @@ def WindowsSdkVersion(self): return None @property - def WindowsSdkLastVersion(self): + def WindowsSdkLastVersion(self) -> str: """ Microsoft Windows SDK last version. @@ -607,7 +613,7 @@ def WindowsSdkLastVersion(self): return self._use_last_dir_name(os.path.join(self.WindowsSdkDir, 'lib')) @property - def WindowsSdkDir(self): # noqa: C901 # is too complex (12) # FIXME + def WindowsSdkDir(self) -> str: # noqa: C901 # is too complex (12) # FIXME """ Microsoft Windows SDK directory. @@ -650,7 +656,7 @@ def WindowsSdkDir(self): # noqa: C901 # is too complex (12) # FIXME return sdkdir @property - def WindowsSDKExecutablePath(self): + def WindowsSDKExecutablePath(self) -> str | None: """ Microsoft Windows SDK executable directory. @@ -687,7 +693,7 @@ def WindowsSDKExecutablePath(self): return None @property - def FSharpInstallDir(self): + def FSharpInstallDir(self) -> str: """ Microsoft Visual F# directory. @@ -700,7 +706,7 @@ def FSharpInstallDir(self): return self.ri.lookup(path, 'productdir') or '' @property - def UniversalCRTSdkDir(self): + def UniversalCRTSdkDir(self) -> str | None: """ Microsoft Universal CRT SDK directory. @@ -721,7 +727,7 @@ def UniversalCRTSdkDir(self): return None @property - def UniversalCRTSdkLastVersion(self): + def UniversalCRTSdkLastVersion(self) -> str: """ Microsoft Universal C Runtime SDK last version. @@ -733,7 +739,7 @@ def UniversalCRTSdkLastVersion(self): return self._use_last_dir_name(os.path.join(self.UniversalCRTSdkDir, 'lib')) @property - def NetFxSdkVersion(self): + def NetFxSdkVersion(self) -> tuple[LiteralString, ...]: """ Microsoft .NET Framework SDK versions. @@ -750,7 +756,7 @@ def NetFxSdkVersion(self): ) @property - def NetFxSdkDir(self): + def NetFxSdkDir(self) -> str | None: """ Microsoft .NET Framework SDK directory. @@ -759,7 +765,6 @@ def NetFxSdkDir(self): str path """ - sdkdir = '' for ver in self.NetFxSdkVersion: loc = os.path.join(self.ri.netfx_sdk, ver) sdkdir = self.ri.lookup(loc, 'kitsinstallationfolder') @@ -768,7 +773,7 @@ def NetFxSdkDir(self): return sdkdir @property - def FrameworkDir32(self): + def FrameworkDir32(self) -> str: """ Microsoft .NET Framework 32bit directory. @@ -784,7 +789,7 @@ def FrameworkDir32(self): return self.ri.lookup(self.ri.vc, 'frameworkdir32') or guess_fw @property - def FrameworkDir64(self): + def FrameworkDir64(self) -> str: """ Microsoft .NET Framework 64bit directory. @@ -800,7 +805,7 @@ def FrameworkDir64(self): return self.ri.lookup(self.ri.vc, 'frameworkdir64') or guess_fw @property - def FrameworkVersion32(self): + def FrameworkVersion32(self) -> tuple[str, ...] | None: """ Microsoft .NET Framework 32bit versions. @@ -812,7 +817,7 @@ def FrameworkVersion32(self): return self._find_dot_net_versions(32) @property - def FrameworkVersion64(self): + def FrameworkVersion64(self) -> tuple[str, ...] | None: """ Microsoft .NET Framework 64bit versions. diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 97806e8ff8..3ae0f838ca 100644 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -18,6 +18,7 @@ import urllib.error import urllib.parse import urllib.request +from collections.abc import Iterator from fnmatch import translate from functools import wraps from typing import NamedTuple @@ -113,7 +114,7 @@ def egg_info_for_url(url): return base, fragment -def distros_for_url(url, metadata=None): +def distros_for_url(url, metadata=None) -> Iterator[Distribution]: """Yield egg or source distribution objects that might be found at a URL""" base, fragment = egg_info_for_url(url) yield from distros_for_location(url, base, metadata) @@ -125,7 +126,9 @@ def distros_for_url(url, metadata=None): ) -def distros_for_location(location, basename, metadata=None): +def distros_for_location( + location, basename, metadata=None +) -> list[Distribution] | Iterator[Distribution]: """Yield egg or source distribution objects based on basename""" if basename.endswith('.egg.zip'): basename = basename[:-4] # strip the .zip @@ -169,7 +172,7 @@ def distros_for_filename(filename, metadata=None): def interpret_distro_name( location, basename, metadata, py_version=None, precedence=SOURCE_DIST, platform=None -): +) -> Iterator[Distribution]: """Generate the interpretation of a source distro name Note: if `location` is a filesystem filename, you should call @@ -244,7 +247,7 @@ class ContentChecker: A null content checker that defines the interface for checking content """ - def feed(self, block): + def feed(self, block) -> None: """ Feed a block of data to the hash. """ @@ -256,7 +259,7 @@ def is_valid(self): """ return True - def report(self, reporter, template): + def report(self, reporter, template) -> None: """ Call reporter with information about the checker (hash name) substituted into the template. @@ -286,7 +289,7 @@ def from_url(cls, url): return ContentChecker() return cls(**match.groupdict()) - def feed(self, block): + def feed(self, block) -> None: self.hash.update(block) def is_valid(self): @@ -1017,7 +1020,7 @@ def __str__(self) -> str: class PyPIConfig(configparser.RawConfigParser): - def __init__(self): + def __init__(self) -> None: """ Load from ~/.pypirc """ diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py index 2d84242d66..88271cfc94 100644 --- a/setuptools/sandbox.py +++ b/setuptools/sandbox.py @@ -144,7 +144,7 @@ def __exit__( # suppress the exception return True - def resume(self): + def resume(self) -> None: "restore and re-raise any exception" if '_saved' not in vars(self): @@ -300,7 +300,7 @@ def __exit__( exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None, - ): + ) -> None: self._active = False builtins.open = _open self._copy(_os) diff --git a/setuptools/wheel.py b/setuptools/wheel.py index fb19f1a65a..9dac318da3 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.tags import sys_tags from packaging.utils import canonicalize_name @@ -62,7 +63,7 @@ def unpack(src_dir, dst_dir) -> None: @contextlib.contextmanager -def disable_info_traces(): +def disable_info_traces() -> Iterator[None]: """ Temporarily disable info traces. """ From af535338ec112f6aba1b901eae8ae17ecf5c7601 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 6 Nov 2024 13:32:46 -0500 Subject: [PATCH 2/7] ANN204 (missing return type for special methods) autofixes --- _distutils_hack/__init__.py | 2 +- pkg_resources/tests/test_resources.py | 2 +- pkg_resources/tests/test_working_set.py | 2 +- setuptools/__init__.py | 4 ++-- setuptools/build_meta.py | 2 +- setuptools/command/develop.py | 2 +- setuptools/command/easy_install.py | 2 +- setuptools/command/editable_wheel.py | 6 +++--- setuptools/command/egg_info.py | 4 +++- setuptools/config/expand.py | 6 +++--- setuptools/config/pyprojecttoml.py | 4 ++-- setuptools/config/setupcfg.py | 6 +++--- setuptools/depends.py | 2 +- setuptools/discovery.py | 4 ++-- setuptools/extension.py | 2 +- setuptools/msvc.py | 8 ++++---- setuptools/package_index.py | 2 +- setuptools/sandbox.py | 4 ++-- setuptools/wheel.py | 2 +- 19 files changed, 34 insertions(+), 32 deletions(-) diff --git a/_distutils_hack/__init__.py b/_distutils_hack/__init__.py index 6ee497b38f..94f71b99ec 100644 --- a/_distutils_hack/__init__.py +++ b/_distutils_hack/__init__.py @@ -90,7 +90,7 @@ def do_override(): class _TrivialRe: - def __init__(self, *patterns): + def __init__(self, *patterns) -> None: self._patterns = patterns def match(self, string): diff --git a/pkg_resources/tests/test_resources.py b/pkg_resources/tests/test_resources.py index 00fb5b3290..70436c0881 100644 --- a/pkg_resources/tests/test_resources.py +++ b/pkg_resources/tests/test_resources.py @@ -32,7 +32,7 @@ def pairwise(iterable): class Metadata(pkg_resources.EmptyProvider): """Mock object to return metadata as if from an on-disk distribution""" - def __init__(self, *pairs): + def __init__(self, *pairs) -> None: self.metadata = dict(pairs) def has_metadata(self, name) -> bool: diff --git a/pkg_resources/tests/test_working_set.py b/pkg_resources/tests/test_working_set.py index 0537bb69a4..7bb84952c1 100644 --- a/pkg_resources/tests/test_working_set.py +++ b/pkg_resources/tests/test_working_set.py @@ -56,7 +56,7 @@ def parse_distributions(s): class FakeInstaller: - def __init__(self, installable_dists): + def __init__(self, installable_dists) -> None: self._installable_dists = installable_dists def __call__(self, req): diff --git a/setuptools/__init__.py b/setuptools/__init__.py index b330e9aa3e..4f5c01708a 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -60,7 +60,7 @@ class MinimalDistribution(distutils.core.Distribution): fetch_build_eggs interface. """ - def __init__(self, attrs: Mapping[str, object]): + def __init__(self, attrs: Mapping[str, object]) -> None: _incl = 'dependency_links', 'setup_requires' filtered = {k: attrs[k] for k in set(_incl) & set(attrs)} super().__init__(filtered) @@ -167,7 +167,7 @@ class Command(_Command): command_consumes_arguments = False distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution - def __init__(self, dist: Distribution, **kw): + def __init__(self, dist: Distribution, **kw) -> None: """ Construct the command for dist, updating vars(self) with any keyword parameters. diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index 3500b2dfd1..23471accb6 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -72,7 +72,7 @@ class SetupRequirementsError(BaseException): - def __init__(self, specifiers): + def __init__(self, specifiers) -> None: self.specifiers = specifiers diff --git a/setuptools/command/develop.py b/setuptools/command/develop.py index 19908d5d70..7eee29d491 100644 --- a/setuptools/command/develop.py +++ b/setuptools/command/develop.py @@ -185,7 +185,7 @@ class VersionlessRequirement: 'foo' """ - def __init__(self, dist): + def __init__(self, dist) -> None: self.__dist = dist def __getattr__(self, name: str): diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 37f01ed46e..21e6f008d7 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1612,7 +1612,7 @@ def get_exe_prefixes(exe_filename): class PthDistributions(Environment): """A .pth file with Distribution paths in it""" - def __init__(self, filename, sitedirs=()): + def __init__(self, filename, sitedirs=()) -> None: self.filename = filename self.sitedirs = list(map(normalize_path, sitedirs)) self.basedir = normalize_path(os.path.dirname(self.filename)) diff --git a/setuptools/command/editable_wheel.py b/setuptools/command/editable_wheel.py index cae643618c..30570e092a 100644 --- a/setuptools/command/editable_wheel.py +++ b/setuptools/command/editable_wheel.py @@ -392,7 +392,7 @@ def __exit__( class _StaticPth: - def __init__(self, dist: Distribution, name: str, path_entries: list[Path]): + def __init__(self, dist: Distribution, name: str, path_entries: list[Path]) -> None: self.dist = dist self.name = name self.path_entries = path_entries @@ -436,7 +436,7 @@ def __init__( name: str, auxiliary_dir: StrPath, build_lib: StrPath, - ): + ) -> None: self.auxiliary_dir = Path(auxiliary_dir) self.build_lib = Path(build_lib).resolve() self._file = dist.get_command_obj("build_py").copy_file @@ -496,7 +496,7 @@ def __exit__( class _TopLevelFinder: - def __init__(self, dist: Distribution, name: str): + def __init__(self, dist: Distribution, name: str) -> None: self.dist = dist self.name = name diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 56ddb100e0..1411ac3d89 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -324,7 +324,9 @@ def find_sources(self) -> None: class FileList(_FileList): # Implementations of the various MANIFEST.in commands - def __init__(self, warn=None, debug_print=None, ignore_egg_info_dir: bool = False): + def __init__( + self, warn=None, debug_print=None, ignore_egg_info_dir: bool = False + ) -> None: super().__init__(warn, debug_print) self.ignore_egg_info_dir = ignore_egg_info_dir diff --git a/setuptools/config/expand.py b/setuptools/config/expand.py index 2a85363d8d..54c68bed4f 100644 --- a/setuptools/config/expand.py +++ b/setuptools/config/expand.py @@ -52,7 +52,7 @@ class StaticModule: """Proxy to a module object that avoids executing arbitrary code.""" - def __init__(self, name: str, spec: ModuleSpec): + def __init__(self, name: str, spec: ModuleSpec) -> None: module = ast.parse(pathlib.Path(spec.origin).read_bytes()) # type: ignore[arg-type] # Let it raise an error on None vars(self).update(locals()) del self.self @@ -383,7 +383,7 @@ class EnsurePackagesDiscovered: and those might not have been processed yet. """ - def __init__(self, distribution: Distribution): + def __init__(self, distribution: Distribution) -> None: self._dist = distribution self._called = False @@ -430,7 +430,7 @@ class LazyMappingProxy(Mapping[_K, _V_co]): 'other value' """ - def __init__(self, obtain_mapping_value: Callable[[], Mapping[_K, _V_co]]): + def __init__(self, obtain_mapping_value: Callable[[], Mapping[_K, _V_co]]) -> None: self._obtain = obtain_mapping_value self._value: Mapping[_K, _V_co] | None = None diff --git a/setuptools/config/pyprojecttoml.py b/setuptools/config/pyprojecttoml.py index 688040ab50..15b0baa18e 100644 --- a/setuptools/config/pyprojecttoml.py +++ b/setuptools/config/pyprojecttoml.py @@ -176,7 +176,7 @@ def __init__( root_dir: StrPath | None = None, ignore_option_errors: bool = False, dist: Distribution | None = None, - ): + ) -> None: self.config = config self.root_dir = root_dir or os.getcwd() self.project_cfg = config.get("project", {}) @@ -413,7 +413,7 @@ def _ignore_errors(ignore_option_errors: bool): class _EnsurePackagesDiscovered(_expand.EnsurePackagesDiscovered): def __init__( self, distribution: Distribution, project_cfg: dict, setuptools_cfg: dict - ): + ) -> None: super().__init__(distribution) self._project_cfg = project_cfg self._setuptools_cfg = setuptools_cfg diff --git a/setuptools/config/setupcfg.py b/setuptools/config/setupcfg.py index 1f3a180bbe..b35d0b00cd 100644 --- a/setuptools/config/setupcfg.py +++ b/setuptools/config/setupcfg.py @@ -247,7 +247,7 @@ def __init__( options: AllCommandOptions, ignore_option_errors, ensure_discovered: expand.EnsurePackagesDiscovered, - ): + ) -> None: self.ignore_option_errors = ignore_option_errors self.target_obj: Target = target_obj self.sections = dict(self._section_options(options)) @@ -540,7 +540,7 @@ def __init__( ensure_discovered: expand.EnsurePackagesDiscovered, package_dir: dict | None = None, root_dir: StrPath | None = os.curdir, - ): + ) -> None: super().__init__(target_obj, options, ignore_option_errors, ensure_discovered) self.package_dir = package_dir self.root_dir = root_dir @@ -602,7 +602,7 @@ def __init__( options: AllCommandOptions, ignore_option_errors: bool, ensure_discovered: expand.EnsurePackagesDiscovered, - ): + ) -> None: super().__init__(target_obj, options, ignore_option_errors, ensure_discovered) self.root_dir = target_obj.src_root self.package_dir: dict[str, str] = {} # To be filled by `find_packages` diff --git a/setuptools/depends.py b/setuptools/depends.py index 16a67c0306..1be71857a5 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -28,7 +28,7 @@ def __init__( homepage: str = '', attribute=None, format=None, - ): + ) -> None: if format is None and requested_version is not None: format = Version diff --git a/setuptools/discovery.py b/setuptools/discovery.py index eb8969146f..c888399185 100644 --- a/setuptools/discovery.py +++ b/setuptools/discovery.py @@ -71,7 +71,7 @@ class _Filter: the input matches at least one of the patterns. """ - def __init__(self, *patterns: str): + def __init__(self, *patterns: str) -> None: self._patterns = dict.fromkeys(patterns) def __call__(self, item: str) -> bool: @@ -300,7 +300,7 @@ class ConfigDiscovery: (from other metadata/options, the file system or conventions) """ - def __init__(self, distribution: Distribution): + def __init__(self, distribution: Distribution) -> None: self.dist = distribution self._called = False self._disabled = False diff --git a/setuptools/extension.py b/setuptools/extension.py index 79bcc203e9..76e03d9d6b 100644 --- a/setuptools/extension.py +++ b/setuptools/extension.py @@ -147,7 +147,7 @@ def __init__( *args, py_limited_api: bool = False, **kw, - ): + ) -> None: # The *args is needed for compatibility as calls may use positional # arguments. py_limited_api may be set only via keyword. self.py_limited_api = py_limited_api diff --git a/setuptools/msvc.py b/setuptools/msvc.py index 55f5090878..6492d3be9d 100644 --- a/setuptools/msvc.py +++ b/setuptools/msvc.py @@ -50,7 +50,7 @@ class PlatformInfo: current_cpu = environ.get('processor_architecture', '').lower() - def __init__(self, arch): + def __init__(self, arch) -> None: self.arch = arch.lower().replace('x64', 'amd64') @property @@ -176,7 +176,7 @@ class RegistryInfo: winreg.HKEY_CLASSES_ROOT, ) - def __init__(self, platform_info): + def __init__(self, platform_info) -> None: self.pi = platform_info @property @@ -366,7 +366,7 @@ class SystemInfo: ProgramFiles = environ.get('ProgramFiles', '') ProgramFilesx86 = environ.get('ProgramFiles(x86)', ProgramFiles) - def __init__(self, registry_info, vc_ver=None): + def __init__(self, registry_info, vc_ver=None) -> None: self.ri = registry_info self.pi = self.ri.pi @@ -911,7 +911,7 @@ class EnvironmentInfo: # Variables and properties in this class use originals CamelCase variables # names from Microsoft source files for more easy comparison. - def __init__(self, arch, vc_ver=None, vc_min_ver=0): + def __init__(self, arch, vc_ver=None, vc_min_ver=0) -> None: self.pi = PlatformInfo(arch) self.ri = RegistryInfo(self.pi) self.si = SystemInfo(self.ri, vc_ver) diff --git a/setuptools/package_index.py b/setuptools/package_index.py index ad95d3573a..97806e8ff8 100644 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -270,7 +270,7 @@ class HashChecker(ContentChecker): r'(?P[a-f0-9]+)' ) - def __init__(self, hash_name, expected): + def __init__(self, hash_name, expected) -> None: self.hash_name = hash_name self.hash = hashlib.new(hash_name) self.expected = expected diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py index b6c63f03d4..2d84242d66 100644 --- a/setuptools/sandbox.py +++ b/setuptools/sandbox.py @@ -279,7 +279,7 @@ class AbstractSandbox: _active = False - def __init__(self): + def __init__(self) -> None: self._attrs = [ name for name in dir(_os) @@ -442,7 +442,7 @@ class DirectorySandbox(AbstractSandbox): _exception_patterns: list[str | re.Pattern] = [] "exempt writing to paths that match the pattern" - def __init__(self, sandbox, exceptions=_EXCEPTIONS): + def __init__(self, sandbox, exceptions=_EXCEPTIONS) -> None: self._sandbox = os.path.normcase(os.path.realpath(sandbox)) self._prefix = os.path.join(self._sandbox, '') self._exceptions = [ diff --git a/setuptools/wheel.py b/setuptools/wheel.py index a6b3720033..fb19f1a65a 100644 --- a/setuptools/wheel.py +++ b/setuptools/wheel.py @@ -76,7 +76,7 @@ def disable_info_traces(): class Wheel: - def __init__(self, filename): + def __init__(self, filename) -> None: match = WHEEL_NAME(os.path.basename(filename)) if match is None: raise ValueError('invalid wheel name: %r' % filename) From aa0ad576c771917bc527eb11941ccff1abc3176e Mon Sep 17 00:00:00 2001 From: Avasam Date: Sun, 10 Nov 2024 18:07:21 -0500 Subject: [PATCH 3/7] Merge typeshed return annotations --- setuptools/__init__.py | 9 +-- setuptools/build_meta.py | 30 +++++----- setuptools/command/bdist_egg.py | 18 +++--- setuptools/command/bdist_wheel.py | 2 +- setuptools/command/build_ext.py | 4 +- setuptools/command/build_py.py | 10 ++-- setuptools/command/develop.py | 2 +- setuptools/command/easy_install.py | 4 +- setuptools/command/editable_wheel.py | 2 +- setuptools/command/egg_info.py | 8 ++- setuptools/command/install_egg_info.py | 2 +- setuptools/command/saveopts.py | 2 +- setuptools/command/sdist.py | 5 +- setuptools/command/setopt.py | 4 +- setuptools/command/test.py | 8 ++- setuptools/config/expand.py | 6 +- setuptools/config/setupcfg.py | 8 ++- setuptools/dist.py | 8 +-- setuptools/extension.py | 2 +- setuptools/monkey.py | 4 +- setuptools/msvc.py | 79 ++++++++++++++------------ setuptools/package_index.py | 17 +++--- setuptools/sandbox.py | 4 +- setuptools/wheel.py | 3 +- 24 files changed, 133 insertions(+), 108 deletions(-) diff --git a/setuptools/__init__.py b/setuptools/__init__.py index 4f5c01708a..82c8d0179f 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -110,11 +110,12 @@ 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 + return distutils.core.setup(**attrs) # type: ignore[return-value] setup.__doc__ = distutils.core.setup.__doc__ @@ -216,14 +217,14 @@ def ensure_string_list(self, option: str) -> 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 23471accb6..fd3e00d46e 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 @@ -77,14 +77,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 @@ -307,7 +307,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) @@ -330,10 +330,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( @@ -364,7 +368,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), @@ -420,7 +424,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( @@ -445,7 +449,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 ) @@ -467,7 +471,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 [] @@ -479,12 +483,12 @@ def build_editable( 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 ) @@ -502,7 +506,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 04d7e945bc..bcfabe292d 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_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 """ @@ -163,7 +167,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 @@ -247,7 +251,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: @@ -325,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) @@ -411,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/bdist_wheel.py b/setuptools/command/bdist_wheel.py index 8cf91538f9..ff83ceeb79 100644 --- a/setuptools/command/bdist_wheel.py +++ b/setuptools/command/bdist_wheel.py @@ -391,7 +391,7 @@ def get_tag(self) -> tuple[str, str, str]: ) return tag - def run(self): + def run(self) -> None: build_scripts = self.reinitialize_command("build_scripts") build_scripts.executable = "python" build_scripts.force = True diff --git a/setuptools/command/build_ext.py b/setuptools/command/build_ext.py index f098246b9b..9bf51e05e0 100644 --- a/setuptools/command/build_ext.py +++ b/setuptools/command/build_ext.py @@ -93,7 +93,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, 0 _build_ext.run(self) @@ -223,7 +223,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 f8c9b11676..52569c5d3c 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: str | 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 {} @@ -100,7 +100,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. @@ -110,7 +110,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) @@ -178,7 +178,7 @@ def build_package_data(self) -> None: _outf, _copied = self.copy_file(srcfile, target) make_writable(target) - def analyze_manifest(self): + def analyze_manifest(self) -> None: self.manifest_files = mf = {} if not self.distribution.include_package_data: return @@ -277,7 +277,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 7eee29d491..f16c14dfb3 100644 --- a/setuptools/command/develop.py +++ b/setuptools/command/develop.py @@ -26,7 +26,7 @@ class develop(namespaces.DevelopInstaller, easy_install): command_consumes_arguments = False # override base - def run(self): + def run(self) -> None: if self.uninstall: self.multi_version = True self.uninstall_link() diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 21e6f008d7..e2acad23b9 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -239,7 +239,7 @@ def _render_version(): print(f'setuptools {dist.version} from {dist.location} (Python {ver})') raise SystemExit - def finalize_options(self): # noqa: C901 # is too complex (25) # FIXME + def finalize_options(self) -> None: # noqa: C901 # is too complex (25) # FIXME self.version and self._render_version() py_version = sys.version.split()[0] @@ -748,7 +748,7 @@ def install_item( return dist return None - def select_scheme(self, name): + def select_scheme(self, name) -> None: try: install._select_scheme(self, name) except AttributeError: diff --git a/setuptools/command/editable_wheel.py b/setuptools/command/editable_wheel.py index 30570e092a..d4ef24038d 100644 --- a/setuptools/command/editable_wheel.py +++ b/setuptools/command/editable_wheel.py @@ -779,7 +779,7 @@ def _empty_dir(dir_: _P) -> _P: class _NamespaceInstaller(namespaces.Installer): - def __init__(self, distribution, installation_dir, editable_name, src_root): + def __init__(self, distribution, installation_dir, editable_name, src_root) -> None: self.distribution = distribution self.src_root = src_root self.installation_dir = installation_dir diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 1411ac3d89..2a24f310ef 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 @@ -195,11 +197,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 #################################### @@ -330,7 +332,7 @@ def __init__( super().__init__(warn, debug_print) self.ignore_egg_info_dir = ignore_egg_info_dir - def process_template_line(self, line): + def process_template_line(self, line) -> None: # Parse the line: split it up, make sure the right number of words # is there, and return the relevant words. 'action' is always # defined: it's the first word of the line. Which of the other diff --git a/setuptools/command/install_egg_info.py b/setuptools/command/install_egg_info.py index be4dd7b229..597a04228e 100644 --- a/setuptools/command/install_egg_info.py +++ b/setuptools/command/install_egg_info.py @@ -20,7 +20,7 @@ class install_egg_info(namespaces.Installer, Command): def initialize_options(self): self.install_dir = None - def finalize_options(self): + def finalize_options(self) -> None: self.set_undefined_options('install_lib', ('install_dir', 'install_dir')) ei_cmd = self.get_finalized_command("egg_info") basename = f"{ei_cmd._get_egg_basename()}.egg-info" diff --git a/setuptools/command/saveopts.py b/setuptools/command/saveopts.py index f175de1015..48dcd3bc4b 100644 --- a/setuptools/command/saveopts.py +++ b/setuptools/command/saveopts.py @@ -6,7 +6,7 @@ class saveopts(option_base): description = "save supplied options to setup.cfg or other config file" - def run(self): + def run(self) -> None: dist = self.distribution settings = {} diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py index be69b33500..246a01e46b 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 75393f32f0..1c07e34f14 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 54c68bed4f..1c48961fd5 100644 --- a/setuptools/config/expand.py +++ b/setuptools/config/expand.py @@ -387,7 +387,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 @@ -401,7 +401,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 @@ -411,7 +411,7 @@ def _get_package_dir(self) -> Mapping[str, str]: return {} if pkg_dir is None else pkg_dir @property - def package_dir(self) -> Mapping[str, str]: + def package_dir(self) -> LazyMappingProxy[str, str]: """Proxy to ``package_dir`` that may trigger auto-discovery when used.""" return LazyMappingProxy(self._get_package_dir) diff --git a/setuptools/config/setupcfg.py b/setuptools/config/setupcfg.py index b35d0b00cd..1a6830dda4 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( '%s must provide .parsers property' % self.__class__.__name__ @@ -546,7 +548,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 = self._parse_list parse_file = partial(self._parse_file, root_dir=self.root_dir) @@ -623,7 +625,7 @@ def _parse_requirements_list(self, label: str, value: str): return [line for line in parsed if not line.startswith("#")] @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 6062c4f868..fde9d0dd94 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -6,7 +6,7 @@ import os import re import sys -from collections.abc import Iterable, MutableMapping, Sequence +from collections.abc import Iterable, Iterator, MutableMapping, Sequence from glob import iglob from pathlib import Path from typing import TYPE_CHECKING, Any, Union @@ -696,7 +696,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') @@ -904,7 +904,7 @@ def _parse_command_opts(self, parser, args): return nargs - def get_cmdline_options(self): + def get_cmdline_options(self) -> dict[str, dict[str, str | None]]: """Return a '{cmd: {opt:val}}' map of all command-line options Option names are all long, but do not include the leading '--', and @@ -942,7 +942,7 @@ def get_cmdline_options(self): 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..98e819a4ae 100644 --- a/setuptools/extension.py +++ b/setuptools/extension.py @@ -13,7 +13,7 @@ import distutils.extension -def _have_cython(): +def _have_cython() -> bool: """ Return True if Cython can be imported. """ diff --git a/setuptools/monkey.py b/setuptools/monkey.py index 07919722b8..7bea2374a2 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 6492d3be9d..a8b74a6503 100644 --- a/setuptools/msvc.py +++ b/setuptools/msvc.py @@ -13,14 +13,14 @@ 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 import distutils.errors if TYPE_CHECKING: - from typing_extensions import NotRequired + from typing_extensions import LiteralString, NotRequired # https://github.com/python/mypy/issues/8166 if not TYPE_CHECKING and platform.system() == 'Windows': @@ -50,11 +50,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. @@ -65,7 +65,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.. @@ -76,7 +76,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.. @@ -135,7 +135,7 @@ def target_dir(self, hidex86=False, x64=False) -> str: else r'\%s' % self.target_cpu ) - def cross_dir(self, forcex86=False): + def cross_dir(self, forcex86=False) -> str: r""" Cross platform specific subfolder. @@ -180,7 +180,7 @@ def __init__(self, platform_info) -> None: self.pi = platform_info @property - def visualstudio(self) -> str: + def visualstudio(self) -> LiteralString: """ Microsoft Visual Studio root registry key. @@ -192,7 +192,7 @@ def visualstudio(self) -> str: return 'VisualStudio' @property - def sxs(self): + def sxs(self) -> LiteralString: """ Microsoft Visual Studio SxS registry key. @@ -204,7 +204,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. @@ -216,7 +216,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. @@ -228,7 +228,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. @@ -240,7 +240,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. @@ -252,7 +252,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. @@ -264,7 +264,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. @@ -276,7 +276,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. @@ -287,7 +287,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. @@ -306,7 +310,7 @@ def microsoft(self, key, x86=False): node64 = '' if self.pi.current_is_x86() or x86 else 'Wow6432Node' return os.path.join('Software', node64, 'Microsoft', key) - def lookup(self, key, name): + def lookup(self, key: str, name: str) -> str | None: """ Look for values in registry in Microsoft software registry. @@ -366,7 +370,9 @@ class SystemInfo: ProgramFiles = environ.get('ProgramFiles', '') ProgramFilesx86 = environ.get('ProgramFiles(x86)', ProgramFiles) - def __init__(self, registry_info, 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 @@ -395,7 +401,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. @@ -426,7 +432,7 @@ def find_reg_vs_vers(self): vs_vers.append(ver) return sorted(vs_vers) - def find_programdata_vs_vers(self): + def find_programdata_vs_vers(self) -> dict[float, str]: r""" Find Visual studio 2017+ versions from information in "C:\ProgramData\Microsoft\VisualStudio\Packages\_Instances". @@ -486,7 +492,7 @@ def _as_float_version(version): return float('.'.join(version.split('.')[:2])) @property - def VSInstallDir(self): + def VSInstallDir(self) -> str: """ Microsoft Visual Studio directory. @@ -504,7 +510,7 @@ def VSInstallDir(self): return self.ri.lookup(self.ri.vs, '%0.1f' % self.vs_ver) or default @property - def VCInstallDir(self): + def VCInstallDir(self) -> str: """ Microsoft Visual C++ directory. @@ -573,7 +579,7 @@ def _guess_vc_legacy(self): return self.ri.lookup(self.ri.vc, '%0.1f' % self.vs_ver) or default_vc @property - def WindowsSdkVersion(self): + def WindowsSdkVersion(self) -> tuple[LiteralString, ...] | None: """ Microsoft Windows SDK versions for specified MSVC++ version. @@ -595,7 +601,7 @@ def WindowsSdkVersion(self): return None @property - def WindowsSdkLastVersion(self): + def WindowsSdkLastVersion(self) -> str: """ Microsoft Windows SDK last version. @@ -607,7 +613,7 @@ def WindowsSdkLastVersion(self): return self._use_last_dir_name(os.path.join(self.WindowsSdkDir, 'lib')) @property - def WindowsSdkDir(self): # noqa: C901 # is too complex (12) # FIXME + def WindowsSdkDir(self) -> str: # noqa: C901 # is too complex (12) # FIXME """ Microsoft Windows SDK directory. @@ -650,7 +656,7 @@ def WindowsSdkDir(self): # noqa: C901 # is too complex (12) # FIXME return sdkdir @property - def WindowsSDKExecutablePath(self): + def WindowsSDKExecutablePath(self) -> str | None: """ Microsoft Windows SDK executable directory. @@ -687,7 +693,7 @@ def WindowsSDKExecutablePath(self): return None @property - def FSharpInstallDir(self): + def FSharpInstallDir(self) -> str: """ Microsoft Visual F# directory. @@ -700,7 +706,7 @@ def FSharpInstallDir(self): return self.ri.lookup(path, 'productdir') or '' @property - def UniversalCRTSdkDir(self): + def UniversalCRTSdkDir(self) -> str | None: """ Microsoft Universal CRT SDK directory. @@ -721,7 +727,7 @@ def UniversalCRTSdkDir(self): return None @property - def UniversalCRTSdkLastVersion(self): + def UniversalCRTSdkLastVersion(self) -> str: """ Microsoft Universal C Runtime SDK last version. @@ -733,7 +739,7 @@ def UniversalCRTSdkLastVersion(self): return self._use_last_dir_name(os.path.join(self.UniversalCRTSdkDir, 'lib')) @property - def NetFxSdkVersion(self): + def NetFxSdkVersion(self) -> tuple[LiteralString, ...]: """ Microsoft .NET Framework SDK versions. @@ -750,7 +756,7 @@ def NetFxSdkVersion(self): ) @property - def NetFxSdkDir(self): + def NetFxSdkDir(self) -> str | None: """ Microsoft .NET Framework SDK directory. @@ -759,7 +765,6 @@ def NetFxSdkDir(self): str path """ - sdkdir = '' for ver in self.NetFxSdkVersion: loc = os.path.join(self.ri.netfx_sdk, ver) sdkdir = self.ri.lookup(loc, 'kitsinstallationfolder') @@ -768,7 +773,7 @@ def NetFxSdkDir(self): return sdkdir @property - def FrameworkDir32(self): + def FrameworkDir32(self) -> str: """ Microsoft .NET Framework 32bit directory. @@ -784,7 +789,7 @@ def FrameworkDir32(self): return self.ri.lookup(self.ri.vc, 'frameworkdir32') or guess_fw @property - def FrameworkDir64(self): + def FrameworkDir64(self) -> str: """ Microsoft .NET Framework 64bit directory. @@ -800,7 +805,7 @@ def FrameworkDir64(self): return self.ri.lookup(self.ri.vc, 'frameworkdir64') or guess_fw @property - def FrameworkVersion32(self): + def FrameworkVersion32(self) -> tuple[str, ...] | None: """ Microsoft .NET Framework 32bit versions. @@ -812,7 +817,7 @@ def FrameworkVersion32(self): return self._find_dot_net_versions(32) @property - def FrameworkVersion64(self): + def FrameworkVersion64(self) -> tuple[str, ...] | None: """ Microsoft .NET Framework 64bit versions. diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 97806e8ff8..3ae0f838ca 100644 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -18,6 +18,7 @@ import urllib.error import urllib.parse import urllib.request +from collections.abc import Iterator from fnmatch import translate from functools import wraps from typing import NamedTuple @@ -113,7 +114,7 @@ def egg_info_for_url(url): return base, fragment -def distros_for_url(url, metadata=None): +def distros_for_url(url, metadata=None) -> Iterator[Distribution]: """Yield egg or source distribution objects that might be found at a URL""" base, fragment = egg_info_for_url(url) yield from distros_for_location(url, base, metadata) @@ -125,7 +126,9 @@ def distros_for_url(url, metadata=None): ) -def distros_for_location(location, basename, metadata=None): +def distros_for_location( + location, basename, metadata=None +) -> list[Distribution] | Iterator[Distribution]: """Yield egg or source distribution objects based on basename""" if basename.endswith('.egg.zip'): basename = basename[:-4] # strip the .zip @@ -169,7 +172,7 @@ def distros_for_filename(filename, metadata=None): def interpret_distro_name( location, basename, metadata, py_version=None, precedence=SOURCE_DIST, platform=None -): +) -> Iterator[Distribution]: """Generate the interpretation of a source distro name Note: if `location` is a filesystem filename, you should call @@ -244,7 +247,7 @@ class ContentChecker: A null content checker that defines the interface for checking content """ - def feed(self, block): + def feed(self, block) -> None: """ Feed a block of data to the hash. """ @@ -256,7 +259,7 @@ def is_valid(self): """ return True - def report(self, reporter, template): + def report(self, reporter, template) -> None: """ Call reporter with information about the checker (hash name) substituted into the template. @@ -286,7 +289,7 @@ def from_url(cls, url): return ContentChecker() return cls(**match.groupdict()) - def feed(self, block): + def feed(self, block) -> None: self.hash.update(block) def is_valid(self): @@ -1017,7 +1020,7 @@ def __str__(self) -> str: class PyPIConfig(configparser.RawConfigParser): - def __init__(self): + def __init__(self) -> None: """ Load from ~/.pypirc """ diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py index 2d84242d66..88271cfc94 100644 --- a/setuptools/sandbox.py +++ b/setuptools/sandbox.py @@ -144,7 +144,7 @@ def __exit__( # suppress the exception return True - def resume(self): + def resume(self) -> None: "restore and re-raise any exception" if '_saved' not in vars(self): @@ -300,7 +300,7 @@ def __exit__( exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None, - ): + ) -> None: self._active = False builtins.open = _open self._copy(_os) diff --git a/setuptools/wheel.py b/setuptools/wheel.py index fb19f1a65a..9dac318da3 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.tags import sys_tags from packaging.utils import canonicalize_name @@ -62,7 +63,7 @@ def unpack(src_dir, dst_dir) -> None: @contextlib.contextmanager -def disable_info_traces(): +def disable_info_traces() -> Iterator[None]: """ Temporarily disable info traces. """ From f0f05bdd1e846d898b185b1c9d01c5850756b17d Mon Sep 17 00:00:00 2001 From: Avasam Date: Tue, 19 Nov 2024 00:19:15 -0500 Subject: [PATCH 4/7] include a type-ignore comment --- setuptools/command/develop.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/command/develop.py b/setuptools/command/develop.py index f16c14dfb3..777309e0a4 100644 --- a/setuptools/command/develop.py +++ b/setuptools/command/develop.py @@ -26,7 +26,7 @@ class develop(namespaces.DevelopInstaller, easy_install): command_consumes_arguments = False # override base - def run(self) -> None: + def run(self) -> None: # type: ignore[override] # Not including easy_install's show_deprecation argument if self.uninstall: self.multi_version = True self.uninstall_link() From 120539ecc30bdd4bf8195d52a5953704e79c8764 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 20 Nov 2024 15:00:44 -0500 Subject: [PATCH 5/7] More annotation changes --- setuptools/command/bdist_egg.py | 2 +- setuptools/command/bdist_wheel.py | 2 +- setuptools/command/easy_install.py | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/setuptools/command/bdist_egg.py b/setuptools/command/bdist_egg.py index c094b64dde..1ec337f708 100644 --- a/setuptools/command/bdist_egg.py +++ b/setuptools/command/bdist_egg.py @@ -238,7 +238,7 @@ def run(self) -> None: # 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: diff --git a/setuptools/command/bdist_wheel.py b/setuptools/command/bdist_wheel.py index 13e79440df..234df2a7c7 100644 --- a/setuptools/command/bdist_wheel.py +++ b/setuptools/command/bdist_wheel.py @@ -369,7 +369,7 @@ def get_tag(self) -> tuple[str, str, str]: ) return tag - def run(self) -> None: + def run(self): build_scripts = self.reinitialize_command("build_scripts") build_scripts.executable = "python" build_scripts.force = True diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index fbac071ec3..bd393d3697 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -752,7 +752,10 @@ def select_scheme(self, name) -> None: install._select_scheme(self, name) except AttributeError: # stdlib distutils - install.install.select_scheme(self, name.replace('posix', 'unix')) + install.install.select_scheme( + self, # type: ignore[arg-type] # Pretend it's the correct type for stdlib compatibility + name.replace('posix', 'unix'), + ) # FIXME: 'easy_install.process_distribution' is too complex (12) def process_distribution( # noqa: C901 From 59fc3b4b253b6fbad890ee7b34acd37b92d024f1 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 20 Nov 2024 15:31:35 -0500 Subject: [PATCH 6/7] Add assert in zap_pyfiles --- setuptools/command/bdist_egg.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setuptools/command/bdist_egg.py b/setuptools/command/bdist_egg.py index 1ec337f708..0582a131f4 100644 --- a/setuptools/command/bdist_egg.py +++ b/setuptools/command/bdist_egg.py @@ -266,6 +266,8 @@ def zap_pyfiles(self) -> None: pattern = r'(?P.+)\.(?P[^.]+)\.pyc' m = re.match(pattern, name) + # We shouldn't ind 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("Renaming file from [%s] to [%s]" % (path_old, path_new)) try: From 1540c752d33d3241901b550d8322c40303d6f49e Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 20 Nov 2024 15:50:27 -0500 Subject: [PATCH 7/7] typo --- setuptools/command/bdist_egg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/command/bdist_egg.py b/setuptools/command/bdist_egg.py index 0582a131f4..e320205289 100644 --- a/setuptools/command/bdist_egg.py +++ b/setuptools/command/bdist_egg.py @@ -266,7 +266,7 @@ def zap_pyfiles(self) -> None: pattern = r'(?P.+)\.(?P[^.]+)\.pyc' m = re.match(pattern, name) - # We shouldn't ind any non-pyc files in __pycache__ + # 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("Renaming file from [%s] to [%s]" % (path_old, path_new))