Skip to content

Commit

Permalink
Merge simple type annotations from typeshed (#4504)
Browse files Browse the repository at this point in the history
* Merge simple type annotations from typeshed

* Incorrect TypeAlias usage

* Wrap self.always_copy in bool

* Update setuptools/command/editable_wheel.py

* Add jaraco ignore_missing_imports

* Fix type-errors post-merge

* More distutils workarounds

* Remove StrIter

---------

Co-authored-by: Anderson Bravalheri <andersonbravalheri@gmail.com>
  • Loading branch information
Avasam and abravalheri authored Oct 25, 2024
1 parent 1ca55c9 commit 0bc3248
Show file tree
Hide file tree
Showing 29 changed files with 253 additions and 191 deletions.
14 changes: 8 additions & 6 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
strict = False

# Early opt-in even when strict = False
warn_unused_ignores = True
# warn_unused_ignores = True # Disabled until we have distutils stubs for Python 3.12+
warn_redundant_casts = True
enable_error_code = ignore-without-code

Expand Down Expand Up @@ -34,12 +34,14 @@ exclude = (?x)(
# Duplicate module name
| ^pkg_resources/tests/data/my-test-package-source/setup.py$
)

# DistributionMetadata.license_files and DistributionMetadata.license_file
# are dynamically patched in setuptools/_core_metadata.py
# and no DistributionMetadata subclass exists in setuptools
[mypy-setuptools.*]
disable_error_code = attr-defined
disable_error_code =
# DistributionMetadata.license_files and DistributionMetadata.license_file
# are dynamically patched in setuptools/_core_metadata.py
# and no DistributionMetadata subclass exists in setuptools
attr-defined,
# See issue described below about distutils across Python versions
has-type,

# - pkg_resources tests create modules that won't exists statically before the test is run.
# Let's ignore all "import-not-found" since, if an import really wasn't found, then the test would fail.
Expand Down
2 changes: 2 additions & 0 deletions ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ ignore = [
# Only enforcing return type annotations for public modules
"**/tests/**" = ["ANN2"]
"tools/**" = ["ANN2"]
# Temporarily disabling enforced return annotations for the setuptool package to progressively type from Typeshed
"setuptools/**" = ["ANN2"]
# 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"]
Expand Down
8 changes: 3 additions & 5 deletions setuptools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def finalize_options(self):
_fetch_build_eggs(dist)


def _fetch_build_eggs(dist):
def _fetch_build_eggs(dist: Distribution):
try:
dist.fetch_build_eggs(dist.setup_requires)
except Exception as ex:
Expand Down Expand Up @@ -120,10 +120,8 @@ def setup(**attrs):
setup.__doc__ = distutils.core.setup.__doc__

if TYPE_CHECKING:
from typing_extensions import TypeAlias

# Work around a mypy issue where type[T] can't be used as a base: https://github.com/python/mypy/issues/10962
_Command: TypeAlias = distutils.core.Command
from distutils.core import Command as _Command
else:
_Command = monkey.get_unpatched(distutils.core.Command)

Expand Down Expand Up @@ -188,7 +186,7 @@ def _ensure_stringlike(self, option, what, default=None):
)
return val

def ensure_string_list(self, option):
def ensure_string_list(self, option: str):
r"""Ensure that 'option' is a list of strings. If 'option' is
currently a string, we split it either on /,\s*/ or /\s+/, so
"foo bar baz", "foo,bar,baz", and "foo, bar baz" all become
Expand Down
6 changes: 2 additions & 4 deletions setuptools/_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@
import sys
from typing import TYPE_CHECKING, Union

if TYPE_CHECKING:
from typing_extensions import TypeAlias


from more_itertools import unique_everseen

if TYPE_CHECKING:
from typing_extensions import TypeAlias

StrPath: TypeAlias = Union[str, os.PathLike[str]] # Same as _typeshed.StrPath
else:
# Python 3.8 support
Expand Down
35 changes: 20 additions & 15 deletions setuptools/build_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
import tokenize
import warnings
from pathlib import Path
from typing import TYPE_CHECKING, Dict, Iterable, Iterator, List, Union
from typing import TYPE_CHECKING, Iterable, Iterator, List, Mapping, Union

import setuptools

Expand All @@ -53,7 +53,6 @@
if TYPE_CHECKING:
from typing_extensions import TypeAlias


__all__ = [
'get_requires_for_build_sdist',
'get_requires_for_build_wheel',
Expand Down Expand Up @@ -147,7 +146,7 @@ def suppress_known_deprecation():
yield


_ConfigSettings: TypeAlias = Union[Dict[str, Union[str, List[str], None]], None]
_ConfigSettings: TypeAlias = Union[Mapping[str, Union[str, List[str], None]], None]
"""
Currently the user can run::
Expand Down Expand Up @@ -291,7 +290,9 @@ def _arbitrary_args(self, config_settings: _ConfigSettings) -> Iterator[str]:


class _BuildMetaBackend(_ConfigSettingsTranslator):
def _get_build_requires(self, config_settings, requirements):
def _get_build_requires(
self, config_settings: _ConfigSettings, requirements: list[str]
):
sys.argv = [
*sys.argv[:1],
*self._global_args(config_settings),
Expand All @@ -305,7 +306,7 @@ def _get_build_requires(self, config_settings, requirements):

return requirements

def run_setup(self, setup_script='setup.py'):
def run_setup(self, setup_script: str = 'setup.py'):
# Note that we can reuse our build directory between calls
# Correctness comes first, then optimization later
__file__ = os.path.abspath(setup_script)
Expand All @@ -328,13 +329,15 @@ def run_setup(self, setup_script='setup.py'):
"setup-py-deprecated.html",
)

def get_requires_for_build_wheel(self, config_settings=None):
def get_requires_for_build_wheel(self, config_settings: _ConfigSettings = None):
return self._get_build_requires(config_settings, requirements=[])

def get_requires_for_build_sdist(self, config_settings=None):
def get_requires_for_build_sdist(self, config_settings: _ConfigSettings = None):
return self._get_build_requires(config_settings, requirements=[])

def _bubble_up_info_directory(self, metadata_directory: str, suffix: str) -> str:
def _bubble_up_info_directory(
self, metadata_directory: StrPath, suffix: str
) -> str:
"""
PEP 517 requires that the .dist-info directory be placed in the
metadata_directory. To comply, we MUST copy the directory to the root.
Expand All @@ -347,7 +350,7 @@ def _bubble_up_info_directory(self, metadata_directory: str, suffix: str) -> str
# PEP 517 allow other files and dirs to exist in metadata_directory
return info_dir.name

def _find_info_directory(self, metadata_directory: str, suffix: str) -> Path:
def _find_info_directory(self, metadata_directory: StrPath, suffix: str) -> Path:
for parent, dirs, _ in os.walk(metadata_directory):
candidates = [f for f in dirs if f.endswith(suffix)]

Expand All @@ -359,14 +362,14 @@ def _find_info_directory(self, metadata_directory: str, suffix: str) -> Path:
raise errors.InternalError(msg)

def prepare_metadata_for_build_wheel(
self, metadata_directory, config_settings=None
self, metadata_directory: StrPath, config_settings: _ConfigSettings = None
):
sys.argv = [
*sys.argv[:1],
*self._global_args(config_settings),
"dist_info",
"--output-dir",
metadata_directory,
str(metadata_directory),
"--keep-egg-info",
]
with no_install_setup_requires():
Expand Down Expand Up @@ -462,7 +465,7 @@ def build_editable(
self,
wheel_directory: StrPath,
config_settings: _ConfigSettings = None,
metadata_directory: str | None = None,
metadata_directory: StrPath | None = None,
):
# XXX can or should we hide our editable_wheel command normally?
info_dir = self._get_dist_info_dir(metadata_directory)
Expand All @@ -473,11 +476,13 @@ def build_editable(
cmd, ".whl", wheel_directory, config_settings
)

def get_requires_for_build_editable(self, config_settings=None):
def get_requires_for_build_editable(
self, config_settings: _ConfigSettings = None
):
return self.get_requires_for_build_wheel(config_settings)

def prepare_metadata_for_build_editable(
self, metadata_directory, config_settings=None
self, metadata_directory: StrPath, config_settings: _ConfigSettings = None
):
return self.prepare_metadata_for_build_wheel(
metadata_directory, config_settings
Expand All @@ -496,7 +501,7 @@ class _BuildMetaLegacyBackend(_BuildMetaBackend):
and will eventually be removed.
"""

def run_setup(self, setup_script='setup.py'):
def run_setup(self, setup_script: str = 'setup.py'):
# 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)
Expand Down
16 changes: 15 additions & 1 deletion setuptools/command/bdist_egg.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
Build .egg distributions"""

from __future__ import annotations

import marshal
import os
import re
import sys
import textwrap
from sysconfig import get_path, get_python_version
from types import CodeType
from typing import TYPE_CHECKING, Literal

from setuptools import Command
from setuptools.extension import Library
Expand All @@ -18,6 +21,12 @@
from distutils import log
from distutils.dir_util import mkpath, remove_tree

if TYPE_CHECKING:
from typing_extensions import TypeAlias

# Same as zipfile._ZipFileMode from typeshed
_ZipFileMode: TypeAlias = Literal["r", "w", "x", "a"]


def _get_purelib():
return get_path("purelib")
Expand Down Expand Up @@ -431,7 +440,12 @@ def can_scan():


def make_zipfile(
zip_filename, base_dir, verbose=False, dry_run=False, compress=True, mode='w'
zip_filename,
base_dir,
verbose: bool = False,
dry_run: bool = False,
compress=True,
mode: _ZipFileMode = 'w',
):
"""Create a zip file from all the files under 'base_dir'. The output
zip file will be named 'base_dir' + ".zip". Uses either the "zipfile"
Expand Down
6 changes: 3 additions & 3 deletions setuptools/command/bdist_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,9 @@ def initialize_options(self) -> None:
self.relative = False
self.owner = None
self.group = None
self.universal: bool = False
self.compression: int | str = "deflated"
self.python_tag: str = python_tag()
self.universal = False
self.compression: str | int = "deflated"
self.python_tag = python_tag()
self.build_number: str | None = None
self.py_limited_api: str | Literal[False] = False
self.plat_name_supplied = False
Expand Down
8 changes: 4 additions & 4 deletions setuptools/command/build_ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ def get_abi3_suffix():

class build_ext(_build_ext):
distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution
editable_mode: bool = False
inplace: bool = False
editable_mode = False
inplace = False

def run(self):
"""Build extensions in build directory, then copy if --inplace"""
Expand Down Expand Up @@ -410,7 +410,7 @@ def link_shared_object(
library_dirs=None,
runtime_library_dirs=None,
export_symbols=None,
debug=False,
debug: bool = False,
extra_preargs=None,
extra_postargs=None,
build_temp=None,
Expand Down Expand Up @@ -445,7 +445,7 @@ def link_shared_object(
library_dirs=None,
runtime_library_dirs=None,
export_symbols=None,
debug=False,
debug: bool = False,
extra_preargs=None,
extra_postargs=None,
build_temp=None,
Expand Down
18 changes: 10 additions & 8 deletions setuptools/command/build_py.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

from more_itertools import unique_everseen

from setuptools._path import StrPath

from ..dist import Distribution
from ..warnings import SetuptoolsDeprecationWarning

Expand Down Expand Up @@ -48,14 +50,14 @@ def finalize_options(self):
del self.__dict__['data_files']
self.__updated_files = []

def copy_file(
def copy_file( # type: ignore[override] # No overload, str support only
self,
infile,
outfile,
preserve_mode=True,
preserve_times=True,
link=None,
level=1,
infile: StrPath,
outfile: StrPath,
preserve_mode: bool = True,
preserve_times: bool = True,
link: str | None = None,
level: object = 1,
):
# Overwrite base class to allow using links
if link:
Expand Down Expand Up @@ -141,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=True) -> list[str]:
def get_outputs(self, include_bytecode: bool = True) -> list[str]: # type: ignore[override] # Using a real boolean instead of 0|1
"""See :class:`setuptools.commands.build.SubCommand`"""
if self.editable_mode:
return list(self.get_output_mapping().keys())
Expand Down
Loading

0 comments on commit 0bc3248

Please sign in to comment.