Install build requirements in the prepare operation

This commit is contained in:
xoviat 2018-01-26 12:11:00 -06:00
parent 958a9369f5
commit 27cb7f36cc
3 changed files with 52 additions and 27 deletions

View File

@ -65,3 +65,14 @@ class BuildEnvironment(object):
def cleanup(self):
self._temp_dir.cleanup()
class FakeBuildEnvironment(BuildEnvironment):
def __enter__(self):
pass
def __exit__(self, exc_type, exc_val, exc_tb):
pass
def cleanup(self):
pass

View File

@ -3,6 +3,10 @@
import logging
import os
import sys
import itertools
from copy import copy
from pip._vendor import pkg_resources, requests
@ -16,8 +20,12 @@ from pip._internal.exceptions import (
)
from pip._internal.utils.hashes import MissingHashes
from pip._internal.utils.logging import indent_log
from pip._internal.utils.misc import display_path, normalize_path
from pip._internal.utils.misc import display_path, normalize_path, call_subprocess
from pip._internal.utils.ui import open_spinner
from pip._internal.vcs import vcs
from pip._internal.req.req_install import InstallRequirement
from pip._internal.index import FormatControl
from pip._internal.build_env import FakeBuildEnvironment
logger = logging.getLogger(__name__)
@ -38,6 +46,19 @@ def make_abstract_dist(req):
return IsSDist(req)
def _install_build_reqs(finder, prefix, build_requirements):
finder = copy(finder)
finder.format_control = FormatControl(set(), set([":all:"]))
urls = [finder.find_requirement(InstallRequirement.from_line(r),
upgrade=False).url
for r in build_requirements]
args = [sys.executable, '-m', 'pip', 'install', '--ignore-installed',
'--prefix', prefix] + list(urls)
with open_spinner("Installing build dependencies") as spinner:
call_subprocess(args, show_stdout=False, spinner=spinner)
class DistAbstraction(object):
"""Abstracts out the wheel vs non-wheel Resolver.resolve() logic.
@ -92,8 +113,25 @@ class IsSDist(DistAbstraction):
return dist
def prep_for_dist(self, finder):
self.req.run_egg_info()
self.req.assert_source_matches_version()
build_requirements, isolate = self.req.get_pep_518_info()
if 'setuptools' not in build_requirements:
logger.warning(
"This version of pip does not implement PEP 516, so "
"it cannot build a wheel without setuptools. You may need to "
"upgrade to a newer version of pip.")
if not isolate:
self.req.build_environment = FakeBuildEnvironment(no_clean=False)
with self.req.build_environment as prefix:
# Ignore the --no-binary option when installing the build system, so
# we don't recurse trying to build a self-hosting build system.
if isolate:
_install_build_reqs(finder, prefix, build_requirements)
self.req.run_egg_info()
self.req.assert_source_matches_version()
class Installed(DistAbstraction):

View File

@ -617,36 +617,12 @@ class WheelBuilder(object):
self.global_options = global_options or []
self.no_clean = no_clean
def _install_build_reqs(self, reqs, prefix):
# Local import to avoid circular import (wheel <-> req_install)
from pip._internal.req.req_install import InstallRequirement
from pip._internal.index import FormatControl
# Ignore the --no-binary option when installing the build system, so
# we don't recurse trying to build a self-hosting build system.
finder = copy.copy(self.finder)
finder.format_control = FormatControl(set(), set([":all:"]))
urls = [finder.find_requirement(InstallRequirement.from_line(r),
upgrade=False).url
for r in reqs]
args = [sys.executable, '-m', 'pip', 'install', '--ignore-installed',
'--prefix', prefix] + list(urls)
with open_spinner("Installing build dependencies") as spinner:
call_subprocess(args, show_stdout=False, spinner=spinner)
def _build_one(self, req, output_dir, python_tag=None):
"""Build one wheel.
:return: The filename of the built wheel, or None if the build failed.
"""
build_reqs, isolate = req.get_pep_518_info()
if 'setuptools' not in build_reqs:
logger.warning(
"This version of pip does not implement PEP 516, so "
"it cannot build a wheel without setuptools. You may need to "
"upgrade to a newer version of pip.")
# Install build deps into temporary directory (PEP 518)
self._install_build_reqs(build_reqs, prefix)
with req.build_environment as prefix:
return self._build_one_inside_env(req, output_dir,
python_tag=python_tag,