Skip to content

Commit 2cec4fc

Browse files
committed
Type-check with mypy on Python 3.12
1 parent a6f7484 commit 2cec4fc

File tree

9 files changed

+54
-31
lines changed

9 files changed

+54
-31
lines changed

mypy.ini

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[mypy]
22
# CI should test for all versions, local development gets hints for oldest supported
3-
# Some upstream typeshed distutils stubs fixes are necessary before we can start testing on Python 3.12
4-
python_version = 3.8
3+
# But our testing setup doesn't allow passing CLI arguments, so local devs have to set this manually.
4+
# python_version = 3.8
55
strict = False
66
warn_unused_ignores = True
77
warn_redundant_casts = True
@@ -30,15 +30,19 @@ disable_error_code = attr-defined
3030
[mypy-pkg_resources.tests.*]
3131
disable_error_code = import-not-found
3232

33-
# - distutils._modified has different errors on Python 3.8 [import-untyped], on Python 3.9+ [import-not-found]
33+
# - distutils doesn't exist on Python 3.12, unfortunately, this means typing
34+
# will be missing for subclasses of distutils on Python 3.12 until either:
35+
# - support for `SETUPTOOLS_USE_DISTUTILS=stdlib` is dropped (#3625)
36+
# for setuptools to import `_distutils` directly
37+
# - or non-stdlib distutils typings are exposed
3438
# - All jaraco modules are still untyped
3539
# - _validate_project sometimes complains about trove_classifiers (#4296)
3640
# - wheel appears to be untyped
37-
[mypy-distutils._modified,jaraco.*,trove_classifiers,wheel.*]
41+
[mypy-distutils.*,jaraco.*,trove_classifiers,wheel.*]
3842
ignore_missing_imports = True
3943

4044
# Even when excluding a module, import issues can show up due to following import
4145
# https://github.com/python/mypy/issues/11936#issuecomment-1466764006
42-
[mypy-setuptools.config._validate_pyproject.*]
46+
[mypy-setuptools.config._validate_pyproject.*,setuptools._distutils.*]
4347
follow_imports = silent
4448
# silent => ignore errors when following imports

setuptools/__init__.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
"""Extensions to the 'distutils' for large or complex distributions"""
2+
# mypy: disable_error_code=override
3+
# Command.reinitialize_command has an extra **kw param that distutils doesn't have
4+
# Can't disable on the exact line because distutils doesn't exists on Python 3.12
5+
# and mypy isn't aware of distutils_hack, causing distutils.core.Command to be Any,
6+
# and a [unused-ignore] to be raised on 3.12+
27

38
from __future__ import annotations
49

@@ -114,8 +119,10 @@ def setup(**attrs):
114119
setup.__doc__ = distutils.core.setup.__doc__
115120

116121
if TYPE_CHECKING:
122+
from typing_extensions import TypeAlias
123+
117124
# Work around a mypy issue where type[T] can't be used as a base: https://github.com/python/mypy/issues/10962
118-
_Command = distutils.core.Command
125+
_Command: TypeAlias = distutils.core.Command
119126
else:
120127
_Command = monkey.get_unpatched(distutils.core.Command)
121128

@@ -207,7 +214,7 @@ def ensure_string_list(self, option):
207214
"'%s' must be a list of strings (got %r)" % (option, val)
208215
)
209216

210-
@overload # type:ignore[override] # Extra **kw param
217+
@overload
211218
def reinitialize_command(
212219
self, command: str, reinit_subcommands: bool = False, **kw
213220
) -> _Command: ...

setuptools/build_meta.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,9 +385,10 @@ def _build_with_temp_dir(
385385

386386
# Build in a temporary directory, then copy to the target.
387387
os.makedirs(result_directory, exist_ok=True)
388-
temp_opts = {"prefix": ".tmp-", "dir": result_directory}
389388

390-
with tempfile.TemporaryDirectory(**temp_opts) as tmp_dist_dir:
389+
with tempfile.TemporaryDirectory(
390+
prefix=".tmp-", dir=result_directory
391+
) as tmp_dist_dir:
391392
sys.argv = [
392393
*sys.argv[:1],
393394
*self._global_args(config_settings),

setuptools/command/build_ext.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
get_config_var("LDSHARED")
3131
# Not publicly exposed in typeshed distutils stubs, but this is done on purpose
3232
# See https://github.com/pypa/setuptools/pull/4228#issuecomment-1959856400
33-
from distutils.sysconfig import _config_vars as _CONFIG_VARS # type: ignore # noqa
33+
from distutils.sysconfig import _config_vars as _CONFIG_VARS # noqa: E402
3434

3535

3636
def _customize_compiler_for_shlib(compiler):

setuptools/command/sdist.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
from __future__ import annotations
12
from distutils import log
23
import distutils.command.sdist as orig
34
import os
45
import contextlib
56
from itertools import chain
7+
from typing import ClassVar
68

79
from .._importlib import metadata
810
from ..dist import Distribution
@@ -45,7 +47,7 @@ class sdist(orig.sdist):
4547
]
4648

4749
distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution
48-
negative_opt = {}
50+
negative_opt: ClassVar[dict[str, str]] = {} # type: ignore[misc] # Fixed upstream in typeshed to be a ClassVar. Should be included in mypy 1.12
4951

5052
README_EXTENSIONS = ['', '.rst', '.txt', '.md']
5153
READMES = tuple('README{0}'.format(ext) for ext in README_EXTENSIONS)

setuptools/config/setupcfg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def _apply(
108108
filenames = [*other_files, filepath]
109109

110110
try:
111-
_Distribution.parse_config_files(dist, filenames=filenames) # type: ignore[arg-type] # TODO: fix in distutils stubs
111+
_Distribution.parse_config_files(dist, filenames=filenames)
112112
handlers = parse_configuration(
113113
dist, dist.command_options, ignore_option_errors=ignore_option_errors
114114
)

setuptools/dist.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,10 @@ def check_packages(dist, attr, value):
194194

195195

196196
if TYPE_CHECKING:
197+
from typing_extensions import TypeAlias
198+
197199
# Work around a mypy issue where type[T] can't be used as a base: https://github.com/python/mypy/issues/10962
198-
_Distribution = distutils.core.Distribution
200+
_Distribution: TypeAlias = distutils.core.Distribution
199201
else:
200202
_Distribution = get_unpatched(distutils.core.Distribution)
201203

setuptools/errors.py

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,35 @@
33
Provides exceptions used by setuptools modules.
44
"""
55

6+
from __future__ import annotations
7+
8+
from typing import TYPE_CHECKING
69
from distutils import errors as _distutils_errors
710

11+
if TYPE_CHECKING:
12+
from typing_extensions import TypeAlias
813

914
# Re-export errors from distutils to facilitate the migration to PEP632
1015

11-
ByteCompileError = _distutils_errors.DistutilsByteCompileError
12-
CCompilerError = _distutils_errors.CCompilerError
13-
ClassError = _distutils_errors.DistutilsClassError
14-
CompileError = _distutils_errors.CompileError
15-
ExecError = _distutils_errors.DistutilsExecError
16-
FileError = _distutils_errors.DistutilsFileError
17-
InternalError = _distutils_errors.DistutilsInternalError
18-
LibError = _distutils_errors.LibError
19-
LinkError = _distutils_errors.LinkError
20-
ModuleError = _distutils_errors.DistutilsModuleError
21-
OptionError = _distutils_errors.DistutilsOptionError
22-
PlatformError = _distutils_errors.DistutilsPlatformError
23-
PreprocessError = _distutils_errors.PreprocessError
24-
SetupError = _distutils_errors.DistutilsSetupError
25-
TemplateError = _distutils_errors.DistutilsTemplateError
26-
UnknownFileError = _distutils_errors.UnknownFileError
16+
ByteCompileError: TypeAlias = _distutils_errors.DistutilsByteCompileError
17+
CCompilerError: TypeAlias = _distutils_errors.CCompilerError
18+
ClassError: TypeAlias = _distutils_errors.DistutilsClassError
19+
CompileError: TypeAlias = _distutils_errors.CompileError
20+
ExecError: TypeAlias = _distutils_errors.DistutilsExecError
21+
FileError: TypeAlias = _distutils_errors.DistutilsFileError
22+
InternalError: TypeAlias = _distutils_errors.DistutilsInternalError
23+
LibError: TypeAlias = _distutils_errors.LibError
24+
LinkError: TypeAlias = _distutils_errors.LinkError
25+
ModuleError: TypeAlias = _distutils_errors.DistutilsModuleError
26+
OptionError: TypeAlias = _distutils_errors.DistutilsOptionError
27+
PlatformError: TypeAlias = _distutils_errors.DistutilsPlatformError
28+
PreprocessError: TypeAlias = _distutils_errors.PreprocessError
29+
SetupError: TypeAlias = _distutils_errors.DistutilsSetupError
30+
TemplateError: TypeAlias = _distutils_errors.DistutilsTemplateError
31+
UnknownFileError: TypeAlias = _distutils_errors.UnknownFileError
2732

2833
# The root error class in the hierarchy
29-
BaseError = _distutils_errors.DistutilsError
34+
BaseError: TypeAlias = _distutils_errors.DistutilsError
3035

3136

3237
class InvalidConfigError(OptionError):

setuptools/extension.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ def _have_cython():
2525
# for compatibility
2626
have_pyrex = _have_cython
2727
if TYPE_CHECKING:
28+
from typing_extensions import TypeAlias
29+
2830
# Work around a mypy issue where type[T] can't be used as a base: https://github.com/python/mypy/issues/10962
29-
_Extension = distutils.core.Extension
31+
_Extension: TypeAlias = distutils.core.Extension
3032
else:
3133
_Extension = get_unpatched(distutils.core.Extension)
3234

0 commit comments

Comments
 (0)