[setuptools] setuptools.setup Complete partially Unknown method and fix Command type variance issue (#15161)

This commit is contained in:
Avasam
2025-12-22 09:53:14 -05:00
committed by GitHub
parent 90d855985b
commit 7dea89995d
2 changed files with 46 additions and 24 deletions
@@ -0,0 +1,23 @@
from typing_extensions import assert_type
from setuptools import Command as setuptools_Command, Distribution as setuptools_Distribution, setup
from setuptools._distutils.cmd import Command as distutils_Command
from setuptools._distutils.dist import Distribution as distutils_Distribution
# Ensure that any distutils-derived classes are usable w/o type variance issues
assert_type(
setup(
cmdclass=dict[str, type[distutils_Command]](),
command_obj=dict[str, distutils_Command](),
distclass=distutils_Distribution,
),
distutils_Distribution,
)
assert_type(
setup(
cmdclass=dict[str, type[setuptools_Command]](),
command_obj=dict[str, setuptools_Command](),
distclass=setuptools_Distribution,
),
setuptools_Distribution,
)
+23 -24
View File
@@ -1,4 +1,4 @@
from _typeshed import StrPath
from _typeshed import Incomplete, StrPath
from abc import abstractmethod
from collections.abc import ItemsView, Iterable, Mapping, Sequence
from typing import Any, Literal, Protocol, TypedDict, TypeVar, overload, type_check_only
@@ -36,9 +36,7 @@ from .warnings import SetuptoolsDeprecationWarning as SetuptoolsDeprecationWarni
_CommandT = TypeVar("_CommandT", bound=_Command)
_DistributionT = TypeVar("_DistributionT", bound=_Distribution, default=Distribution)
_T = TypeVar("_T")
_KT = TypeVar("_KT")
_VT = TypeVar("_VT")
_VT_co = TypeVar("_VT_co", covariant=True)
__all__ = [
@@ -54,22 +52,23 @@ __all__ = [
__version__: str
# We need any Command subclass to be valid
# Any: pyright would accept using covariance in __setitem__, but mypy won't let a dict be assignable to this protocol
# This is unsound, but it's a quirk of setuptools' internals
@type_check_only
class _DictLike(Protocol[_KT, _VT_co]): # type: ignore[misc] # Covariant type as parameter
@overload
def get(self, key: _KT, /) -> _VT_co | None: ...
@overload
def get(self, key: _KT, default: _VT_co, /) -> _VT_co: ... # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] # Covariant type as parameter
@overload
def get(self, key: _KT, default: _T, /) -> _VT_co | _T: ...
class _DictLike(Protocol[_KT, _VT_co]):
# See note about using _VT_co instead of Any
def get(self, key: _KT, default: Any | None = None, /) -> _VT_co | None: ...
def items(self) -> ItemsView[_KT, _VT_co]: ...
def keys(self) -> Iterable[_KT]: ...
def __getitem__(self, key: _KT, /) -> _VT_co: ...
def __contains__(self, x: Any, /) -> bool: ...
def __contains__(self, x: object, /) -> bool: ...
@type_check_only
class _MutableDictLike(_DictLike[_KT, _VT], Protocol):
def __setitem__(self, key: _KT, value: _VT, /) -> None: ...
class _MutableDictLike(_DictLike[_KT, _VT_co], Protocol):
# See note about using _VT_co instead of Any
def __setitem__(self, key: _KT, value: Any, /) -> None: ...
def setdefault(self, key: _KT, default: Any, /) -> _VT_co: ...
@type_check_only
class _BuildInfo(TypedDict):
@@ -107,9 +106,9 @@ def setup(
download_url: str | None = None,
# Attributes from distutils.dist.Distribution.__init__ (except self.metadata)
# These take priority over attributes from distutils.dist.Distribution.display_option_names
verbose=True,
dry_run=False,
help=False,
verbose: bool = True,
dry_run: bool = False,
help: bool = False,
cmdclass: _MutableDictLike[str, type[_Command]] = {},
command_packages: str | list[str] | None = None,
script_name: StrPath | None = ..., # default is actually set in distutils.core.setup
@@ -123,7 +122,7 @@ def setup(
ext_modules: Sequence[_Extension] | None = None,
ext_package: str | None = None,
include_dirs: list[str] | None = None,
extra_path=None,
extra_path: Never = ..., # Deprecated
scripts: list[str] | None = None,
data_files: list[tuple[str, Sequence[str]]] | None = None,
password: str = "",
@@ -149,13 +148,13 @@ def setup(
setup_requires: list[str] = [],
# From Distribution._DISTUTILS_UNSUPPORTED_METADATA set in Distribution._set_metadata_defaults
long_description_content_type: str | None = None,
project_urls={},
provides_extras={},
license_expression=None,
license_file=None,
license_files=None,
install_requires=[],
extras_require={},
project_urls: _DictLike[Incomplete, Incomplete] = {},
provides_extras: _MutableDictLike[Incomplete, Incomplete] = {},
license_expression: str | None = None,
license_file: Never = ..., # Deprecated
license_files: Iterable[str] | None = None,
install_requires: str | Iterable[str] = [],
extras_require: _DictLike[Incomplete, Incomplete] = {},
# kwargs used directly in distutils.core.setup
distclass: type[_DistributionT] = Distribution, # type: ignore[assignment] # noqa: Y011
# Custom Distributions could accept more params