2019-07-29 10:57:46 +02:00
|
|
|
import pytest
|
2020-04-14 09:33:37 +02:00
|
|
|
from pip._vendor import toml
|
2018-08-01 17:45:08 +02:00
|
|
|
|
2018-08-01 16:51:17 +02:00
|
|
|
from pip._internal.build_env import BuildEnvironment
|
|
|
|
from pip._internal.req import InstallRequirement
|
2020-01-29 14:47:52 +01:00
|
|
|
from tests.lib import make_test_finder, path_to_url, windows_workaround_7667
|
2018-08-01 16:51:17 +02:00
|
|
|
|
|
|
|
|
2020-06-04 23:11:08 +02:00
|
|
|
def make_project(tmpdir, requires=None, backend=None, backend_path=None):
|
|
|
|
requires = requires or []
|
2019-08-17 03:34:17 +02:00
|
|
|
project_dir = tmpdir / 'project'
|
|
|
|
project_dir.mkdir()
|
2018-08-01 16:51:17 +02:00
|
|
|
buildsys = {'requires': requires}
|
|
|
|
if backend:
|
|
|
|
buildsys['build-backend'] = backend
|
2019-11-23 15:38:27 +01:00
|
|
|
if backend_path:
|
|
|
|
buildsys['backend-path'] = backend_path
|
2020-04-14 09:33:37 +02:00
|
|
|
data = toml.dumps({'build-system': buildsys})
|
2019-07-02 07:00:32 +02:00
|
|
|
project_dir.joinpath('pyproject.toml').write_text(data)
|
2018-10-10 12:25:26 +02:00
|
|
|
return project_dir
|
2018-08-01 16:51:17 +02:00
|
|
|
|
|
|
|
|
|
|
|
def test_backend(tmpdir, data):
|
2018-10-10 12:25:26 +02:00
|
|
|
"""Check we can call a requirement's backend successfully"""
|
|
|
|
project_dir = make_project(tmpdir, backend="dummy_backend")
|
2020-04-11 18:04:26 +02:00
|
|
|
req = InstallRequirement(None, None)
|
|
|
|
req.source_dir = project_dir # make req believe it has been unpacked
|
2018-08-02 20:48:56 +02:00
|
|
|
req.load_pyproject_toml()
|
2018-08-01 16:51:17 +02:00
|
|
|
env = BuildEnvironment()
|
2019-06-01 18:45:53 +02:00
|
|
|
finder = make_test_finder(find_links=[data.backends])
|
2018-10-25 17:35:25 +02:00
|
|
|
env.install_requirements(finder, ["dummy_backend"], 'normal', "Installing")
|
|
|
|
conflicting, missing = env.check_requirements(["dummy_backend"])
|
|
|
|
assert not conflicting and not missing
|
2018-08-01 16:51:17 +02:00
|
|
|
assert hasattr(req.pep517_backend, 'build_wheel')
|
|
|
|
with env:
|
|
|
|
assert req.pep517_backend.build_wheel("dir") == "Backend called"
|
2019-11-23 15:38:27 +01:00
|
|
|
|
|
|
|
|
|
|
|
dummy_backend_code = """\
|
|
|
|
def build_wheel(
|
|
|
|
wheel_directory,
|
|
|
|
config_settings=None,
|
|
|
|
metadata_directory=None
|
|
|
|
):
|
|
|
|
return "Backend called"
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
def test_backend_path(tmpdir, data):
|
|
|
|
"""Check we can call a backend inside the project"""
|
|
|
|
project_dir = make_project(
|
|
|
|
tmpdir, backend="dummy_backend", backend_path=['.']
|
|
|
|
)
|
|
|
|
(project_dir / 'dummy_backend.py').write_text(dummy_backend_code)
|
2020-04-11 18:04:26 +02:00
|
|
|
req = InstallRequirement(None, None)
|
|
|
|
req.source_dir = project_dir # make req believe it has been unpacked
|
2019-11-23 15:38:27 +01:00
|
|
|
req.load_pyproject_toml()
|
|
|
|
|
|
|
|
env = BuildEnvironment()
|
|
|
|
assert hasattr(req.pep517_backend, 'build_wheel')
|
|
|
|
with env:
|
|
|
|
assert req.pep517_backend.build_wheel("dir") == "Backend called"
|
2019-11-23 17:57:24 +01:00
|
|
|
|
|
|
|
|
|
|
|
def test_backend_path_and_dep(tmpdir, data):
|
|
|
|
"""Check we can call a requirement's backend successfully"""
|
|
|
|
project_dir = make_project(
|
|
|
|
tmpdir, backend="dummy_internal_backend", backend_path=['.']
|
|
|
|
)
|
|
|
|
(project_dir / 'dummy_internal_backend.py').write_text(
|
|
|
|
"from dummy_backend import build_wheel"
|
|
|
|
)
|
2020-04-11 18:04:26 +02:00
|
|
|
req = InstallRequirement(None, None)
|
|
|
|
req.source_dir = project_dir # make req believe it has been unpacked
|
2019-11-23 17:57:24 +01:00
|
|
|
req.load_pyproject_toml()
|
|
|
|
env = BuildEnvironment()
|
|
|
|
finder = make_test_finder(find_links=[data.backends])
|
|
|
|
env.install_requirements(finder, ["dummy_backend"], 'normal', "Installing")
|
|
|
|
|
|
|
|
assert hasattr(req.pep517_backend, 'build_wheel')
|
|
|
|
with env:
|
|
|
|
assert req.pep517_backend.build_wheel("dir") == "Backend called"
|
2018-10-10 12:25:26 +02:00
|
|
|
|
|
|
|
|
|
|
|
def test_pep517_install(script, tmpdir, data):
|
|
|
|
"""Check we can build with a custom backend"""
|
|
|
|
project_dir = make_project(
|
|
|
|
tmpdir, requires=['test_backend'],
|
|
|
|
backend="test_backend"
|
|
|
|
)
|
|
|
|
result = script.pip(
|
|
|
|
'install', '--no-index', '-f', data.backends, project_dir
|
|
|
|
)
|
|
|
|
result.assert_installed('project', editable=False)
|
|
|
|
|
|
|
|
|
|
|
|
def test_pep517_install_with_reqs(script, tmpdir, data):
|
|
|
|
"""Backend generated requirements are installed in the build env"""
|
|
|
|
project_dir = make_project(
|
|
|
|
tmpdir, requires=['test_backend'],
|
|
|
|
backend="test_backend"
|
|
|
|
)
|
2019-07-02 07:00:32 +02:00
|
|
|
project_dir.joinpath("backend_reqs.txt").write_text("simplewheel")
|
2018-10-10 12:25:26 +02:00
|
|
|
result = script.pip(
|
|
|
|
'install', '--no-index',
|
|
|
|
'-f', data.backends,
|
|
|
|
'-f', data.packages,
|
|
|
|
project_dir
|
|
|
|
)
|
|
|
|
result.assert_installed('project', editable=False)
|
|
|
|
|
|
|
|
|
|
|
|
def test_no_use_pep517_without_setup_py(script, tmpdir, data):
|
|
|
|
"""Using --no-use-pep517 requires setup.py"""
|
|
|
|
project_dir = make_project(
|
|
|
|
tmpdir, requires=['test_backend'],
|
|
|
|
backend="test_backend"
|
|
|
|
)
|
|
|
|
result = script.pip(
|
|
|
|
'install', '--no-index', '--no-use-pep517',
|
|
|
|
'-f', data.backends,
|
|
|
|
project_dir,
|
|
|
|
expect_error=True
|
|
|
|
)
|
|
|
|
assert 'project does not have a setup.py' in result.stderr
|
2018-10-26 23:27:25 +02:00
|
|
|
|
|
|
|
|
|
|
|
def test_conflicting_pep517_backend_requirements(script, tmpdir, data):
|
|
|
|
project_dir = make_project(
|
|
|
|
tmpdir, requires=['test_backend', 'simplewheel==1.0'],
|
|
|
|
backend="test_backend"
|
|
|
|
)
|
2019-07-02 07:00:32 +02:00
|
|
|
project_dir.joinpath("backend_reqs.txt").write_text("simplewheel==2.0")
|
2018-10-26 23:27:25 +02:00
|
|
|
result = script.pip(
|
|
|
|
'install', '--no-index',
|
|
|
|
'-f', data.backends,
|
|
|
|
'-f', data.packages,
|
|
|
|
project_dir,
|
|
|
|
expect_error=True
|
|
|
|
)
|
2020-02-29 20:53:59 +01:00
|
|
|
msg = (
|
|
|
|
'Some build dependencies for {url} conflict with the backend '
|
|
|
|
'dependencies: simplewheel==1.0 is incompatible with '
|
|
|
|
'simplewheel==2.0.'.format(url=path_to_url(project_dir)))
|
2018-10-26 23:27:25 +02:00
|
|
|
assert (
|
|
|
|
result.returncode != 0 and
|
2020-02-29 20:53:59 +01:00
|
|
|
msg in result.stderr
|
2018-10-26 23:27:25 +02:00
|
|
|
), str(result)
|
|
|
|
|
|
|
|
|
|
|
|
def test_pep517_backend_requirements_already_satisfied(script, tmpdir, data):
|
|
|
|
project_dir = make_project(
|
|
|
|
tmpdir, requires=['test_backend', 'simplewheel==1.0'],
|
|
|
|
backend="test_backend"
|
|
|
|
)
|
2019-07-02 07:00:32 +02:00
|
|
|
project_dir.joinpath("backend_reqs.txt").write_text("simplewheel")
|
2018-10-26 23:27:25 +02:00
|
|
|
result = script.pip(
|
|
|
|
'install', '--no-index',
|
|
|
|
'-f', data.backends,
|
|
|
|
'-f', data.packages,
|
|
|
|
project_dir,
|
|
|
|
)
|
|
|
|
assert 'Installing backend dependencies:' not in result.stdout
|
2019-01-23 03:31:29 +01:00
|
|
|
|
|
|
|
|
|
|
|
def test_pep517_install_with_no_cache_dir(script, tmpdir, data):
|
|
|
|
"""Check builds with a custom backends work, even with no cache.
|
|
|
|
"""
|
|
|
|
project_dir = make_project(
|
|
|
|
tmpdir, requires=['test_backend'],
|
|
|
|
backend="test_backend"
|
|
|
|
)
|
|
|
|
result = script.pip(
|
|
|
|
'install', '--no-cache-dir', '--no-index', '-f', data.backends,
|
|
|
|
project_dir,
|
|
|
|
)
|
|
|
|
result.assert_installed('project', editable=False)
|
2019-01-28 11:16:20 +01:00
|
|
|
|
|
|
|
|
|
|
|
def make_pyproject_with_setup(tmpdir, build_system=True, set_backend=True):
|
2019-08-17 03:34:17 +02:00
|
|
|
project_dir = tmpdir / 'project'
|
|
|
|
project_dir.mkdir()
|
2019-01-28 11:16:20 +01:00
|
|
|
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
|
2020-04-14 09:33:37 +02:00
|
|
|
project_data = toml.dumps({'build-system': buildsys})
|
2019-01-28 11:16:20 +01:00
|
|
|
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"])'
|
|
|
|
)
|
|
|
|
|
2019-07-02 07:00:32 +02:00
|
|
|
project_dir.joinpath('pyproject.toml').write_text(project_data)
|
|
|
|
project_dir.joinpath('setup.py').write_text(setup_script)
|
2019-08-17 03:34:17 +02:00
|
|
|
package_dir = project_dir / "pep517_test"
|
|
|
|
package_dir.mkdir()
|
2019-07-02 07:00:32 +02:00
|
|
|
package_dir.joinpath('__init__.py').write_text('__version__ = "0.1"')
|
2019-01-28 11:16:20 +01:00
|
|
|
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)
|
2019-02-27 18:40:52 +01:00
|
|
|
|
2019-02-27 19:04:50 +01:00
|
|
|
|
2019-07-29 10:57:46 +02:00
|
|
|
@pytest.mark.network
|
2020-01-29 14:47:52 +01:00
|
|
|
@windows_workaround_7667
|
2019-02-27 18:40:52 +01:00
|
|
|
def test_pep517_and_build_options(script, tmpdir, data, common_wheels):
|
|
|
|
"""Backend generated requirements are installed in the build env"""
|
|
|
|
project_dir, name = make_pyproject_with_setup(tmpdir)
|
|
|
|
result = script.pip(
|
2019-02-27 18:50:42 +01:00
|
|
|
'wheel', '--wheel-dir', tmpdir,
|
2019-02-27 18:40:52 +01:00
|
|
|
'--build-option', 'foo',
|
|
|
|
'-f', common_wheels,
|
|
|
|
project_dir,
|
|
|
|
expect_error=True
|
|
|
|
)
|
|
|
|
assert 'Cannot build wheel' in result.stderr
|
2019-11-12 12:03:01 +01:00
|
|
|
assert 'when --build-option is present' in result.stderr
|