Skip to content

Commit

Permalink
Merge branch 'main' into Merge-typeshed-return-annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
Avasam authored Dec 30, 2024
2 parents 5e17283 + 4d4efe5 commit 2ef5dc1
Show file tree
Hide file tree
Showing 47 changed files with 300 additions and 250 deletions.
2 changes: 1 addition & 1 deletion docs/userguide/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ Package discovery
-----------------
For projects that follow a simple directory structure, ``setuptools`` should be
able to automatically detect all :term:`packages <package>` and
:term:`namespaces <namespace-package>`. However, complex projects might include
:term:`namespaces <namespace package>`. However, complex projects might include
additional folders and supporting files that not necessarily should be
distributed (or that can confuse ``setuptools`` auto discovery algorithm).

Expand Down
6 changes: 3 additions & 3 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,16 @@ 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
follow_untyped_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
# - jaraco.envs: https://github.com/jaraco/jaraco.envs/issues/7
# - jaraco.packaging: https://github.com/jaraco/jaraco.packaging/issues/20
# - jaraco.path: https://github.com/jaraco/jaraco.path/issues/2
# - jaraco.text: https://github.com/jaraco/jaraco.text/issues/17
[mypy-jaraco,jaraco.develop,jaraco.envs,jaraco.packaging.*,jaraco.path,jaraco.text]
ignore_missing_imports = True
[mypy-jaraco,jaraco.develop.*,jaraco.envs,jaraco.packaging.*,jaraco.path,jaraco.text]
follow_untyped_imports = True

# Even when excluding a module, import issues can show up due to following import
# https://github.com/python/mypy/issues/11936#issuecomment-1466764006
Expand Down
1 change: 1 addition & 0 deletions newsfragments/4478.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Synced with pypa/distutils@c97a3db2f including better support for free threaded Python on Windows (pypa/distutils#310), improved typing support, and linter accommodations.
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ test = [
"packaging>=24.2",
"jaraco.envs>=2.2",
"pytest-xdist>=3", # Dropped dependency on pytest-fork and py
"jaraco.path>=3.2.0",
"jaraco.path>=3.7.2", # Typing fixes
"build[virtualenv]>=1.0.3",
"filelock>=3.4.0",
"ini2toml[lite]>=0.14",
Expand Down Expand Up @@ -102,7 +102,7 @@ core = [

# for distutils
"jaraco.collections",
"jaraco.functools>=4",
"jaraco.functools >= 4",
"packaging",
"more_itertools",
]
Expand Down Expand Up @@ -135,7 +135,7 @@ type = [
# 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.12,<1.14",
"mypy==1.14.*",
# Typing fixes in version newer than we require at runtime
"importlib_metadata>=7.0.2; python_version < '3.10'",
# Imported unconditionally in tools/finalize.py
Expand Down
27 changes: 25 additions & 2 deletions setuptools/_distutils/cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@
in the distutils.command package.
"""

from __future__ import annotations

import logging
import os
import re
import sys
from collections.abc import Callable
from typing import Any, ClassVar, TypeVar, overload

from . import _modified, archive_util, dir_util, file_util, util
from ._log import log
from .errors import DistutilsOptionError

_CommandT = TypeVar("_CommandT", bound="Command")


class Command:
"""Abstract base class for defining command classes, the "worker bees"
Expand Down Expand Up @@ -44,7 +50,14 @@ class Command:
# 'sub_commands' is usually defined at the *end* of a class, because
# predicates can be unbound methods, so they must already have been
# defined. The canonical example is the "install" command.
sub_commands = []
sub_commands: ClassVar[ # Any to work around variance issues
list[tuple[str, Callable[[Any], bool] | None]]
] = []

user_options: ClassVar[
# Specifying both because list is invariant. Avoids mypy override assignment issues
list[tuple[str, str, str]] | list[tuple[str, str | None, str]]
] = []

# -- Creation/initialization methods -------------------------------

Expand Down Expand Up @@ -305,7 +318,17 @@ def get_finalized_command(self, command, create=True):

# XXX rename to 'get_reinitialized_command()'? (should do the
# same in dist.py, if so)
def reinitialize_command(self, command, reinit_subcommands=False):
@overload
def reinitialize_command(
self, command: str, reinit_subcommands: bool = False
) -> Command: ...
@overload
def reinitialize_command(
self, command: _CommandT, reinit_subcommands: bool = False
) -> _CommandT: ...
def reinitialize_command(
self, command: str | Command, reinit_subcommands=False
) -> Command:
return self.distribution.reinitialize_command(command, reinit_subcommands)

def run_command(self, command):
Expand Down
5 changes: 3 additions & 2 deletions setuptools/_distutils/command/bdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import os
import warnings
from typing import ClassVar

from ..core import Command
from ..errors import DistutilsOptionError, DistutilsPlatformError
Expand All @@ -23,7 +24,7 @@ def show_formats():
pretty_printer.print_help("List of available distribution formats:")


class ListCompat(dict):
class ListCompat(dict[str, tuple[str, str]]):
# adapter to allow for Setuptools compatibility in format_commands
def append(self, item):
warnings.warn(
Expand Down Expand Up @@ -70,7 +71,7 @@ class bdist(Command):
]

# The following commands do not take a format option from bdist
no_format_option = ('bdist_rpm',)
no_format_option: ClassVar[tuple[str, ...]] = ('bdist_rpm',)

# This won't do in reality: will need to distinguish RPM-ish Linux,
# Debian-ish Linux, Solaris, FreeBSD, ..., Windows, Mac OS.
Expand Down
3 changes: 2 additions & 1 deletion setuptools/_distutils/command/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ def finalize_options(self): # noqa: C901
self.build_temp = os.path.join(self.build_base, 'temp' + plat_specifier)
if self.build_scripts is None:
self.build_scripts = os.path.join(
self.build_base, 'scripts-%d.%d' % sys.version_info[:2]
self.build_base,
f'scripts-{sys.version_info.major}.{sys.version_info.minor}',
)

if self.executable is None and sys.executable:
Expand Down
6 changes: 3 additions & 3 deletions setuptools/_distutils/command/build_clib.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import os
from distutils._log import log
from typing import ClassVar

from ..core import Command
from ..errors import DistutilsSetupError
Expand All @@ -31,7 +32,7 @@ def show_compilers():
class build_clib(Command):
description = "build C/C++ libraries used by Python extensions"

user_options = [
user_options: ClassVar[list[tuple[str, str, str]]] = [
('build-clib=', 'b', "directory to build C/C++ libraries to"),
('build-temp=', 't', "directory to put temporary build by-products"),
('debug', 'g', "compile with debugging information"),
Expand Down Expand Up @@ -138,8 +139,7 @@ def check_library_list(self, libraries):

if '/' in name or (os.sep != '/' and os.sep in name):
raise DistutilsSetupError(
f"bad library name '{lib[0]}': "
"may not contain directory separators"
f"bad library name '{lib[0]}': may not contain directory separators"
)

if not isinstance(build_info, dict):
Expand Down
14 changes: 9 additions & 5 deletions setuptools/_distutils/command/build_ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
)
from ..extension import Extension
from ..sysconfig import customize_compiler, get_config_h_filename, get_python_version
from ..util import get_platform, is_mingw
from ..util import get_platform, is_freethreaded, is_mingw

# An extension name is just a dot-separated list of Python NAMEs (ie.
# the same as a fully-qualified module name).
Expand Down Expand Up @@ -333,6 +333,12 @@ def run(self): # noqa: C901
if os.name == 'nt' and self.plat_name != get_platform():
self.compiler.initialize(self.plat_name)

# The official Windows free threaded Python installer doesn't set
# Py_GIL_DISABLED because its pyconfig.h is shared with the
# default build, so define it here (pypa/setuptools#4662).
if os.name == 'nt' and is_freethreaded():
self.compiler.define_macro('Py_GIL_DISABLED', '1')

# And make sure that any compile/link-related options (which might
# come from the command-line or from the setup script) are set in
# that CCompiler object -- that way, they automatically apply to
Expand Down Expand Up @@ -437,8 +443,7 @@ def check_extensions_list(self, extensions): # noqa: C901
for macro in macros:
if not (isinstance(macro, tuple) and len(macro) in (1, 2)):
raise DistutilsSetupError(
"'macros' element of build info dict "
"must be 1- or 2-tuple"
"'macros' element of build info dict must be 1- or 2-tuple"
)
if len(macro) == 1:
ext.undef_macros.append(macro[0])
Expand Down Expand Up @@ -666,8 +671,7 @@ def find_swig(self):
return "swig.exe"
else:
raise DistutilsPlatformError(
"I don't know how to find (much less run) SWIG "
f"on platform '{os.name}'"
f"I don't know how to find (much less run) SWIG on platform '{os.name}'"
)

# -- Name generators -----------------------------------------------
Expand Down
3 changes: 2 additions & 1 deletion setuptools/_distutils/command/build_scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from distutils import sysconfig
from distutils._log import log
from stat import ST_MODE
from typing import ClassVar

from .._modified import newer
from ..core import Command
Expand All @@ -25,7 +26,7 @@
class build_scripts(Command):
description = "\"build\" scripts (copy and fixup #! line)"

user_options = [
user_options: ClassVar[list[tuple[str, str, str]]] = [
('build-dir=', 'd', "directory to \"build\" (copy) to"),
('force', 'f', "forcibly build everything (ignore file timestamps"),
('executable=', 'e', "specify final destination interpreter path"),
Expand Down
8 changes: 3 additions & 5 deletions setuptools/_distutils/command/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"""

import contextlib
from typing import ClassVar

from ..core import Command
from ..errors import DistutilsSetupError
Expand Down Expand Up @@ -41,15 +42,12 @@ class check(Command):
"""This command checks the meta-data of the package."""

description = "perform some checks on the package"
user_options = [
user_options: ClassVar[list[tuple[str, str, str]]] = [
('metadata', 'm', 'Verify meta-data'),
(
'restructuredtext',
'r',
(
'Checks if long string meta-data syntax '
'are reStructuredText-compliant'
),
'Checks if long string meta-data syntax are reStructuredText-compliant',
),
('strict', 's', 'Will exit with an error if a check fails'),
]
Expand Down
8 changes: 4 additions & 4 deletions setuptools/_distutils/command/command_template
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ Implements the Distutils 'x' command.
__revision__ = "$Id$"

from distutils.core import Command
from typing import ClassVar


class x(Command):

# Brief (40-50 characters) description of the command
description = ""

# List of option tuples: long name, short name (None if no short
# name), and help string.
user_options = [('', '',
""),
]
user_options: ClassVar[list[tuple[str, str, str]]] = [
('', '', ""),
]

def initialize_options(self):
self. = None
Expand Down
4 changes: 2 additions & 2 deletions setuptools/_distutils/command/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,8 +407,8 @@ def finalize_options(self): # noqa: C901
'dist_version': self.distribution.get_version(),
'dist_fullname': self.distribution.get_fullname(),
'py_version': py_version,
'py_version_short': '%d.%d' % sys.version_info[:2],
'py_version_nodot': '%d%d' % sys.version_info[:2],
'py_version_short': f'{sys.version_info.major}.{sys.version_info.minor}',
'py_version_nodot': f'{sys.version_info.major}{sys.version_info.minor}',
'sys_prefix': prefix,
'prefix': prefix,
'sys_exec_prefix': exec_prefix,
Expand Down
5 changes: 2 additions & 3 deletions setuptools/_distutils/command/install_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import functools
import os
from typing import Iterable
from collections.abc import Iterable

from ..core import Command
from ..util import change_root, convert_path
Expand All @@ -22,8 +22,7 @@ class install_data(Command):
(
'install-dir=',
'd',
"base directory for installing data files "
"[default: installation base dir]",
"base directory for installing data files [default: installation base dir]",
),
('root=', None, "install everything relative to this alternate root directory"),
('force', 'f', "force installation (overwrite existing files)"),
Expand Down
11 changes: 5 additions & 6 deletions setuptools/_distutils/command/install_egg_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import os
import re
import sys
from typing import ClassVar

from .. import dir_util
from .._log import log
Expand All @@ -18,7 +19,7 @@ class install_egg_info(Command):
"""Install an .egg-info file for the package"""

description = "Install package's PKG-INFO metadata as an .egg-info file"
user_options = [
user_options: ClassVar[list[tuple[str, str, str]]] = [
('install-dir=', 'd', "directory to install to"),
]

Expand All @@ -31,11 +32,9 @@ def basename(self):
Allow basename to be overridden by child class.
Ref pypa/distutils#2.
"""
return "%s-%s-py%d.%d.egg-info" % (
to_filename(safe_name(self.distribution.get_name())),
to_filename(safe_version(self.distribution.get_version())),
*sys.version_info[:2],
)
name = to_filename(safe_name(self.distribution.get_name()))
version = to_filename(safe_version(self.distribution.get_version()))
return f"{name}-{version}-py{sys.version_info.major}.{sys.version_info.minor}.egg-info"

def finalize_options(self):
self.set_undefined_options('install_lib', ('install_dir', 'install_dir'))
Expand Down
4 changes: 3 additions & 1 deletion setuptools/_distutils/command/install_headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
Implements the Distutils 'install_headers' command, to install C/C++ header
files to the Python include directory."""

from typing import ClassVar

from ..core import Command


# XXX force is never used
class install_headers(Command):
description = "install C/C++ header files"

user_options = [
user_options: ClassVar[list[tuple[str, str, str]]] = [
('install-dir=', 'd', "directory to install header files to"),
('force', 'f', "force installation (overwrite existing files)"),
]
Expand Down
6 changes: 3 additions & 3 deletions setuptools/_distutils/command/sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from distutils._log import log
from glob import glob
from itertools import filterfalse
from typing import ClassVar

from ..core import Command
from ..errors import DistutilsOptionError, DistutilsTemplateError
Expand Down Expand Up @@ -114,7 +115,7 @@ def checking_metadata(self):

sub_commands = [('check', checking_metadata)]

READMES = ('README', 'README.txt', 'README.rst')
READMES: ClassVar[tuple[str, ...]] = ('README', 'README.txt', 'README.rst')

def initialize_options(self):
# 'template' and 'manifest' are, respectively, the names of
Expand Down Expand Up @@ -362,8 +363,7 @@ def read_template(self):
# convert_path function
except (DistutilsTemplateError, ValueError) as msg:
self.warn(
"%s, line %d: %s"
% (template.filename, template.current_line, msg)
f"{template.filename}, line {int(template.current_line)}: {msg}"
)
finally:
template.close()
Expand Down
Loading

0 comments on commit 2ef5dc1

Please sign in to comment.