Skip to content

Commit 31decc9

Browse files
authored
Using dict as an OrderedDict and allowed using dict as an ordered type in setuptools.dist.check_requirements (#4575)
2 parents 65c6ff5 + 2072d98 commit 31decc9

File tree

6 files changed

+20
-29
lines changed

6 files changed

+20
-29
lines changed

newsfragments/4575.feature.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Allowed using `dict` as an ordered type in ``setuptools.dist.check_requirements`` -- by :user:`Avasam`

setuptools/command/_requirestxt.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,11 @@
1818
from packaging.requirements import Requirement
1919

2020
from .. import _reqs
21+
from .._reqs import _StrOrIter
2122

2223
# dict can work as an ordered set
2324
_T = TypeVar("_T")
2425
_Ordered = Dict[_T, None]
25-
_ordered = dict
26-
_StrOrIter = _reqs._StrOrIter
2726

2827

2928
def _prepare(

setuptools/command/egg_info.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
33
Create a distribution's .egg-info directory and contents"""
44

5-
import collections
65
import functools
76
import os
87
import re
@@ -211,11 +210,9 @@ def save_version_info(self, filename):
211210
build tag. Install build keys in a deterministic order
212211
to avoid arbitrary reordering on subsequent builds.
213212
"""
214-
egg_info = collections.OrderedDict()
215213
# follow the order these keys would have been added
216214
# when PYTHONHASHSEED=0
217-
egg_info['tag_build'] = self.tags()
218-
egg_info['tag_date'] = 0
215+
egg_info = dict(tag_build=self.tags(), tag_date=0)
219216
edit_config(filename, dict(egg_info=egg_info))
220217

221218
def finalize_options(self):

setuptools/dist.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
from typing import (
1212
TYPE_CHECKING,
1313
Any,
14+
Dict,
1415
List,
1516
MutableMapping,
16-
NoReturn,
17+
Sequence,
1718
Tuple,
1819
Union,
19-
overload,
2020
)
2121

2222
from more_itertools import partition, unique_everseen
@@ -30,7 +30,6 @@
3030
command as _, # noqa: F401 # imported for side-effects
3131
)
3232
from ._importlib import metadata
33-
from ._reqs import _StrOrIter
3433
from .config import pyprojecttoml, setupcfg
3534
from .discovery import ConfigDiscovery
3635
from .monkey import get_unpatched
@@ -63,7 +62,13 @@
6362
"""
6463
_Sequence: TypeAlias = Union[Tuple[str, ...], List[str]]
6564
# This is how stringifying _Sequence would look in Python 3.10
66-
_requence_type_repr = "tuple[str, ...] | list[str]"
65+
_sequence_type_repr = "tuple[str, ...] | list[str]"
66+
_OrderedStrSequence: TypeAlias = Union[str, Dict[str, Any], Sequence[str]]
67+
"""
68+
:meta private:
69+
Avoid single-use iterable. Disallow sets.
70+
A poor approximation of an OrderedSequence (dict doesn't match a Sequence).
71+
"""
6772

6873

6974
def __getattr__(name: str) -> Any: # pragma: no cover
@@ -97,7 +102,7 @@ def assert_string_list(dist, attr: str, value: _Sequence) -> None:
97102
assert ''.join(value) != value
98103
except (TypeError, ValueError, AttributeError, AssertionError) as e:
99104
raise DistutilsSetupError(
100-
f"{attr!r} must be of type <{_requence_type_repr}> (got {value!r})"
105+
f"{attr!r} must be of type <{_sequence_type_repr}> (got {value!r})"
101106
) from e
102107

103108

@@ -173,15 +178,11 @@ def invalid_unless_false(dist, attr, value):
173178
raise DistutilsSetupError(f"{attr} is invalid.")
174179

175180

176-
@overload
177-
def check_requirements(dist, attr: str, value: set | dict) -> NoReturn: ...
178-
@overload
179-
def check_requirements(dist, attr: str, value: _StrOrIter) -> None: ...
180-
def check_requirements(dist, attr: str, value: _StrOrIter) -> None:
181+
def check_requirements(dist, attr: str, value: _OrderedStrSequence) -> None:
181182
"""Verify that install_requires is a valid requirements list"""
182183
try:
183184
list(_reqs.parse(value))
184-
if isinstance(value, (dict, set)):
185+
if isinstance(value, set):
185186
raise TypeError("Unordered types are not allowed")
186187
except (TypeError, ValueError) as error:
187188
msg = (
@@ -810,7 +811,7 @@ def _exclude_misc(self, name: str, value: _Sequence) -> None:
810811
"""Handle 'exclude()' for list/tuple attrs without a special handler"""
811812
if not isinstance(value, _sequence):
812813
raise DistutilsSetupError(
813-
f"{name}: setting must be of type <{_requence_type_repr}> (got {value!r})"
814+
f"{name}: setting must be of type <{_sequence_type_repr}> (got {value!r})"
814815
)
815816
try:
816817
old = getattr(self, name)
@@ -828,7 +829,7 @@ def _include_misc(self, name: str, value: _Sequence) -> None:
828829

829830
if not isinstance(value, _sequence):
830831
raise DistutilsSetupError(
831-
f"{name}: setting must be of type <{_requence_type_repr}> (got {value!r})"
832+
f"{name}: setting must be of type <{_sequence_type_repr}> (got {value!r})"
832833
)
833834
try:
834835
old = getattr(self, name)
@@ -870,7 +871,7 @@ def exclude(self, **attrs):
870871
def _exclude_packages(self, packages: _Sequence) -> None:
871872
if not isinstance(packages, _sequence):
872873
raise DistutilsSetupError(
873-
f"packages: setting must be of type <{_requence_type_repr}> (got {packages!r})"
874+
f"packages: setting must be of type <{_sequence_type_repr}> (got {packages!r})"
874875
)
875876
list(map(self.exclude_package, packages))
876877

setuptools/tests/test_core_metadata.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,6 @@ def test_parity_with_metadata_from_pypa_wheel(tmp_path):
310310
python_requires=">=3.8",
311311
install_requires="""
312312
packaging==23.2
313-
ordered-set==3.1.1
314313
more-itertools==8.8.0; extra == "other"
315314
jaraco.text==3.7.0
316315
importlib-resources==5.10.2; python_version<"3.8"

setuptools/tests/test_dist.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import collections
21
import os
32
import re
43
import urllib.parse
@@ -72,15 +71,10 @@ def sdist_with_index(distname, version):
7271

7372

7473
def test_provides_extras_deterministic_order():
75-
extras = collections.OrderedDict()
76-
extras['a'] = ['foo']
77-
extras['b'] = ['bar']
78-
attrs = dict(extras_require=extras)
74+
attrs = dict(extras_require=dict(a=['foo'], b=['bar']))
7975
dist = Distribution(attrs)
8076
assert list(dist.metadata.provides_extras) == ['a', 'b']
81-
attrs['extras_require'] = collections.OrderedDict(
82-
reversed(list(attrs['extras_require'].items()))
83-
)
77+
attrs['extras_require'] = dict(reversed(attrs['extras_require'].items()))
8478
dist = Distribution(attrs)
8579
assert list(dist.metadata.provides_extras) == ['b', 'a']
8680

0 commit comments

Comments
 (0)