diff --git a/tests/test_env.py b/tests/test_env.py index 9b5506fa..953cda0b 100644 --- a/tests/test_env.py +++ b/tests/test_env.py @@ -1,5 +1,4 @@ # SPDX-License-Identifier: MIT -import collections import logging import os import platform @@ -21,30 +20,29 @@ @pytest.mark.isolated def test_isolation(): subprocess.check_call([sys.executable, '-c', 'import build.env']) - with build.env.IsolatedEnvBuilder() as env: + with build.env.IsolatedEnvManager() as env: with pytest.raises(subprocess.CalledProcessError): debug = 'import sys; import os; print(os.linesep.join(sys.path));' - subprocess.check_call([env.executable, '-c', f'{debug} import build.env']) + subprocess.check_call([env.python_executable, '-c', f'{debug} import build.env']) @pytest.mark.isolated def test_isolated_environment_install(mocker): - with build.env.IsolatedEnvBuilder() as env: - mocker.patch('build.env._subprocess') + with build.env.IsolatedEnvManager() as env: + mocker.patch('build.env._DefaultIsolatedEnv.run_isolated') - env.install([]) - build.env._subprocess.assert_not_called() + env.install_packages([]) + build.env._DefaultIsolatedEnv.run_isolated.assert_not_called() - env.install(['some', 'requirements']) - build.env._subprocess.assert_called() - args = build.env._subprocess.call_args[0][0][:-1] + env.install_packages(['some', 'requirements']) + build.env._DefaultIsolatedEnv.run_isolated.assert_called() + args = build.env._DefaultIsolatedEnv.run_isolated.call_args[0][0][:-1] assert args == [ - env.executable, - '-Im', + env.python_executable, + '-m', 'pip', 'install', '--use-pep517', - '--no-warn-script-location', '-r', ] @@ -53,7 +51,7 @@ def test_isolated_environment_install(mocker): @pytest.mark.skipif(sys.platform != 'darwin', reason='workaround for Apple Python') def test_can_get_venv_paths_with_conflicting_default_scheme(mocker): get_scheme_names = mocker.patch('sysconfig.get_scheme_names', return_value=('osx_framework_library',)) - with build.env.IsolatedEnvBuilder(): + with build.env.IsolatedEnvManager(): pass assert get_scheme_names.call_count == 1 @@ -68,7 +66,7 @@ def _get_paths(vars): # noqa get_paths = mocker.patch('sysconfig.get_paths', side_effect=_get_paths) with pytest.raises(RuntimeError, match='Virtual environment creation failed, executable .* missing'): - with build.env.IsolatedEnvBuilder(): + with build.env.IsolatedEnvManager(): pass assert get_paths.call_count == 1 @@ -98,55 +96,50 @@ def install(self, requirements): def test_isolated_env_log(mocker, caplog, package_test_flit): - mocker.patch('build.env._subprocess') + mocker.patch('build.env._DefaultIsolatedEnv.run_isolated') caplog.set_level(logging.DEBUG) - builder = build.env.IsolatedEnvBuilder() + builder = build.env.IsolatedEnvManager() builder.log('something') with builder as env: - env.install(['something']) + env.install_packages(['something']) assert [(record.levelname, record.message) for record in caplog.records] == [ ('INFO', 'something'), - ('INFO', 'Creating venv isolated environment...'), - ('INFO', 'Installing packages in isolated environment... (something)'), + ('INFO', 'Creating isolated environment (venv)...'), + ('INFO', 'Updating pip...'), + ('INFO', 'Uninstalling setuptools...'), + ('INFO', 'Installing build dependencies... (something)'), ] if sys.version_info >= (3, 8): # stacklevel - assert [(record.lineno) for record in caplog.records] == [105, 102, 193] + assert [(record.lineno) for record in caplog.records] == [103, 209, 216, 218, 239] @pytest.mark.isolated def test_default_pip_is_never_too_old(): - with build.env.IsolatedEnvBuilder() as env: + with build.env.IsolatedEnvManager() as env: version = subprocess.check_output( - [env.executable, '-c', 'import pip; print(pip.__version__)'], universal_newlines=True + [env.python_executable, '-c', 'import pip; print(pip.__version__)'], universal_newlines=True ).strip() assert Version(version) >= Version('19.1') @pytest.mark.isolated -@pytest.mark.parametrize('pip_version', ['20.2.0', '20.3.0', '21.0.0', '21.0.1']) @pytest.mark.parametrize('arch', ['x86_64', 'arm64']) -def test_pip_needs_upgrade_mac_os_11(mocker, pip_version, arch): - SimpleNamespace = collections.namedtuple('SimpleNamespace', 'version') - - _subprocess = mocker.patch('build.env._subprocess') +def test_pip_needs_upgrade_mac_os_11(mocker, arch): + _subprocess = mocker.patch('build.env._DefaultIsolatedEnv.run_isolated') mocker.patch('platform.system', return_value='Darwin') - mocker.patch('platform.machine', return_value=arch) - mocker.patch('platform.mac_ver', return_value=('11.0', ('', '', ''), '')) - mocker.patch('build.env.metadata.distributions', return_value=(SimpleNamespace(version=pip_version),)) - - min_version = Version('20.3' if arch == 'x86_64' else '21.0.1') - with build.env.IsolatedEnvBuilder(): - if Version(pip_version) < min_version: - print(_subprocess.call_args_list) - upgrade_call, uninstall_call = _subprocess.call_args_list - answer = 'pip>=20.3.0' if arch == 'x86_64' else 'pip>=21.0.1' - assert upgrade_call[0][0][1:] == ['-m', 'pip', 'install', answer] - assert uninstall_call[0][0][1:] == ['-m', 'pip', 'uninstall', 'setuptools', '-y'] - else: - (uninstall_call,) = _subprocess.call_args_list - assert uninstall_call[0][0][1:] == ['-m', 'pip', 'uninstall', 'setuptools', '-y'] + mocker.patch('platform.mac_ver', return_value=('11.0', ('', '', ''), arch)) + + # Cache must be cleared to rerun + build.env._get_min_pip_version.cache_clear() + + with build.env.IsolatedEnvManager(): + upgrade_call, uninstall_call = _subprocess.call_args_list + print(_subprocess.call_args_list) + answer = 'pip>=20.3' if arch == 'x86_64' else 'pip>=21.0.1' + assert upgrade_call[0][0][1:] == ['-m', 'pip', 'install', answer] + assert uninstall_call[0][0][1:] == ['-m', 'pip', 'uninstall', '-y', 'setuptools'] @pytest.mark.isolated @@ -160,8 +153,8 @@ def test_venv_symlink(mocker, has_symlink): mocker.patch('os.symlink', side_effect=OSError()) # Cache must be cleared to rerun - build.env._fs_supports_symlink.cache_clear() - supports_symlink = build.env._fs_supports_symlink() - build.env._fs_supports_symlink.cache_clear() + build.env._fs_supports_symlinks.cache_clear() + supports_symlinks = build.env._fs_supports_symlinks() + build.env._fs_supports_symlinks.cache_clear() - assert supports_symlink is has_symlink + assert supports_symlinks is has_symlink diff --git a/tests/test_main.py b/tests/test_main.py index d34f1bc2..9c313692 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -125,7 +125,7 @@ def test_build_isolated(mocker, package_test_flit): ], ) mocker.patch('build.__main__._error') - install = mocker.patch('build.env._IsolatedEnvVenvPip.install') + install = mocker.patch('build.env._DefaultIsolatedEnv.install_packages') build.__main__.build_package(package_test_flit, '.', ['sdist']) @@ -168,7 +168,7 @@ def test_build_no_isolation_with_check_deps(mocker, package_test_flit, missing_d @pytest.mark.isolated def test_build_raises_build_exception(mocker, package_test_flit): mocker.patch('build.ProjectBuilder.get_requires_for_build', side_effect=build.BuildException) - mocker.patch('build.env._IsolatedEnvVenvPip.install') + mocker.patch('build.env._DefaultIsolatedEnv.install_packages') with pytest.raises(build.BuildException): build.__main__.build_package(package_test_flit, '.', ['sdist']) @@ -177,7 +177,7 @@ def test_build_raises_build_exception(mocker, package_test_flit): @pytest.mark.isolated def test_build_raises_build_backend_exception(mocker, package_test_flit): mocker.patch('build.ProjectBuilder.get_requires_for_build', side_effect=build.BuildBackendException(Exception('a'))) - mocker.patch('build.env._IsolatedEnvVenvPip.install') + mocker.patch('build.env._DefaultIsolatedEnv.install_packages') msg = f"Backend operation failed: Exception('a'{',' if sys.version_info < (3, 7) else ''})" with pytest.raises(build.BuildBackendException, match=re.escape(msg)): @@ -218,15 +218,19 @@ def test_build_package_via_sdist_invalid_distribution(tmp_dir, package_test_setu ( [], [ - '* Creating venv isolated environment...', - '* Installing packages in isolated environment... (setuptools >= 42.0.0, wheel >= 0.36.0)', + '* Creating isolated environment (venv)...', + '* Updating pip...', + '* Uninstalling setuptools...', + '* Installing build dependencies... (setuptools >= 42.0.0, wheel >= 0.36.0)', '* Getting dependencies for sdist...', '* Building sdist...', '* Building wheel from sdist', - '* Creating venv isolated environment...', - '* Installing packages in isolated environment... (setuptools >= 42.0.0, wheel >= 0.36.0)', + '* Creating isolated environment (venv)...', + '* Updating pip...', + '* Uninstalling setuptools...', + '* Installing build dependencies... (setuptools >= 42.0.0, wheel >= 0.36.0)', '* Getting dependencies for wheel...', - '* Installing packages in isolated environment... (wheel)', + '* Installing build dependencies... (wheel)', '* Building wheel...', 'Successfully built test_setuptools-1.0.0.tar.gz and test_setuptools-1.0.0-py2.py3-none-any.whl', ], @@ -245,10 +249,12 @@ def test_build_package_via_sdist_invalid_distribution(tmp_dir, package_test_setu ( ['--wheel'], [ - '* Creating venv isolated environment...', - '* Installing packages in isolated environment... (setuptools >= 42.0.0, wheel >= 0.36.0)', + '* Creating isolated environment (venv)...', + '* Updating pip...', + '* Uninstalling setuptools...', + '* Installing build dependencies... (setuptools >= 42.0.0, wheel >= 0.36.0)', '* Getting dependencies for wheel...', - '* Installing packages in isolated environment... (wheel)', + '* Installing build dependencies... (wheel)', '* Building wheel...', 'Successfully built test_setuptools-1.0.0-py2.py3-none-any.whl', ], @@ -285,7 +291,7 @@ def test_build_package_via_sdist_invalid_distribution(tmp_dir, package_test_setu 'sdist-and-wheel-direct-no-isolation', ], ) -@pytest.mark.flaky(reruns=5) +# @pytest.mark.flaky(reruns=5) def test_output(package_test_setuptools, tmp_dir, capsys, args, output): build.__main__.main([package_test_setuptools, '-o', tmp_dir] + args) stdout, stderr = capsys.readouterr() @@ -307,8 +313,10 @@ def main_reload_styles(): False, 'ERROR ', [ - '* Creating venv isolated environment...', - '* Installing packages in isolated environment... (setuptools >= 42.0.0, this is invalid, wheel >= 0.36.0)', + '* Creating isolated environment (venv)...', + '* Updating pip...', + '* Uninstalling setuptools...', + '* Installing build dependencies... (setuptools >= 42.0.0, this is invalid, wheel >= 0.36.0)', '', 'Traceback (most recent call last):', ], @@ -317,9 +325,10 @@ def main_reload_styles(): True, '\33[91mERROR\33[0m ', [ - '\33[1m* Creating venv isolated environment...\33[0m', - '\33[1m* Installing packages in isolated environment... ' - '(setuptools >= 42.0.0, this is invalid, wheel >= 0.36.0)\33[0m', + '\33[1m* Creating isolated environment (venv)...\33[0m', + '\33[1m* Updating pip...\33[0m', + '\33[1m* Uninstalling setuptools...\33[0m', + '\33[1m* Installing build dependencies... ' '(setuptools >= 42.0.0, this is invalid, wheel >= 0.36.0)\33[0m', '', '\33[2mTraceback (most recent call last):', ], @@ -354,7 +363,7 @@ def test_output_env_subprocess_error( stdout, stderr = capsys.readouterr() stdout, stderr = stdout.splitlines(), stderr.splitlines() - assert stdout[:4] == stdout_body + assert stdout[:6] == stdout_body assert stdout[-1].startswith(stdout_error) assert len(stderr) == 1 diff --git a/tests/test_projectbuilder.py b/tests/test_projectbuilder.py index 98687f88..0556c75e 100644 --- a/tests/test_projectbuilder.py +++ b/tests/test_projectbuilder.py @@ -356,7 +356,7 @@ def test_build_not_dir_outdir(mocker, tmp_dir, package_test_flit): def demo_pkg_inline(tmp_path_factory): # builds a wheel without any dependencies and with a console script demo-pkg-inline tmp_path = tmp_path_factory.mktemp('demo-pkg-inline') - builder = build.ProjectBuilder(srcdir=os.path.join(os.path.dirname(__file__), 'packages', 'inline')) + builder = build.ProjectBuilder(source_dir=os.path.join(os.path.dirname(__file__), 'packages', 'inline')) out = tmp_path / 'dist' builder.build('wheel', str(out)) return next(out.iterdir())