diff --git a/ruff.toml b/ruff.toml index 83a6f173a3..8d7b5e71f7 100644 --- a/ruff.toml +++ b/ruff.toml @@ -66,13 +66,12 @@ ignore = [ "UP038", # Using `X | Y` in `isinstance` call is slower and more verbose https://github.com/astral-sh/ruff/issues/7871 # Only enforcing return type annotations for public functions "ANN202", # missing-return-type-private-function - "ANN204", # missing-return-type-special-method ] [lint.per-file-ignores] # Suppress nuisance warnings about module-import-not-at-top-of-file (E402) due to workaround for #4476 "setuptools/__init__.py" = ["E402"] -"pkg_resources/__init__.py" = ["E402"] +"pkg_resources/__init__.py" = ["E402", "ANN204"] [lint.isort] combine-as-imports = true diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index 339699dbbc..59a9785308 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -9,6 +9,7 @@ from functools import partial from glob import glob from pathlib import Path +from typing import Any from more_itertools import unique_everseen @@ -81,7 +82,8 @@ def run(self) -> None: # output files are. self.byte_compile(orig.build_py.get_outputs(self, include_bytecode=False)) - def __getattr__(self, attr: str): + # Should return "list[tuple[str, str, str, list[str]]] | Any" but can't do without typed distutils on Python 3.12+ + def __getattr__(self, attr: str) -> Any: "lazily compute data files" if attr == 'data_files': self.data_files = self._get_data_files() @@ -381,8 +383,8 @@ class _Warning(SetuptoolsDeprecationWarning): # _DUE_DATE: still not defined as this is particularly controversial. # Warning initially introduced in May 2022. See issue #3340 for discussion. - def __init__(self): - self._already_warned = set() + def __init__(self) -> None: + self._already_warned = set[str]() def is_module(self, file): return file.endswith(".py") and file[: -len(".py")].isidentifier() diff --git a/setuptools/command/editable_wheel.py b/setuptools/command/editable_wheel.py index c772570817..48bd12ac40 100644 --- a/setuptools/command/editable_wheel.py +++ b/setuptools/command/editable_wheel.py @@ -406,7 +406,9 @@ def __init__(self, dist: Distribution, name: str, path_entries: list[Path]) -> N self.name = name self.path_entries = path_entries - def __call__(self, wheel: WheelFile, files: list[str], mapping: Mapping[str, str]): + def __call__( + self, wheel: WheelFile, files: list[str], mapping: Mapping[str, str] + ) -> None: entries = "\n".join(str(p.resolve()) for p in self.path_entries) contents = _encode_pth(f"{entries}\n") wheel.writestr(f"__editable__.{self.name}.pth", contents) @@ -451,7 +453,9 @@ def __init__( self._file = dist.get_command_obj("build_py").copy_file super().__init__(dist, name, [self.auxiliary_dir]) - def __call__(self, wheel: WheelFile, files: list[str], mapping: Mapping[str, str]): + def __call__( + self, wheel: WheelFile, files: list[str], mapping: Mapping[str, str] + ) -> None: self._create_links(files, mapping) super().__call__(wheel, files, mapping) @@ -545,7 +549,9 @@ def get_implementation(self) -> Iterator[tuple[str, bytes]]: content = _encode_pth(f"import {finder}; {finder}.install()") yield (f"__editable__.{self.name}.pth", content) - def __call__(self, wheel: WheelFile, files: list[str], mapping: Mapping[str, str]): + def __call__( + self, wheel: WheelFile, files: list[str], mapping: Mapping[str, str] + ) -> None: for file, content in self.get_implementation(): wheel.writestr(file, content) diff --git a/setuptools/config/expand.py b/setuptools/config/expand.py index dc066d9427..d9a2ded430 100644 --- a/setuptools/config/expand.py +++ b/setuptools/config/expand.py @@ -65,7 +65,7 @@ def _find_assignments(self) -> Iterator[tuple[ast.AST, ast.AST]]: elif isinstance(statement, ast.AnnAssign) and statement.value: yield (statement.target, statement.value) - def __getattr__(self, attr: str): + def __getattr__(self, attr: str) -> Any: """Attempt to load an attribute "statically", via :func:`ast.literal_eval`.""" try: return next( diff --git a/setuptools/discovery.py b/setuptools/discovery.py index c888399185..606796c388 100644 --- a/setuptools/discovery.py +++ b/setuptools/discovery.py @@ -335,7 +335,7 @@ def _package_dir(self) -> dict[str, str]: def __call__( self, force: bool = False, name: bool = True, ignore_ext_modules: bool = False - ): + ) -> None: """Automatically discover missing configuration fields and modifies the given ``distribution`` object in-place. diff --git a/setuptools/tests/integration/helpers.py b/setuptools/tests/integration/helpers.py index 77b196e029..16b1302291 100644 --- a/setuptools/tests/integration/helpers.py +++ b/setuptools/tests/integration/helpers.py @@ -5,11 +5,14 @@ facilitate debugging. """ +from __future__ import annotations + import os import subprocess import tarfile +from collections.abc import Iterator from pathlib import Path -from zipfile import ZipFile +from zipfile import ZipFile, ZipInfo def run(cmd, env=None): @@ -35,16 +38,16 @@ def run(cmd, env=None): class Archive: """Compatibility layer for ZipFile/Info and TarFile/Info""" - def __init__(self, filename): + def __init__(self, filename) -> None: self._filename = filename if filename.endswith("tar.gz"): - self._obj = tarfile.open(filename, "r:gz") + self._obj: tarfile.TarFile | ZipFile = tarfile.open(filename, "r:gz") elif filename.endswith("zip"): self._obj = ZipFile(filename) else: raise ValueError(f"{filename} doesn't seem to be a zip or tar.gz") - def __iter__(self): + def __iter__(self) -> Iterator[ZipInfo] | Iterator[tarfile.TarInfo]: if hasattr(self._obj, "infolist"): return iter(self._obj.infolist()) return iter(self._obj) diff --git a/setuptools/tests/test_bdist_wheel.py b/setuptools/tests/test_bdist_wheel.py index 2ab4e9cfc6..68cc0c4d36 100644 --- a/setuptools/tests/test_bdist_wheel.py +++ b/setuptools/tests/test_bdist_wheel.py @@ -295,7 +295,7 @@ def test_preserve_unicode_metadata(monkeypatch, tmp_path): class simpler_bdist_wheel(bdist_wheel): """Avoid messing with setuptools/distutils internals""" - def __init__(self): + def __init__(self) -> None: pass @property diff --git a/setuptools/tests/test_build_meta.py b/setuptools/tests/test_build_meta.py index 57162fd6af..2cd0a0a8ed 100644 --- a/setuptools/tests/test_build_meta.py +++ b/setuptools/tests/test_build_meta.py @@ -35,7 +35,7 @@ class BuildBackendBase: - def __init__(self, cwd='.', env=None, backend_name='setuptools.build_meta'): + def __init__(self, cwd='.', env=None, backend_name='setuptools.build_meta') -> None: self.cwd = cwd self.env = env or {} self.backend_name = backend_name @@ -44,7 +44,7 @@ def __init__(self, cwd='.', env=None, backend_name='setuptools.build_meta'): class BuildBackend(BuildBackendBase): """PEP 517 Build Backend""" - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.pool = futures.ProcessPoolExecutor(max_workers=1) @@ -77,12 +77,12 @@ def _kill(self, pid): class BuildBackendCaller(BuildBackendBase): - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) (self.backend_name, _, self.backend_obj) = self.backend_name.partition(':') - def __call__(self, name, *args, **kw): + def __call__(self, name, *args, **kw) -> Any: """Handles arbitrary function invocations on the build backend.""" os.chdir(self.cwd) os.environ.update(self.env) diff --git a/setuptools/tests/test_wheel.py b/setuptools/tests/test_wheel.py index f91465084a..c6e3ec7bca 100644 --- a/setuptools/tests/test_wheel.py +++ b/setuptools/tests/test_wheel.py @@ -168,7 +168,7 @@ def _check_wheel_install( class Record: - def __init__(self, id, **kwargs): + def __init__(self, id, **kwargs) -> None: self._id = id self._fields = kwargs