Skip to content

Type setup method #5021

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
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
10 changes: 3 additions & 7 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,14 @@
"""
Undo secondary effect of `extra_path` adding to `install_lib`
"""
suffix = os.path.relpath(self.install_lib, self.install_libbase)

Check warning on line 51 in setup.py

View workflow job for this annotation

GitHub Actions / pyright (3.9, ubuntu-latest)

No overloads for "relpath" match the provided arguments (reportCallIssue)

if suffix.strip() == self._pth_contents.strip():
self.install_lib = self.install_libbase


setup_params = dict(
cmdclass={'install': install_with_pth},
)

if __name__ == '__main__':
# allow setup.py to run from another directory
# TODO: Use a proper conditional statement here
here and os.chdir(here) # type: ignore[func-returns-value]
dist = setuptools.setup(**setup_params)
if here:
os.chdir(here)
dist = setuptools.setup(cmdclass={'install': install_with_pth})
116 changes: 106 additions & 10 deletions setuptools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
import os
import sys
from abc import abstractmethod
from collections.abc import Mapping
from typing import TYPE_CHECKING, TypeVar, overload
from collections.abc import Iterable, Mapping, Sequence
from typing import TYPE_CHECKING, Any, Literal, TypeVar, overload

sys.path.extend(((vendor_path := os.path.join(os.path.dirname(os.path.dirname(__file__)), 'setuptools', '_vendor')) not in sys.path) * [vendor_path]) # fmt: skip
# workaround for #4476
Expand All @@ -21,6 +21,7 @@
import _distutils_hack.override # noqa: F401

from . import logging, monkey
from ._path import StrPath
from .depends import Require
from .discovery import PackageFinder, PEP420PackageFinder
from .dist import Distribution
Expand Down Expand Up @@ -108,13 +109,106 @@ def _fetch_build_eggs(dist: Distribution):
raise


def setup(**attrs) -> Distribution:
logging.configure()
# Make sure we have any requirements needed to interpret 'attrs'.
_install_setup_requires(attrs)
# Override return type of distutils.core.Distribution with setuptools.dist.Distribution
# (implicitly implemented via `setuptools.monkey.patch_all`).
return distutils.core.setup(**attrs) # type: ignore[return-value]
if TYPE_CHECKING:
from typing_extensions import Never

from setuptools.command.build_clib import _BuildInfo

_DistributionT = TypeVar(
"_DistributionT",
bound=distutils.core.Distribution,
default=Distribution,
)

def setup(
*,
# Attributes from distutils.dist.DistributionMetadata.set_*
# These take priority over attributes from distutils.dist.DistributionMetadata.__init__
keywords: str | Iterable[str] = ...,
platforms: str | Iterable[str] = ...,
classifiers: str | Iterable[str] = ...,
requires: Iterable[str] = ...,
provides: Iterable[str] = ...,
obsoletes: Iterable[str] = ...,
# Attributes from distutils.dist.DistributionMetadata.__init__
# These take priority over attributes from distutils.dist.Distribution.__init__
name: str | None = None,
version: str | None = None,
author: str | None = None,
author_email: str | None = None,
maintainer: str | None = None,
maintainer_email: str | None = None,
url: str | None = None,
license: str | None = None,
description: str | None = None,
long_description: str | None = None,
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,
cmdclass: dict[str, type[_Command]] = {},
command_packages: str | list[str] | None = None,
script_name: StrPath
| None = ..., # default is actually set in distutils.core.setup
script_args: list[str]
| None = ..., # default is actually set in distutils.core.setup
command_options: dict[str, dict[str, tuple[str, str]]] = {},
packages: list[str] | None = None,
package_dir: Mapping[str, str] | None = None,
py_modules: list[str] | None = None,
libraries: list[tuple[str, _BuildInfo]] | None = None,
headers: list[str] | None = None,
ext_modules: Sequence[distutils.core.Extension] | None = None,
ext_package: str | None = None,
include_dirs: list[str] | None = None,
extra_path=None,
scripts: list[str] | None = None,
data_files: list[tuple[str, list[str]]] | None = None,
password: str = '',
command_obj: dict[str, _Command] = {},
have_run: dict[str, bool] = {},
# kwargs used directly in distutils.dist.Distribution.__init__
options: Mapping[str, Mapping[str, str]] | None = None,
licence: Never = ..., # Deprecated
# Attributes from distutils.dist.Distribution.display_option_names
# (this can more easily be copied from the `if TYPE_CHECKING` block)
help_commands: bool = False,
fullname: str | Literal[False] = False,
contact: str | Literal[False] = False,
contact_email: str | Literal[False] = False,
# kwargs used directly in setuptools.dist.Distribution.__init__
# and attributes from setuptools.dist.Distribution.__init__
package_data: dict[str, list[str]] = {},
dist_files: list[tuple[str, str, str]] = [],
include_package_data: bool | None = None,
exclude_package_data: dict[str, list[str]] | None = None,
src_root: str | None = None,
dependency_links: list[str] = [],
setup_requires: list[str] = [],
# From Distribution._DISTUTILS_UNSUPPORTED_METADATA set in Distribution._set_metadata_defaults
long_description_content_type: str | None = None,
project_urls=dict(),
provides_extras=dict(),
license_expression=None,
license_file=None,
license_files=None,
install_requires=list(),
extras_require=dict(),
# kwargs used directly in distutils.core.setup
distclass: type[_DistributionT] = Distribution, # type: ignore[assignment]
# Custom Distributions could accept more params
**attrs: Any,
) -> _DistributionT: ...

else:

def setup(**attrs) -> Distribution:
logging.configure()
# Make sure we have any requirements needed to interpret 'attrs'.
_install_setup_requires(attrs)
return distutils.core.setup(**attrs)


setup.__doc__ = distutils.core.setup.__doc__
Expand Down Expand Up @@ -167,7 +261,9 @@ class Command(_Command):
command_consumes_arguments = False
distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution

def __init__(self, dist: Distribution, **kw) -> None:
# Any: The kwargs could match any Command attribute including from subclasses
# and subclasses can further override it to include any type.
def __init__(self, dist: Distribution, **kw: Any) -> None:
"""
Construct the command for dist, updating
vars(self) with any keyword parameters.
Expand Down
18 changes: 17 additions & 1 deletion setuptools/command/build_clib.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
from __future__ import annotations

from collections.abc import Iterable
from typing import TYPE_CHECKING, TypedDict

from ..dist import Distribution
from ..modified import newer_pairwise_group

import distutils.command.build_clib as orig
from distutils import log
from distutils.errors import DistutilsSetupError

if TYPE_CHECKING:
from typing_extensions import NotRequired


class _BuildInfo(TypedDict):
sources: list[str] | tuple[str, ...]
obj_deps: NotRequired[dict[str, list[str] | tuple[str, ...]]]
macros: NotRequired[list[tuple[str] | tuple[str, str | None]]]
include_dirs: NotRequired[list[str]]
cflags: NotRequired[list[str]]


class build_clib(orig.build_clib):
"""
Expand All @@ -24,7 +40,7 @@ class build_clib(orig.build_clib):

distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution

def build_libraries(self, libraries) -> None:
def build_libraries(self, libraries: Iterable[tuple[str, _BuildInfo]]) -> None:
for lib_name, build_info in libraries:
sources = build_info.get('sources')
if sources is None or not isinstance(sources, (list, tuple)):
Expand Down
Loading