From 87b54759c2fc151bbc55102d430b7a93b7c73f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Thu, 21 May 2020 16:15:08 +0200 Subject: [PATCH] Pass scheme to build_wheel_for_editable --- src/pip/_internal/commands/install.py | 15 ++++++++++++++- src/pip/_internal/commands/wheel.py | 1 + src/pip/_internal/locations.py | 4 +++- src/pip/_internal/models/scheme.py | 14 ++++++++++++++ src/pip/_internal/operations/build/wheel.py | 3 +++ src/pip/_internal/wheel_builder.py | 13 ++++++++++++- src/pip/_vendor/pep517/_in_process.py | 6 ++++-- src/pip/_vendor/pep517/wrappers.py | 6 +++++- 8 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/pip/_internal/commands/install.py b/src/pip/_internal/commands/install.py index e4787ad6682..ee059cd4af6 100644 --- a/src/pip/_internal/commands/install.py +++ b/src/pip/_internal/commands/install.py @@ -24,7 +24,7 @@ from pip._internal.cli.req_command import RequirementCommand, with_cleanup from pip._internal.cli.status_codes import ERROR, SUCCESS from pip._internal.exceptions import CommandError, InstallationError -from pip._internal.locations import distutils_scheme +from pip._internal.locations import distutils_scheme, get_scheme from pip._internal.operations.check import check_install_conflicts from pip._internal.req import install_given_reqs from pip._internal.req.req_tracker import get_requirement_tracker @@ -46,6 +46,7 @@ from optparse import Values from typing import Any, Iterable, List, Optional + from pip._internal.locations import Scheme from pip._internal.models.format_control import FormatControl from pip._internal.req.req_install import InstallRequirement from pip._internal.wheel_builder import BinaryAllowedPredicate @@ -353,12 +354,24 @@ def run(self, options, args): ) ] + def get_scheme_for_req(name): + # type: (str) -> Scheme + return get_scheme( + name, + user=options.use_user_site, + home=target_temp_dir_path, + root=options.root_path, + isolated=options.isolated_mode, + prefix=options.prefix_path, + ) + _, build_failures = build( reqs_to_build, wheel_cache=wheel_cache, build_options=[], global_options=[], allow_editable=True, + get_scheme_for_editable_req=get_scheme_for_req, ) # If we're using PEP 517, we cannot do a direct install diff --git a/src/pip/_internal/commands/wheel.py b/src/pip/_internal/commands/wheel.py index cbd5ca341b4..98dcf5ae464 100644 --- a/src/pip/_internal/commands/wheel.py +++ b/src/pip/_internal/commands/wheel.py @@ -171,6 +171,7 @@ def run(self, options, args): build_options=options.build_options or [], global_options=options.global_options or [], allow_editable=False, + get_scheme_for_editable_req=None, ) for req in build_successes: assert req.link and req.link.is_wheel diff --git a/src/pip/_internal/locations.py b/src/pip/_internal/locations.py index 0c115531911..05bd6ff590c 100644 --- a/src/pip/_internal/locations.py +++ b/src/pip/_internal/locations.py @@ -22,10 +22,12 @@ from pip._internal.utils.virtualenv import running_under_virtualenv if MYPY_CHECK_RUNNING: - from typing import Dict, List, Optional, Union + from typing import Callable, Dict, List, Optional, Union from distutils.cmd import Command as DistutilsCommand + GetSchemePredicate = Callable[[str], Scheme] + # Application Directories USER_CACHE_DIR = appdirs.user_cache_dir("pip") diff --git a/src/pip/_internal/models/scheme.py b/src/pip/_internal/models/scheme.py index af07b4078f9..de8096d7cd1 100644 --- a/src/pip/_internal/models/scheme.py +++ b/src/pip/_internal/models/scheme.py @@ -4,6 +4,10 @@ For a general overview of available schemes and their context, see https://docs.python.org/3/install/index.html#alternate-installation. """ +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Dict class Scheme(object): @@ -23,3 +27,13 @@ def __init__( self.headers = headers self.scripts = scripts self.data = data + + def as_dict(self): + # type: () -> Dict[str, str] + return dict( + platlib=self.platlib, + purelib=self.purelib, + headers=self.headers, + scripts=self.scripts, + data=self.data, + ) diff --git a/src/pip/_internal/operations/build/wheel.py b/src/pip/_internal/operations/build/wheel.py index 8cca67c44af..4c4a3a573d8 100644 --- a/src/pip/_internal/operations/build/wheel.py +++ b/src/pip/_internal/operations/build/wheel.py @@ -8,6 +8,7 @@ if MYPY_CHECK_RUNNING: from typing import List, Optional + from pip._internal.locations import Scheme from pip._vendor.pep517.wrappers import Pep517HookCaller logger = logging.getLogger(__name__) @@ -20,6 +21,7 @@ def build_wheel_pep517( build_options, # type: List[str] tempd, # type: str editable, # type: bool + scheme, # type: Scheme ): # type: (...) -> Optional[str] """Build one InstallRequirement using the PEP 517 build process. @@ -43,6 +45,7 @@ def build_wheel_pep517( try: wheel_name = backend.build_wheel_for_editable( tempd, + scheme=scheme.as_dict(), metadata_directory=metadata_directory, ) except HookMissing: diff --git a/src/pip/_internal/wheel_builder.py b/src/pip/_internal/wheel_builder.py index 69f36a3fcd4..63992daed77 100644 --- a/src/pip/_internal/wheel_builder.py +++ b/src/pip/_internal/wheel_builder.py @@ -27,6 +27,7 @@ ) from pip._internal.cache import WheelCache + from pip._internal.locations import GetSchemePredicate, Scheme from pip._internal.req.req_install import InstallRequirement BinaryAllowedPredicate = Callable[[InstallRequirement], bool] @@ -173,6 +174,7 @@ def _build_one( build_options, # type: List[str] global_options, # type: List[str] editable, # type: bool + scheme, # type: Scheme ): # type: (...) -> Optional[str] """Build one wheel. @@ -191,7 +193,7 @@ def _build_one( # Install build deps into temporary directory (PEP 518) with req.build_env: return _build_one_inside_env( - req, output_dir, build_options, global_options, editable + req, output_dir, build_options, global_options, editable, scheme ) @@ -201,6 +203,7 @@ def _build_one_inside_env( build_options, # type: List[str] global_options, # type: List[str] editable, # type: bool + scheme, # type: Scheme ): # type: (...) -> Optional[str] with TempDirectory(kind="wheel") as temp_dir: @@ -212,6 +215,7 @@ def _build_one_inside_env( build_options=build_options, tempd=temp_dir.path, editable=editable, + scheme=scheme, ) else: wheel_path = build_wheel_legacy( @@ -268,6 +272,7 @@ def build( build_options, # type: List[str] global_options, # type: List[str] allow_editable, # type: bool + get_scheme_for_editable_req, # type: Optional[GetSchemePredicate] ): # type: (...) -> BuildResult """Build wheels. @@ -275,6 +280,8 @@ def build( :return: The list of InstallRequirement that succeeded to build and the list of InstallRequirement that failed to build. """ + assert allow_editable == bool(get_scheme_for_editable_req) + if not requirements: return [], [] @@ -288,11 +295,15 @@ def build( build_successes, build_failures = [], [] for req in requirements: cache_dir = _get_cache_dir(req, wheel_cache) + scheme = None + if get_scheme_for_editable_req: + scheme = get_scheme_for_editable_req(req.name) wheel_file = _build_one( req, cache_dir, build_options, global_options, allow_editable and req.editable, + scheme=scheme, ) if wheel_file: # Update the link for this. diff --git a/src/pip/_vendor/pep517/_in_process.py b/src/pip/_vendor/pep517/_in_process.py index 1822f034499..7652133803b 100644 --- a/src/pip/_vendor/pep517/_in_process.py +++ b/src/pip/_vendor/pep517/_in_process.py @@ -206,7 +206,7 @@ def build_wheel(wheel_directory, config_settings, metadata_directory=None): def build_wheel_for_editable( - wheel_directory, config_settings, metadata_directory=None + wheel_directory, scheme, config_settings, metadata_directory=None ): """Invoke the optional build_wheel_for_editable hook. """ @@ -216,7 +216,9 @@ def build_wheel_for_editable( except AttributeError: raise HookMissing() else: - return hook(wheel_directory, config_settings, metadata_directory) + return hook( + wheel_directory, scheme, config_settings, metadata_directory + ) def get_requires_for_build_sdist(config_settings): diff --git a/src/pip/_vendor/pep517/wrappers.py b/src/pip/_vendor/pep517/wrappers.py index 315bba19a6d..8fe09425c10 100644 --- a/src/pip/_vendor/pep517/wrappers.py +++ b/src/pip/_vendor/pep517/wrappers.py @@ -200,16 +200,20 @@ def build_wheel( }) def build_wheel_for_editable( - self, wheel_directory, config_settings=None, + self, wheel_directory, scheme, config_settings=None, metadata_directory=None): """Build a wheel for editable install from this project. Returns the name of the newly created file. + + 'scheme' is a dictionary with the following keys: + 'purelib', 'platlib', 'headers', 'scripts', 'data'. """ if metadata_directory is not None: metadata_directory = abspath(metadata_directory) return self._call_hook('build_wheel_for_editable', { 'wheel_directory': abspath(wheel_directory), + 'scheme': scheme, 'config_settings': config_settings, 'metadata_directory': metadata_directory, })