From 3aba4d4b2abd6b15760f1532871e2321acd2d658 Mon Sep 17 00:00:00 2001 From: Avasam Date: Sat, 20 Jul 2024 15:59:27 -0400 Subject: [PATCH 1/2] Update mypy to 1.11 --- mypy.ini | 3 ++- pyproject.toml | 5 ++++- setuptools/command/editable_wheel.py | 7 ++----- setuptools/command/install.py | 9 +++++++-- setuptools/command/install_lib.py | 2 +- setuptools/command/upload_docs.py | 2 +- setuptools/tests/test_wheel.py | 10 ++++++++-- 7 files changed, 25 insertions(+), 13 deletions(-) diff --git a/mypy.ini b/mypy.ini index c4b30d1acd..4fba13c286 100644 --- a/mypy.ini +++ b/mypy.ini @@ -38,7 +38,8 @@ disable_error_code = import-not-found [mypy-distutils._modified,jaraco.*,trove_classifiers,wheel.*] ignore_missing_imports = True -# Even when excluding generated modules, there might be problems: https://github.com/python/mypy/issues/11936#issuecomment-1466764006 +# Even when excluding a module, import issues can show up due to following import +# https://github.com/python/mypy/issues/11936#issuecomment-1466764006 [mypy-setuptools.config._validate_pyproject.*] follow_imports = silent # silent => ignore errors when following imports diff --git a/pyproject.toml b/pyproject.toml index 020f57ee17..58e991c50e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,7 +59,10 @@ test = [ # for tools/finalize.py 'jaraco.develop >= 7.21; python_version >= "3.9" and sys_platform != "cygwin"', "pytest-home >= 0.5", - "mypy==1.10.0", # pin mypy version so a new version doesn't suddenly cause the CI to fail + # pin mypy version so a new version doesn't suddenly cause the CI to fail, + # until types-setuptools is removed from typeshed. + # For help with static-typing issues, or mypy update, ping @Avasam + "mypy==1.11", # No Python 3.11 dependencies require tomli, but needed for type-checking since we import it directly "tomli", # No Python 3.12 dependencies require importlib_metadata, but needed for type-checking since we import it directly diff --git a/setuptools/command/editable_wheel.py b/setuptools/command/editable_wheel.py index 13c450cb49..49fd609b15 100644 --- a/setuptools/command/editable_wheel.py +++ b/setuptools/command/editable_wheel.py @@ -443,8 +443,7 @@ def __init__( ): self.auxiliary_dir = Path(auxiliary_dir) self.build_lib = Path(build_lib).resolve() - # TODO: Update typeshed distutils stubs to overload non-None return type by default - self._file = dist.get_command_obj("build_py").copy_file # type: ignore[union-attr] + 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: dict[str, str]): @@ -462,9 +461,7 @@ def _create_file(self, relative_output: str, src_file: str, link=None): dest = self.auxiliary_dir / relative_output if not dest.parent.is_dir(): dest.parent.mkdir(parents=True) - # TODO: Update typeshed distutils stubs so distutils.cmd.Command.copy_file, accepts PathLike - # same with methods used by copy_file - self._file(src_file, dest, link=link) # type: ignore[arg-type] + self._file(src_file, dest, link=link) def _create_links(self, outputs, output_mapping): self.auxiliary_dir.mkdir(parents=True, exist_ok=True) diff --git a/setuptools/command/install.py b/setuptools/command/install.py index c49fcda939..f1ea2adf1d 100644 --- a/setuptools/command/install.py +++ b/setuptools/command/install.py @@ -1,9 +1,12 @@ +from __future__ import annotations + +from collections.abc import Callable from distutils.errors import DistutilsArgError import inspect import glob import platform import distutils.command.install as orig -from typing import cast +from typing import Any, ClassVar, cast import setuptools from ..warnings import SetuptoolsDeprecationWarning, SetuptoolsWarning @@ -29,7 +32,9 @@ class install(orig.install): 'old-and-unmanageable', 'single-version-externally-managed', ] - new_commands = [ + # Type the same as distutils.command.install.install.sub_commands + # Must keep the second tuple item potentially None due to invariance + new_commands: ClassVar[list[tuple[str, Callable[[Any], bool] | None]]] = [ ('install_egg_info', lambda self: True), ('install_scripts', lambda self: True), ] diff --git a/setuptools/command/install_lib.py b/setuptools/command/install_lib.py index 5e74be247e..9a4b0472f0 100644 --- a/setuptools/command/install_lib.py +++ b/setuptools/command/install_lib.py @@ -97,7 +97,7 @@ def copy_tree( exclude = self.get_exclusions() if not exclude: - return orig.install_lib.copy_tree(self, infile, outfile) # type: ignore[arg-type] # Fixed upstream + return orig.install_lib.copy_tree(self, infile, outfile) # Exclude namespace package __init__.py* files from the output diff --git a/setuptools/command/upload_docs.py b/setuptools/command/upload_docs.py index 3fbbb62553..32c9abd796 100644 --- a/setuptools/command/upload_docs.py +++ b/setuptools/command/upload_docs.py @@ -50,7 +50,7 @@ def has_sphinx(self): and metadata.entry_points(group='distutils.commands', name='build_sphinx') ) - sub_commands = [('build_sphinx', has_sphinx)] # type: ignore[list-item] # TODO: Fix in typeshed distutils stubs + sub_commands = [('build_sphinx', has_sphinx)] def initialize_options(self): upload.initialize_options(self) diff --git a/setuptools/tests/test_wheel.py b/setuptools/tests/test_wheel.py index e58ccd8d18..cc5d54b6d9 100644 --- a/setuptools/tests/test_wheel.py +++ b/setuptools/tests/test_wheel.py @@ -1,5 +1,7 @@ """wheel tests""" +from __future__ import annotations + from distutils.sysconfig import get_config_var from distutils.util import get_platform import contextlib @@ -11,6 +13,7 @@ import shutil import subprocess import sys +from typing import Any import zipfile import pytest @@ -176,7 +179,10 @@ def __repr__(self): return '%s(**%r)' % (self._id, self._fields) -WHEEL_INSTALL_TESTS = ( +# Using Any to avoid possible type union issues later in test +# making a TypedDict is not worth in a test and anonymous/inline TypedDict are experimental +# https://github.com/python/mypy/issues/9884 +WHEEL_INSTALL_TESTS: tuple[dict[str, Any], ...] = ( dict( id='basic', file_defs={'foo': {'__init__.py': ''}}, @@ -547,7 +553,7 @@ def __repr__(self): @pytest.mark.parametrize( 'params', WHEEL_INSTALL_TESTS, - ids=list(params['id'] for params in WHEEL_INSTALL_TESTS), + ids=[params['id'] for params in WHEEL_INSTALL_TESTS], ) def test_wheel_install(params): project_name = params.get('name', 'foo') From e7575ae7b31c987916bf4724a979b91a8bfa3244 Mon Sep 17 00:00:00 2001 From: Avasam Date: Sun, 21 Jul 2024 00:10:17 -0400 Subject: [PATCH 2/2] Update pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 58e991c50e..db64f2bebd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -62,7 +62,7 @@ test = [ # pin mypy version so a new version doesn't suddenly cause the CI to fail, # until types-setuptools is removed from typeshed. # For help with static-typing issues, or mypy update, ping @Avasam - "mypy==1.11", + "mypy==1.11.*", # No Python 3.11 dependencies require tomli, but needed for type-checking since we import it directly "tomli", # No Python 3.12 dependencies require importlib_metadata, but needed for type-checking since we import it directly