Skip to content

Commit

Permalink
Merge pull request #6442 from cjerdonek/issue-6434-pyproject-editable
Browse files Browse the repository at this point in the history
Permit --no-use-pep517 with editable mode in more cases.
  • Loading branch information
pfmoore authored Apr 25, 2019
2 parents 9816d17 + f069769 commit 9861dc7
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 17 deletions.
7 changes: 7 additions & 0 deletions news/6434.feature
Original file line number Diff line number Diff line change
@@ -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.
55 changes: 41 additions & 14 deletions src/pip/_internal/pyproject.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import absolute_import

import io
import logging
import os
import sys

Expand All @@ -15,6 +16,9 @@
Pep517Data = Tuple[str, List[str]]


logger = logging.getLogger(__name__)


def _is_list_of_str(obj):
# type: (Any) -> bool
return (
Expand Down Expand Up @@ -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: "
Expand All @@ -145,26 +153,45 @@ 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 {} "
"in pyproject.toml".format(
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
Expand Down
52 changes: 49 additions & 3 deletions tests/unit/test_pep517.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Expand Down Expand Up @@ -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', [
Expand Down

0 comments on commit 9861dc7

Please sign in to comment.