Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions stubs/setuptools/@tests/test_cases/check_setup.py
Original file line number Diff line number Diff line change
@@ -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,
)
47 changes: 23 additions & 24 deletions stubs/setuptools/setuptools/__init__.pyi
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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__ = [
Expand 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):
Expand Down Expand Up @@ -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
Expand All @@ -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 = "",
Expand All @@ -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
Expand Down