From 9faad5f44aca75a8f56f88517af61a422abe4fb4 Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 17 Oct 2024 16:38:40 -0400 Subject: [PATCH] Config changes to use our custom stubs --- mypy.ini | 14 +++++--------- pyproject.toml | 4 ++++ pyrightconfig.json | 2 ++ ruff.toml | 3 +++ setuptools/__init__.py | 2 +- setuptools/command/build_py.py | 4 ++-- setuptools/command/install_lib.py | 7 +++---- setuptools/errors.py | 8 ++++---- setuptools/extension.py | 7 +------ 9 files changed, 25 insertions(+), 26 deletions(-) diff --git a/mypy.ini b/mypy.ini index cadfa6be59..83a82c6826 100644 --- a/mypy.ini +++ b/mypy.ini @@ -5,7 +5,7 @@ strict = False # Early opt-in even when strict = False -# warn_unused_ignores = True # Disabled until we have distutils stubs for Python 3.12+ +warn_unused_ignores = True warn_redundant_casts = True enable_error_code = ignore-without-code @@ -18,6 +18,9 @@ disable_error_code = ## local +# Use our custom stubs for distutils +mypy_path = $MYPY_CONFIG_FILE_DIR/typings + # CI should test for all versions, local development gets hints for oldest supported # But our testing setup doesn't allow passing CLI arguments, so local devs have to set this manually. # python_version = 3.8 @@ -48,17 +51,10 @@ disable_error_code = [mypy-pkg_resources.tests.*] disable_error_code = import-not-found -# - distutils doesn't exist on Python 3.12, unfortunately, this means typing -# will be missing for subclasses of distutils on Python 3.12 until either: -# - support for `SETUPTOOLS_USE_DISTUTILS=stdlib` is dropped (#3625) -# for setuptools to import `_distutils` directly -# - or non-stdlib distutils typings are exposed -[mypy-distutils.*] -ignore_missing_imports = True - # - wheel: does not intend on exposing a programmatic API https://github.com/pypa/wheel/pull/610#issuecomment-2081687671 [mypy-wheel.*] ignore_missing_imports = True + # - The following are not marked as py.typed: # - jaraco: Since mypy 1.12, the root name of the untyped namespace package gets called-out too # - jaraco.develop: https://github.com/jaraco/jaraco.develop/issues/22 diff --git a/pyproject.toml b/pyproject.toml index 1a4906fb0c..4b2d99e6ec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -133,6 +133,8 @@ type = [ # local + # Referenced in distutils-stubs + "types-docutils", # 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 @@ -203,6 +205,8 @@ include-package-data = true include = [ "setuptools*", "pkg_resources*", + # TODO: Include distutils stubs with package once we're confident in them + # "typings/distutils-stubs", "_distutils_hack*", ] exclude = [ diff --git a/pyrightconfig.json b/pyrightconfig.json index 27a329e169..4d906d5553 100644 --- a/pyrightconfig.json +++ b/pyrightconfig.json @@ -12,6 +12,8 @@ ], // Our testing setup doesn't allow passing CLI arguments, so local devs have to set this manually. // "pythonVersion": "3.8", + // Allow using distutils-stubs on Python 3.12+ + "reportMissingModuleSource": false, // For now we don't mind if mypy's `type: ignore` comments accidentally suppresses pyright issues "enableTypeIgnoreComments": true, "typeCheckingMode": "basic", diff --git a/ruff.toml b/ruff.toml index e154cdf70d..9d00e7685e 100644 --- a/ruff.toml +++ b/ruff.toml @@ -34,6 +34,9 @@ ignore = [ # Only enforcing return type annotations for public functions "ANN202", # missing-return-type-private-function "ANN204", # missing-return-type-special-method + # Typeshed doesn't want complex or non-literal defaults for maintenance and testing reasons. + # This doesn't affect us, let's have more complete stubs. + "PYI011", # typed-argument-default-in-stub # https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules "W191", diff --git a/setuptools/__init__.py b/setuptools/__init__.py index 7ccf80205e..3a09940906 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -221,7 +221,7 @@ def reinitialize_command( ) -> _Command: cmd = _Command.reinitialize_command(self, command, reinit_subcommands) vars(cmd).update(kw) - return cmd + return cmd # pyright: ignore[reportReturnType] # pypa/distutils#307 @abstractmethod def initialize_options(self) -> None: diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index 628a20b40b..07e2f5bd73 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -50,7 +50,7 @@ def finalize_options(self): del self.__dict__['data_files'] self.__updated_files = [] - def copy_file( # type: ignore[override] # No overload, str support only + def copy_file( self, infile: StrPath, outfile: StrPath, @@ -143,7 +143,7 @@ def find_data_files(self, package, src_dir): ) return self.exclude_data_files(package, src_dir, files) - def get_outputs(self, include_bytecode: bool = True) -> list[str]: # type: ignore[override] # Using a real boolean instead of 0|1 + def get_outputs(self, include_bytecode: bool = True) -> list[str]: """See :class:`setuptools.commands.build.SubCommand`""" if self.editable_mode: return list(self.get_output_mapping().keys()) diff --git a/setuptools/command/install_lib.py b/setuptools/command/install_lib.py index 53b68f6363..88ffdbeec9 100644 --- a/setuptools/command/install_lib.py +++ b/setuptools/command/install_lib.py @@ -95,10 +95,9 @@ def copy_tree( self, infile: StrPath, outfile: str, - # override: Using actual booleans - preserve_mode: bool = True, # type: ignore[override] - preserve_times: bool = True, # type: ignore[override] - preserve_symlinks: bool = False, # type: ignore[override] + preserve_mode: bool = True, + preserve_times: bool = True, + preserve_symlinks: bool = False, level: object = 1, ) -> list[str]: assert preserve_mode and preserve_times and not preserve_symlinks diff --git a/setuptools/errors.py b/setuptools/errors.py index 990ecbf4e2..61b0a55c72 100644 --- a/setuptools/errors.py +++ b/setuptools/errors.py @@ -30,15 +30,15 @@ BaseError = _distutils_errors.DistutilsError -class InvalidConfigError(OptionError): # type: ignore[valid-type, misc] # distutils imports are `Any` on python 3.12+ +class InvalidConfigError(OptionError): """Error used for invalid configurations.""" -class RemovedConfigError(OptionError): # type: ignore[valid-type, misc] # distutils imports are `Any` on python 3.12+ +class RemovedConfigError(OptionError): """Error used for configurations that were deprecated and removed.""" -class RemovedCommandError(BaseError, RuntimeError): # type: ignore[valid-type, misc] # distutils imports are `Any` on python 3.12+ +class RemovedCommandError(BaseError, RuntimeError): """Error used for commands that have been removed in setuptools. Since ``setuptools`` is built on ``distutils``, simply removing a command @@ -48,7 +48,7 @@ class RemovedCommandError(BaseError, RuntimeError): # type: ignore[valid-type, """ -class PackageDiscoveryError(BaseError, RuntimeError): # type: ignore[valid-type, misc] # distutils imports are `Any` on python 3.12+ +class PackageDiscoveryError(BaseError, RuntimeError): """Impossible to perform automatic discovery of packages and/or modules. The current project layout or given discovery options can lead to problems when diff --git a/setuptools/extension.py b/setuptools/extension.py index 79bcc203e9..4e05331bd6 100644 --- a/setuptools/extension.py +++ b/setuptools/extension.py @@ -151,12 +151,7 @@ def __init__( # 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 - super().__init__( - name, - sources, # type: ignore[arg-type] # Vendored version of setuptools supports PathLike - *args, - **kw, - ) + super().__init__(name, sources, *args, **kw) def _convert_pyx_sources_to_lang(self): """