Repository: pypa/pip

Issue:
pip 19.1 and develop mode (with pyproject.toml - build-backend present)
So I get now pip is PEP compliant, and the reasons why it was done.

However, this now breaks peoples workflow without any sane workaround (the only one to work is to remove pyproject.toml file before install and put it back afterwards), I consider it as a PEP oversight to not specify that it does not apply for editable installs.

PEP-517/8 on purpose did not want to cover editable installs, considering something to be addressed down the line (there's some discussion on the topic upstream, but that's ages away from reality). As such I would argue PEP-517/PEP-518 no longer applies when editable install mode is enabled. It's the build frontend dependent on how this case is handled. 

We have two options now:
- In develop mode, pip should fallback to the old system, maintain the status quo until we figure out how to support editable installs in the new world. 
- Alternatively, provide a flag that triggers the old build system independent of the presence/content of the ``pyproject.toml``. 

Note this now breaks *a lot* of dependent systems (pipenv, tox, poetry, etc).

Discussion:

Patch:
diff --git a/news/6434.feature b/news/6434.feature
new file mode 100644
index 000000000..958d75165
--- /dev/null
+++ b/news/6434.feature
@@ -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.
diff --git a/src/pip/_internal/pyproject.py b/src/pip/_internal/pyproject.py
index 13a8f35a9..2e76c399a 100644
--- a/src/pip/_internal/pyproject.py
+++ b/src/pip/_internal/pyproject.py
@@ -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


Test patch:
diff --git a/tests/unit/test_pep517.py b/tests/unit/test_pep517.py
index d539d7b20..83787d56c 100644
--- a/tests/unit/test_pep517.py
+++ b/tests/unit/test_pep517.py
@@ -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', [