7 from distutils
import log
8 from distutils
.errors
import DistutilsError
11 from setuptools
.wheel
import Wheel
12 from ._deprecation
_warning
import SetuptoolsDeprecationWarning
15 def _fixup_find_links(find_links
):
16 """Ensure find-links option end-up being a list of strings."""
17 if isinstance(find_links
, str):
18 return find_links
.split()
19 assert isinstance(find_links
, (tuple, list))
23 def fetch_build_egg(dist
, req
): # noqa: C901 # is too complex (16) # FIXME
24 """Fetch an egg needed for building.
26 Use pip/wheel to fetch/build a wheel."""
28 "setuptools.installer is deprecated. Requirements should "
29 "be satisfied by a PEP 517 installer.",
30 SetuptoolsDeprecationWarning
,
32 # Warn if wheel is not available
34 pkg_resources
.get_distribution('wheel')
35 except pkg_resources
.DistributionNotFound
:
36 dist
.announce('WARNING: The wheel package is not available.', log
.WARN
)
37 # Ignore environment markers; if supplied, it is required.
38 req
= strip_marker(req
)
39 # Take easy_install options into account, but do not override relevant
40 # pip environment variables (like PIP_INDEX_URL or PIP_QUIET); they'll
42 opts
= dist
.get_option_dict('easy_install')
43 if 'allow_hosts' in opts
:
44 raise DistutilsError('the `allow-hosts` option is not supported '
45 'when using pip to install requirements.')
46 quiet
= 'PIP_QUIET' not in os
.environ
and 'PIP_VERBOSE' not in os
.environ
47 if 'PIP_INDEX_URL' in os
.environ
:
49 elif 'index_url' in opts
:
50 index_url
= opts
['index_url'][1]
54 _fixup_find_links(opts
['find_links'][1])[:] if 'find_links' in opts
57 if dist
.dependency_links
:
58 find_links
.extend(dist
.dependency_links
)
59 eggs_dir
= os
.path
.realpath(dist
.get_egg_cache_dir())
60 environment
= pkg_resources
.Environment()
61 for egg_dist
in pkg_resources
.find_distributions(eggs_dir
):
62 if egg_dist
in req
and environment
.can_add(egg_dist
):
64 with tempfile
.TemporaryDirectory() as tmpdir
:
66 sys
.executable
, '-m', 'pip',
67 '--disable-pip-version-check',
73 if index_url
is not None:
74 cmd
.extend(('--index-url', index_url
))
75 for link
in find_links
or []:
76 cmd
.extend(('--find-links', link
))
77 # If requirement is a PEP 508 direct URL, directly pass
78 # the URL to pip, as `req @ url` does not work on the
80 cmd
.append(req
.url
or str(req
))
82 subprocess
.check_call(cmd
)
83 except subprocess
.CalledProcessError
as e
:
84 raise DistutilsError(str(e
)) from e
85 wheel
= Wheel(glob
.glob(os
.path
.join(tmpdir
, '*.whl'))[0])
86 dist_location
= os
.path
.join(eggs_dir
, wheel
.egg_name())
87 wheel
.install_as_egg(dist_location
)
88 dist_metadata
= pkg_resources
.PathMetadata(
89 dist_location
, os
.path
.join(dist_location
, 'EGG-INFO'))
90 dist
= pkg_resources
.Distribution
.from_filename(
91 dist_location
, metadata
=dist_metadata
)
95 def strip_marker(req
):
97 Return a new requirement without the environment marker to avoid
98 calling pip with something like `babel; extra == "i18n"`, which
99 would always be ignored.
101 # create a copy to avoid mutating the input
102 req
= pkg_resources
.Requirement
.parse(str(req
))