5
5
import subprocess
6
6
import sys
7
7
import tempfile
8
- from functools import partial
9
- from typing import TYPE_CHECKING
8
+
9
+ import packaging .requirements
10
+ import packaging .utils
10
11
11
12
from . import _reqs
12
- from ._reqs import _StrOrIter
13
+ from ._importlib import metadata
13
14
from .warnings import SetuptoolsDeprecationWarning
14
15
from .wheel import Wheel
15
16
16
17
from distutils import log
17
18
from distutils .errors import DistutilsError
18
19
19
- if TYPE_CHECKING :
20
- from pkg_resources import Distribution
21
-
22
20
23
21
def _fixup_find_links (find_links ):
24
22
"""Ensure find-links option end-up being a list of strings."""
@@ -37,25 +35,30 @@ def fetch_build_egg(dist, req):
37
35
return _fetch_build_egg_no_warn (dist , req )
38
36
39
37
40
- def _fetch_build_eggs (dist , requires : _StrOrIter ) -> list [Distribution ]:
41
- import pkg_resources # Delay import to avoid unnecessary side-effects
42
-
38
+ def _fetch_build_eggs (dist , requires : _reqs ._StrOrIter ) -> list [metadata .Distribution ]:
43
39
_DeprecatedInstaller .emit (stacklevel = 3 )
44
40
_warn_wheel_not_available (dist )
45
41
46
- resolved_dists = pkg_resources .working_set .resolve (
47
- _reqs .parse (requires , pkg_resources .Requirement ), # required for compatibility
48
- installer = partial (_fetch_build_egg_no_warn , dist ), # avoid warning twice
49
- replace_conflicting = True ,
42
+ needed_reqs = (
43
+ req for req in _reqs .parse (requires ) if not req .marker or req .marker .evaluate ()
50
44
)
45
+ resolved_dists = [_fetch_build_egg_no_warn (dist , req ) for req in needed_reqs ]
51
46
for dist in resolved_dists :
52
- pkg_resources .working_set .add (dist , replace = True )
47
+ # dist.locate_file('') is the directory containing EGG-INFO, where the importabl
48
+ # contents can be found.
49
+ sys .path .insert (0 , str (dist .locate_file ('' )))
53
50
return resolved_dists
54
51
55
52
56
- def _fetch_build_egg_no_warn (dist , req ): # noqa: C901 # is too complex (16) # FIXME
57
- import pkg_resources # Delay import to avoid unnecessary side-effects
53
+ def _dist_matches_req (egg_dist , req ):
54
+ return (
55
+ packaging .utils .canonicalize_name (egg_dist .name )
56
+ == packaging .utils .canonicalize_name (req .name )
57
+ and egg_dist .version in req .specifier
58
+ )
59
+
58
60
61
+ def _fetch_build_egg_no_warn (dist , req ): # noqa: C901 # is too complex (16) # FIXME
59
62
# Ignore environment markers; if supplied, it is required.
60
63
req = strip_marker (req )
61
64
# Take easy_install options into account, but do not override relevant
@@ -80,9 +83,11 @@ def _fetch_build_egg_no_warn(dist, req): # noqa: C901 # is too complex (16) #
80
83
if dist .dependency_links :
81
84
find_links .extend (dist .dependency_links )
82
85
eggs_dir = os .path .realpath (dist .get_egg_cache_dir ())
83
- environment = pkg_resources .Environment ()
84
- for egg_dist in pkg_resources .find_distributions (eggs_dir ):
85
- if egg_dist in req and environment .can_add (egg_dist ):
86
+ cached_dists = metadata .Distribution .discover (
87
+ path = glob .glob (f'{ eggs_dir } /*.egg/EGG-INFO' )
88
+ )
89
+ for egg_dist in cached_dists :
90
+ if _dist_matches_req (egg_dist , req ):
86
91
return egg_dist
87
92
with tempfile .TemporaryDirectory () as tmpdir :
88
93
cmd = [
@@ -112,12 +117,7 @@ def _fetch_build_egg_no_warn(dist, req): # noqa: C901 # is too complex (16) #
112
117
wheel = Wheel (glob .glob (os .path .join (tmpdir , '*.whl' ))[0 ])
113
118
dist_location = os .path .join (eggs_dir , wheel .egg_name ())
114
119
wheel .install_as_egg (dist_location )
115
- dist_metadata = pkg_resources .PathMetadata (
116
- dist_location , os .path .join (dist_location , 'EGG-INFO' )
117
- )
118
- return pkg_resources .Distribution .from_filename (
119
- dist_location , metadata = dist_metadata
120
- )
120
+ return metadata .Distribution .at (dist_location + '/EGG-INFO' )
121
121
122
122
123
123
def strip_marker (req ):
@@ -126,20 +126,16 @@ def strip_marker(req):
126
126
calling pip with something like `babel; extra == "i18n"`, which
127
127
would always be ignored.
128
128
"""
129
- import pkg_resources # Delay import to avoid unnecessary side-effects
130
-
131
129
# create a copy to avoid mutating the input
132
- req = pkg_resources . Requirement . parse (str (req ))
130
+ req = packaging . requirements . Requirement (str (req ))
133
131
req .marker = None
134
132
return req
135
133
136
134
137
135
def _warn_wheel_not_available (dist ):
138
- import pkg_resources # Delay import to avoid unnecessary side-effects
139
-
140
136
try :
141
- pkg_resources . get_distribution ('wheel' )
142
- except pkg_resources . DistributionNotFound :
137
+ metadata . distribution ('wheel' )
138
+ except metadata . PackageNotFoundError :
143
139
dist .announce ('WARNING: The wheel package is not available.' , log .WARN )
144
140
145
141
@@ -149,4 +145,4 @@ class _DeprecatedInstaller(SetuptoolsDeprecationWarning):
149
145
Requirements should be satisfied by a PEP 517 installer.
150
146
If you are using pip, you can try `pip install --use-pep517`.
151
147
"""
152
- # _DUE_DATE not decided yet
148
+ _DUE_DATE = 2025 , 10 , 31
0 commit comments