Allow --no-use-pep517 to be used with editable mode in more cases.

This commit is contained in:
Chris Jerdonek 2019-04-24 21:43:19 -07:00
parent 9816d17cca
commit f069769948
3 changed files with 97 additions and 17 deletions

7
news/6434.feature Normal file
View File

@ -0,0 +1,7 @@
Allow ``--no-use-pep517`` to be used as a work-around when installing a
project in editable mode, even when `PEP 517
<https://www.python.org/dev/peps/pep-0517/>`_ mandates
``pyproject.toml``-style processing (i.e. when the project has a
``pyproject.toml`` file as well as a ``"build-backend"`` key for the
``"build_system"`` value). Since this option conflicts with the PEP 517 spec,
this mode of operation is officially unsupported.

View File

@ -1,6 +1,7 @@
from __future__ import absolute_import
import io
import logging
import os
import sys
@ -15,6 +16,9 @@ if MYPY_CHECK_RUNNING:
Pep517Data = Tuple[str, List[str]]
logger = logging.getLogger(__name__)
def _is_list_of_str(obj):
# type: (Any) -> bool
return (
@ -133,7 +137,11 @@ def resolve_pyproject_toml(
# opposed to False can occur when the value is provided via an
# environment variable or config file option (due to the quirk of
# strtobool() returning an integer in pip's configuration code).
if has_pyproject and not has_setup:
if editable and use_pep517:
raise make_editable_error(
req_name, 'PEP 517 processing was explicitly requested'
)
elif has_pyproject and not has_setup:
if use_pep517 is not None and not use_pep517:
raise InstallationError(
"Disabling PEP 517 processing is invalid: "
@ -145,7 +153,36 @@ def resolve_pyproject_toml(
)
use_pep517 = True
elif build_system and "build-backend" in build_system:
if use_pep517 is not None and not use_pep517:
if editable:
if use_pep517 is None:
message = (
'Error installing {!r}: editable mode is not supported '
'for pyproject.toml-style projects. '
'This project is pyproject.toml-style because it has a '
'pyproject.toml file and a "build-backend" key for the '
'"build_system" value, but editable mode is undefined '
'for pyproject.toml-style projects. '
'Since the project has a setup.py, you may pass '
'--no-use-pep517 to opt out of pyproject.toml-style '
'processing. However, this is an unsupported combination. '
'See PEP 517 for details on pyproject.toml-style projects.'
).format(req_name)
raise InstallationError(message)
# The case of `editable and use_pep517` being true was already
# handled above.
assert not use_pep517
message = (
'Installing {!r} in editable mode, which is not supported '
'for pyproject.toml-style projects: '
'this project is pyproject.toml-style because it has a '
'pyproject.toml file and a "build-backend" key for the '
'"build_system" value, but editable mode is undefined '
'for pyproject.toml-style projects. '
'See PEP 517 for details on pyproject.toml-style projects.'
).format(req_name)
logger.warning(message)
elif use_pep517 is not None and not use_pep517:
raise InstallationError(
"Disabling PEP 517 processing is invalid: "
"project specifies a build backend of {} "
@ -153,18 +190,8 @@ def resolve_pyproject_toml(
build_system["build-backend"]
)
)
if editable:
reason = (
'it has a pyproject.toml file with a "build-backend" key '
'in the "build_system" value'
)
raise make_editable_error(req_name, reason)
use_pep517 = True
elif use_pep517:
if editable:
raise make_editable_error(
req_name, 'PEP 517 processing was explicitly requested'
)
else:
use_pep517 = True
# If we haven't worked out whether to use PEP 517 yet, and the user
# hasn't explicitly stated a preference, we do so if the project has

View File

@ -84,9 +84,6 @@ def test_resolve_pyproject_toml__editable_without_use_pep517_false():
'has_pyproject, has_setup, use_pep517, build_system, expected_err', [
# Test pyproject.toml with no setup.py.
(True, False, None, None, 'has a pyproject.toml file and no setup.py'),
# Test "build-backend" present.
(True, True, None, {'build-backend': 'foo'},
'has a pyproject.toml file with a "build-backend" key'),
# Test explicitly requesting PEP 517 processing.
(True, True, True, None,
'PEP 517 processing was explicitly requested'),
@ -115,6 +112,55 @@ def test_resolve_pyproject_toml__editable_and_pep_517_required(
)
def test_resolve_pyproject_toml__editable_build_backend_use_pep517_none():
"""
Test editable=True with "build-backend" and use_pep517=None.
"""
expected_start = (
"Error installing 'my-package': editable mode is not supported "
)
expected_substr = 'you may pass --no-use-pep517 to opt out'
with assert_error_startswith(
InstallationError, expected_start, expected_substr=expected_substr,
):
resolve_pyproject_toml(
build_system={'requires': ['my-package'], 'build-backend': 'foo'},
has_pyproject=True,
has_setup=True,
use_pep517=None,
editable=True,
req_name='my-package',
)
def test_resolve_pyproject_toml__editable_build_backend_use_pep517_false(
caplog
):
"""
Test editable=True with "build-backend" and use_pep517=False.
"""
resolve_pyproject_toml(
build_system={'requires': ['my-package'], 'build-backend': 'foo'},
has_pyproject=True,
has_setup=True,
use_pep517=False,
editable=True,
req_name='my-package',
)
records = caplog.records
assert len(records) == 1
record = records[0]
assert record.levelname == 'WARNING'
expected_start = (
"Installing 'my-package' in editable mode, which is not supported "
)
assert record.message.startswith(expected_start), (
'full message: {}'.format(record.message)
)
@pytest.mark.parametrize(
'has_pyproject, has_setup, use_pep517, editable, build_system, '
'expected_err', [