mirror of https://github.com/pypa/pip
Fix #6163: Default to setuptools.build_meta:__legacy__
The main setuptools PEP 517 backend is intended for explicit usage in `pyproject.toml`, when the project authors can ensure that their `setup.py` runs without that directory being implicitly on `sys.path`. For implicit usage, setuptools now offers a separate legacy backend that more closely mimics direct execution of the `setup.py` script.
This commit is contained in:
parent
5a61475f95
commit
682cff7230
|
@ -27,6 +27,7 @@ nosetests.xml
|
|||
coverage.xml
|
||||
*.cover
|
||||
tests/data/common_wheels/
|
||||
pip-wheel-metadata
|
||||
|
||||
# Misc
|
||||
*~
|
||||
|
|
|
@ -145,26 +145,28 @@ explicitly manage the build environment. For such workflows, build isolation
|
|||
can be problematic. If this is the case, pip provides a
|
||||
``--no-build-isolation`` flag to disable build isolation. Users supplying this
|
||||
flag are responsible for ensuring the build environment is managed
|
||||
appropriately.
|
||||
appropriately (including ensuring that all required build dependencies are
|
||||
installed).
|
||||
|
||||
By default, pip will continue to use the legacy (``setuptools`` based) build
|
||||
processing for projects that do not have a ``pyproject.toml`` file. Projects
|
||||
with a ``pyproject.toml`` file will use a :pep:`517` backend. Projects with
|
||||
a ``pyproject.toml`` file, but which don't have a ``build-system`` section,
|
||||
By default, pip will continue to use the legacy (direct ``setup.py`` execution
|
||||
based) build processing for projects that do not have a ``pyproject.toml`` file.
|
||||
Projects with a ``pyproject.toml`` file will use a :pep:`517` backend. Projects
|
||||
with a ``pyproject.toml`` file, but which don't have a ``build-system`` section,
|
||||
will be assumed to have the following backend settings::
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools>=40.2.0", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
requires = ["setuptools>=40.8.0", "wheel"]
|
||||
build-backend = "setuptools.build_meta:__legacy__"
|
||||
|
||||
.. note::
|
||||
|
||||
``setuptools`` 40.2.0 is the first version of setuptools with full
|
||||
:pep:`517` support.
|
||||
|
||||
If a project has ``[build-system]``, but no ``build-backend``, pip will use
|
||||
``setuptools.build_meta``, but will assume the project requirements include
|
||||
``setuptools>=40.2.0`` and ``wheel`` (and will report an error if not).
|
||||
``setuptools`` 40.8.0 is the first version of setuptools that offers a
|
||||
:pep:`517` backend that closely mimics directly executing ``setup.py``.
|
||||
|
||||
If a project has ``[build-system]``, but no ``build-backend``, pip will also use
|
||||
``setuptools.build_meta:__legacy__``, but will expect the project requirements
|
||||
to include ``setuptools`` and ``wheel`` (and will report an error if the
|
||||
installed version of ``setuptools`` is not recent enough).
|
||||
|
||||
If a user wants to explicitly request :pep:`517` handling even though a project
|
||||
doesn't have a ``pyproject.toml`` file, this can be done using the
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
The implicit default backend used for projects that provide a ``pyproject.toml``
|
||||
file without explicitly specifying ``build-backend`` now behaves more like direct
|
||||
execution of ``setup.py``, and hence should restore compatibility with projects
|
||||
that were unable to be installed with ``pip`` 19.0. This raised the minimum
|
||||
required version of ``setuptools`` for such builds to 40.8.0.
|
|
@ -111,11 +111,13 @@ def load_pyproject_toml(
|
|||
# section, or the user has no pyproject.toml, but has opted in
|
||||
# explicitly via --use-pep517.
|
||||
# In the absence of any explicit backend specification, we
|
||||
# assume the setuptools backend, and require wheel and a version
|
||||
# of setuptools that supports that backend.
|
||||
# assume the setuptools backend that most closely emulates the
|
||||
# traditional direct setup.py execution, and require wheel and
|
||||
# a version of setuptools that supports that backend.
|
||||
|
||||
build_system = {
|
||||
"requires": ["setuptools>=40.2.0", "wheel"],
|
||||
"build-backend": "setuptools.build_meta",
|
||||
"requires": ["setuptools>=40.8.0", "wheel"],
|
||||
"build-backend": "setuptools.build_meta:__legacy__",
|
||||
}
|
||||
|
||||
# If we're using PEP 517, we have build system information (either
|
||||
|
@ -154,7 +156,7 @@ def load_pyproject_toml(
|
|||
# If the user didn't specify a backend, we assume they want to use
|
||||
# the setuptools backend. But we can't be sure they have included
|
||||
# a version of setuptools which supplies the backend, or wheel
|
||||
# (which is neede by the backend) in their requirements. So we
|
||||
# (which is needed by the backend) in their requirements. So we
|
||||
# make a note to check that those requirements are present once
|
||||
# we have set up the environment.
|
||||
# This is quite a lot of work to check for a very specific case. But
|
||||
|
@ -163,7 +165,7 @@ def load_pyproject_toml(
|
|||
# execute setup.py, but never considered needing to mention the build
|
||||
# tools themselves. The original PEP 518 code had a similar check (but
|
||||
# implemented in a different way).
|
||||
backend = "setuptools.build_meta"
|
||||
check = ["setuptools>=40.2.0", "wheel"]
|
||||
backend = "setuptools.build_meta:__legacy__"
|
||||
check = ["setuptools>=40.8.0", "wheel"]
|
||||
|
||||
return (requires, backend, check)
|
||||
|
|
|
@ -62,7 +62,7 @@ def test_pep518_refuses_conflicting_requires(script, data):
|
|||
result.returncode != 0 and
|
||||
('Some build dependencies for %s conflict with PEP 517/518 supported '
|
||||
'requirements: setuptools==1.0 is incompatible with '
|
||||
'setuptools>=40.2.0.' % path_to_url(project_dir)) in result.stderr
|
||||
'setuptools>=40.8.0.' % path_to_url(project_dir)) in result.stderr
|
||||
), str(result)
|
||||
|
||||
|
||||
|
|
|
@ -123,3 +123,78 @@ def test_pep517_install_with_no_cache_dir(script, tmpdir, data):
|
|||
project_dir,
|
||||
)
|
||||
result.assert_installed('project', editable=False)
|
||||
|
||||
|
||||
def make_pyproject_with_setup(tmpdir, build_system=True, set_backend=True):
|
||||
project_dir = (tmpdir / 'project').mkdir()
|
||||
setup_script = (
|
||||
'from setuptools import setup\n'
|
||||
)
|
||||
expect_script_dir_on_path = True
|
||||
if build_system:
|
||||
buildsys = {
|
||||
'requires': ['setuptools', 'wheel'],
|
||||
}
|
||||
if set_backend:
|
||||
buildsys['build-backend'] = 'setuptools.build_meta'
|
||||
expect_script_dir_on_path = False
|
||||
project_data = pytoml.dumps({'build-system': buildsys})
|
||||
else:
|
||||
project_data = ''
|
||||
|
||||
if expect_script_dir_on_path:
|
||||
setup_script += (
|
||||
'from pep517_test import __version__\n'
|
||||
)
|
||||
else:
|
||||
setup_script += (
|
||||
'try:\n'
|
||||
' import pep517_test\n'
|
||||
'except ImportError:\n'
|
||||
' pass\n'
|
||||
'else:\n'
|
||||
' raise RuntimeError("Source dir incorrectly on sys.path")\n'
|
||||
)
|
||||
|
||||
setup_script += (
|
||||
'setup(name="pep517_test", version="0.1", packages=["pep517_test"])'
|
||||
)
|
||||
|
||||
project_dir.join('pyproject.toml').write(project_data)
|
||||
project_dir.join('setup.py').write(setup_script)
|
||||
package_dir = (project_dir / "pep517_test").mkdir()
|
||||
package_dir.join('__init__.py').write('__version__ = "0.1"')
|
||||
return project_dir, "pep517_test"
|
||||
|
||||
|
||||
def test_no_build_system_section(script, tmpdir, data, common_wheels):
|
||||
"""Check builds with setup.py, pyproject.toml, but no build-system section.
|
||||
"""
|
||||
project_dir, name = make_pyproject_with_setup(tmpdir, build_system=False)
|
||||
result = script.pip(
|
||||
'install', '--no-cache-dir', '--no-index', '-f', common_wheels,
|
||||
project_dir,
|
||||
)
|
||||
result.assert_installed(name, editable=False)
|
||||
|
||||
|
||||
def test_no_build_backend_entry(script, tmpdir, data, common_wheels):
|
||||
"""Check builds with setup.py, pyproject.toml, but no build-backend entry.
|
||||
"""
|
||||
project_dir, name = make_pyproject_with_setup(tmpdir, set_backend=False)
|
||||
result = script.pip(
|
||||
'install', '--no-cache-dir', '--no-index', '-f', common_wheels,
|
||||
project_dir,
|
||||
)
|
||||
result.assert_installed(name, editable=False)
|
||||
|
||||
|
||||
def test_explicit_setuptools_backend(script, tmpdir, data, common_wheels):
|
||||
"""Check builds with setup.py, pyproject.toml, and a build-backend entry.
|
||||
"""
|
||||
project_dir, name = make_pyproject_with_setup(tmpdir)
|
||||
result = script.pip(
|
||||
'install', '--no-cache-dir', '--no-index', '-f', common_wheels,
|
||||
project_dir,
|
||||
)
|
||||
result.assert_installed(name, editable=False)
|
||||
|
|
|
@ -1,2 +1,9 @@
|
|||
setuptools
|
||||
# Create local setuptools wheel files for testing by:
|
||||
# 1. Cloning setuptools and checking out the branch of interest
|
||||
# 2. Running `python3 bootstrap.py` in that directory
|
||||
# 3. Running `python3 -m pip wheel --no-cache -w /tmp/setuptools_build_meta_legacy/ .`
|
||||
# 4. Replacing the `setuptools` entry below with a `file:///...` URL
|
||||
# (Adjust artifact directory used based on preference and operating system)
|
||||
|
||||
setuptools >= 40.8.0
|
||||
wheel
|
||||
|
|
Loading…
Reference in New Issue