Skip to content

Commit a9d4e1f

Browse files
committed
Merge branch 'main' of https://github.com/pypa/setuptools into typeshed-overload-and-typevar
2 parents 3279406 + 2299319 commit a9d4e1f

File tree

6 files changed

+62
-62
lines changed

6 files changed

+62
-62
lines changed

mypy.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
python_version = 3.8
55
strict = False
66
warn_unused_ignores = True
7+
warn_redundant_casts = True
78
# required to support namespace packages: https://github.com/python/mypy/issues/14057
89
explicit_package_bases = True
910
exclude = (?x)(

pkg_resources/__init__.py

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@
3434
import types
3535
from typing import (
3636
Any,
37-
Iterator,
3837
Literal,
38+
Dict,
39+
Iterator,
3940
Mapping,
4041
MutableSequence,
4142
NamedTuple,
@@ -47,8 +48,6 @@
4748
Callable,
4849
Iterable,
4950
TypeVar,
50-
Optional,
51-
Dict,
5251
overload,
5352
)
5453
import zipfile
@@ -101,6 +100,7 @@
101100

102101
if TYPE_CHECKING:
103102
from _typeshed import BytesPath, StrPath, StrOrBytesPath
103+
from typing_extensions import Self
104104

105105
warnings.warn(
106106
"pkg_resources is deprecated as an API. "
@@ -115,17 +115,17 @@
115115
# Type aliases
116116
_NestedStr = Union[str, Iterable[Union[str, Iterable["_NestedStr"]]]]
117117
_InstallerTypeT = Callable[["Requirement"], "_DistributionT"]
118-
_InstallerType = Callable[["Requirement"], Optional["Distribution"]]
118+
_InstallerType = Callable[["Requirement"], Union["Distribution", None]]
119119
_PkgReqType = Union[str, "Requirement"]
120120
_EPDistType = Union["Distribution", _PkgReqType]
121-
_MetadataType = Optional["IResourceProvider"]
121+
_MetadataType = Union["IResourceProvider", None]
122122
_ResolvedEntryPoint = Any # Can be any attribute in the module
123123
_ResourceStream = Any # TODO / Incomplete: A readable file-like object
124124
# Any object works, but let's indicate we expect something like a module (optionally has __loader__ or __file__)
125125
_ModuleLike = Any
126126
_ProviderFactoryType = Callable[[_ModuleLike], "IResourceProvider"]
127127
_DistFinderType = Callable[[_T, str, bool], Iterable["Distribution"]]
128-
_NSHandlerType = Callable[[_T, str, str, types.ModuleType], Optional[str]]
128+
_NSHandlerType = Callable[[_T, str, str, types.ModuleType], Union[str, None]]
129129
_AdapterT = TypeVar(
130130
"_AdapterT", _DistFinderType[Any], _ProviderFactoryType, _NSHandlerType[Any]
131131
)
@@ -161,15 +161,15 @@ def _declare_state(vartype: str, varname: str, initial_value: _T) -> _T:
161161
return initial_value
162162

163163

164-
def __getstate__():
164+
def __getstate__() -> dict[str, Any]:
165165
state = {}
166166
g = globals()
167167
for k, v in _state_vars.items():
168168
state[k] = g['_sget_' + v](g[k])
169169
return state
170170

171171

172-
def __setstate__(state):
172+
def __setstate__(state: dict[str, Any]) -> dict[str, Any]:
173173
g = globals()
174174
for k, v in state.items():
175175
g['_sset_' + _state_vars[k]](k, g[k], v)
@@ -324,11 +324,11 @@ class VersionConflict(ResolutionError):
324324
_template = "{self.dist} is installed but {self.req} is required"
325325

326326
@property
327-
def dist(self):
327+
def dist(self) -> Distribution:
328328
return self.args[0]
329329

330330
@property
331-
def req(self):
331+
def req(self) -> Requirement:
332332
return self.args[1]
333333

334334
def report(self):
@@ -354,7 +354,7 @@ class ContextualVersionConflict(VersionConflict):
354354
_template = VersionConflict._template + ' by {self.required_by}'
355355

356356
@property
357-
def required_by(self):
357+
def required_by(self) -> set[str]:
358358
return self.args[2]
359359

360360

@@ -367,11 +367,11 @@ class DistributionNotFound(ResolutionError):
367367
)
368368

369369
@property
370-
def req(self):
370+
def req(self) -> Requirement:
371371
return self.args[0]
372372

373373
@property
374-
def requirers(self):
374+
def requirers(self) -> set[str] | None:
375375
return self.args[1]
376376

377377
@property
@@ -696,11 +696,11 @@ def add_entry(self, entry: str):
696696
for dist in find_distributions(entry, True):
697697
self.add(dist, entry, False)
698698

699-
def __contains__(self, dist: Distribution):
699+
def __contains__(self, dist: Distribution) -> bool:
700700
"""True if `dist` is the active distribution for its project"""
701701
return self.by_key.get(dist.key) == dist
702702

703-
def find(self, req: Requirement):
703+
def find(self, req: Requirement) -> Distribution | None:
704704
"""Find a distribution matching requirement `req`
705705
706706
If there is an active distribution for the requested project, this
@@ -746,7 +746,7 @@ def run_script(self, requires: str, script_name: str):
746746
ns['__name__'] = name
747747
self.require(requires)[0].run_script(script_name, ns)
748748

749-
def __iter__(self):
749+
def __iter__(self) -> Iterator[Distribution]:
750750
"""Yield distributions for non-duplicate projects in the working set
751751
752752
The yield order is the order in which the items' path entries were
@@ -1186,7 +1186,7 @@ def scan(self, search_path: Iterable[str] | None = None):
11861186
for dist in find_distributions(item):
11871187
self.add(dist)
11881188

1189-
def __getitem__(self, project_name: str):
1189+
def __getitem__(self, project_name: str) -> list[Distribution]:
11901190
"""Return a newest-to-oldest list of distributions for `project_name`
11911191
11921192
Uses case-insensitive `project_name` comparison, assuming all the
@@ -1290,7 +1290,7 @@ def obtain(
12901290
to the `installer` argument."""
12911291
return installer(requirement) if installer else None
12921292

1293-
def __iter__(self):
1293+
def __iter__(self) -> Iterator[str]:
12941294
"""Yield the unique project names of the available distributions"""
12951295
for key in self._distmap.keys():
12961296
if self[key]:
@@ -1523,7 +1523,7 @@ def cleanup_resources(self, force: bool = False) -> list[str]:
15231523
return []
15241524

15251525

1526-
def get_default_cache():
1526+
def get_default_cache() -> str:
15271527
"""
15281528
Return the ``PYTHON_EGG_CACHE`` environment variable
15291529
or a platform-relevant user cache dir for an app
@@ -1615,7 +1615,7 @@ def invalid_marker(text: str):
16151615
return False
16161616

16171617

1618-
def evaluate_marker(text: str, extra: str | None = None):
1618+
def evaluate_marker(text: str, extra: str | None = None) -> bool:
16191619
"""
16201620
Evaluate a PEP 508 environment marker.
16211621
Return a boolean indicating the marker result in this environment.
@@ -1923,7 +1923,7 @@ class ZipManifests(Dict[str, "MemoizedZipManifests.manifest_mod"]):
19231923
zip manifest builder
19241924
"""
19251925

1926-
# `path` could be `Union["StrPath", IO[bytes]]` but that violates the LSP for `MemoizedZipManifests.load`
1926+
# `path` could be `StrPath | IO[bytes]` but that violates the LSP for `MemoizedZipManifests.load`
19271927
@classmethod
19281928
def build(cls, path: str):
19291929
"""
@@ -1955,7 +1955,7 @@ class manifest_mod(NamedTuple):
19551955
manifest: dict[str, zipfile.ZipInfo]
19561956
mtime: float
19571957

1958-
def load(self, path: str): # type: ignore[override] # ZipManifests.load is a classmethod
1958+
def load(self, path: str) -> dict[str, zipfile.ZipInfo]: # type: ignore[override] # ZipManifests.load is a classmethod
19591959
"""
19601960
Load a manifest at path or return a suitable manifest already loaded.
19611961
"""
@@ -2247,7 +2247,7 @@ def find_distributions(path_item: str, only: bool = False):
22472247

22482248
def find_eggs_in_zip(
22492249
importer: zipimport.zipimporter, path_item: str, only: bool = False
2250-
):
2250+
) -> Iterator[Distribution]:
22512251
"""
22522252
Find eggs in zip files; possibly multiple nested eggs.
22532253
"""
@@ -2340,7 +2340,7 @@ def __call__(self, fullpath):
23402340
return iter(())
23412341

23422342

2343-
def safe_listdir(path):
2343+
def safe_listdir(path: StrOrBytesPath):
23442344
"""
23452345
Attempt to list contents of path, but suppress some exceptions.
23462346
"""
@@ -2356,13 +2356,13 @@ def safe_listdir(path):
23562356
return ()
23572357

23582358

2359-
def distributions_from_metadata(path):
2359+
def distributions_from_metadata(path: str):
23602360
root = os.path.dirname(path)
23612361
if os.path.isdir(path):
23622362
if len(os.listdir(path)) == 0:
23632363
# empty metadata dir; skip
23642364
return
2365-
metadata = PathMetadata(root, path)
2365+
metadata: _MetadataType = PathMetadata(root, path)
23662366
else:
23672367
metadata = FileMetadata(path)
23682368
entry = os.path.basename(path)
@@ -2817,7 +2817,7 @@ def parse_group(
28172817
"""Parse an entry point group"""
28182818
if not MODULE(group):
28192819
raise ValueError("Invalid group name", group)
2820-
this = {}
2820+
this: dict[str, Self] = {}
28212821
for line in yield_lines(lines):
28222822
ep = cls.parse(line, dist)
28232823
if ep.name in this:
@@ -2832,11 +2832,12 @@ def parse_map(
28322832
dist: Distribution | None = None,
28332833
):
28342834
"""Parse a map of entry point groups"""
2835+
_data: Iterable[tuple[str | None, str | Iterable[str]]]
28352836
if isinstance(data, dict):
28362837
_data = data.items()
28372838
else:
28382839
_data = split_sections(data)
2839-
maps: dict[str, dict[str, EntryPoint]] = {}
2840+
maps: dict[str, dict[str, Self]] = {}
28402841
for group, lines in _data:
28412842
if group is None:
28422843
if not lines:
@@ -2895,7 +2896,7 @@ def from_location(
28952896
basename: StrPath,
28962897
metadata: _MetadataType = None,
28972898
**kw: int, # We could set `precedence` explicitly, but keeping this as `**kw` for full backwards and subclassing compatibility
2898-
):
2899+
) -> Distribution:
28992900
project_name, version, py_version, platform = [None] * 4
29002901
basename, ext = os.path.splitext(basename)
29012902
if ext.lower() in _distributionImpl:
@@ -3034,14 +3035,14 @@ def _dep_map(self):
30343035
return self.__dep_map
30353036

30363037
@staticmethod
3037-
def _filter_extras(dm):
3038+
def _filter_extras(dm: dict[str | None, list[Requirement]]):
30383039
"""
30393040
Given a mapping of extras to dependencies, strip off
30403041
environment markers and filter out any dependencies
30413042
not matching the markers.
30423043
"""
30433044
for extra in list(filter(None, dm)):
3044-
new_extra = extra
3045+
new_extra: str | None = extra
30453046
reqs = dm.pop(extra)
30463047
new_extra, _, marker = extra.partition(':')
30473048
fails_marker = marker and (
@@ -3064,7 +3065,7 @@ def _build_dep_map(self):
30643065
def requires(self, extras: Iterable[str] = ()):
30653066
"""List of Requirements needed for this distro if `extras` are used"""
30663067
dm = self._dep_map
3067-
deps = []
3068+
deps: list[Requirement] = []
30683069
deps.extend(dm.get(None, ()))
30693070
for ext in extras:
30703071
try:
@@ -3365,11 +3366,11 @@ def _dep_map(self):
33653366
self.__dep_map = self._compute_dependencies()
33663367
return self.__dep_map
33673368

3368-
def _compute_dependencies(self):
3369+
def _compute_dependencies(self) -> dict[str | None, list[Requirement]]:
33693370
"""Recompute this distribution's dependencies."""
3370-
dm = self.__dep_map = {None: []}
3371+
self.__dep_map: dict[str | None, list[Requirement]] = {None: []}
33713372

3372-
reqs = []
3373+
reqs: list[Requirement] = []
33733374
# Including any condition expressions
33743375
for req in self._parsed_pkg_info.get_all('Requires-Dist') or []:
33753376
reqs.extend(parse_requirements(req))
@@ -3380,13 +3381,15 @@ def reqs_for_extra(extra):
33803381
yield req
33813382

33823383
common = types.MappingProxyType(dict.fromkeys(reqs_for_extra(None)))
3383-
dm[None].extend(common)
3384+
self.__dep_map[None].extend(common)
33843385

33853386
for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []:
33863387
s_extra = safe_extra(extra.strip())
3387-
dm[s_extra] = [r for r in reqs_for_extra(extra) if r not in common]
3388+
self.__dep_map[s_extra] = [
3389+
r for r in reqs_for_extra(extra) if r not in common
3390+
]
33883391

3389-
return dm
3392+
return self.__dep_map
33903393

33913394

33923395
_distributionImpl = {
@@ -3447,7 +3450,7 @@ def __eq__(self, other: object):
34473450
def __ne__(self, other):
34483451
return not self == other
34493452

3450-
def __contains__(self, item: Distribution | str | tuple[str, ...]):
3453+
def __contains__(self, item: Distribution | str | tuple[str, ...]) -> bool:
34513454
if isinstance(item, Distribution):
34523455
if item.key != self.key:
34533456
return False
@@ -3511,7 +3514,7 @@ def _bypass_ensure_directory(path):
35113514
pass
35123515

35133516

3514-
def split_sections(s: _NestedStr):
3517+
def split_sections(s: _NestedStr) -> Iterator[tuple[str | None, list[str]]]:
35153518
"""Split a string or iterable thereof into (section, content) pairs
35163519
35173520
Each ``section`` is a stripped version of the section header ("[section]")

setuptools/command/editable_wheel.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ def template_vars(self) -> tuple[str, str, dict[str, str], dict[str, list[str]]]
515515
)
516516

517517
legacy_namespaces = {
518-
cast(str, pkg): find_package_path(pkg, roots, self.dist.src_root or "")
518+
pkg: find_package_path(pkg, roots, self.dist.src_root or "")
519519
for pkg in self.dist.namespace_packages or []
520520
}
521521

setuptools/config/_apply_pyprojecttoml.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
import logging
1414
import os
15-
from collections.abc import Mapping
1615
from email.headerregistry import Address
1716
from functools import partial, reduce
1817
from inspect import cleandoc
@@ -22,8 +21,9 @@
2221
TYPE_CHECKING,
2322
Any,
2423
Callable,
24+
Dict,
25+
Mapping,
2526
Union,
26-
cast,
2727
)
2828
from .._path import StrPath
2929
from ..errors import RemovedConfigError
@@ -35,7 +35,7 @@
3535
from setuptools.dist import Distribution # noqa
3636

3737
EMPTY: Mapping = MappingProxyType({}) # Immutable dict-like
38-
_DictOrStr = Union[dict, str]
38+
_ProjectReadmeValue = Union[str, Dict[str, str]]
3939
_CorrespFn = Callable[["Distribution", Any, StrPath], None]
4040
_Correspondence = Union[str, _CorrespFn]
4141

@@ -149,15 +149,16 @@ def _guess_content_type(file: str) -> str | None:
149149
raise ValueError(f"Undefined content type for {file}, {msg}")
150150

151151

152-
def _long_description(dist: Distribution, val: _DictOrStr, root_dir: StrPath):
152+
def _long_description(dist: Distribution, val: _ProjectReadmeValue, root_dir: StrPath):
153153
from setuptools.config import expand
154154

155+
file: str | tuple[()]
155156
if isinstance(val, str):
156-
file: str | list = val
157+
file = val
157158
text = expand.read_files(file, root_dir)
158-
ctype = _guess_content_type(val)
159+
ctype = _guess_content_type(file)
159160
else:
160-
file = val.get("file") or []
161+
file = val.get("file") or ()
161162
text = val.get("text") or expand.read_files(file, root_dir)
162163
ctype = val["content-type"]
163164

@@ -167,7 +168,7 @@ def _long_description(dist: Distribution, val: _DictOrStr, root_dir: StrPath):
167168
_set_config(dist, "long_description_content_type", ctype)
168169

169170
if file:
170-
dist._referenced_files.add(cast(str, file))
171+
dist._referenced_files.add(file)
171172

172173

173174
def _license(dist: Distribution, val: dict, root_dir: StrPath):

0 commit comments

Comments
 (0)