/
niceSOFT
/
python3-build
Обзор
Документация
Войти
/
niceSOFT
/
python3-build
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
0.5.1
tests/test_env.py
158 строк
6 KB
layday
env: override default scheme for Apple Python venv
19 июн 2021, 19:02
19 июн 2021, 19:02
251c509
Код
Авторство
О чём код?
# SPDX-License-Identifier: MIT import collections import os import platform import shutil import subprocess import sys import sysconfig import pytest from packaging.version import Version import build.env IS_PYPY3 = sys.version_info[0] == 3 and platform.python_implementation() == 'PyPy' IS_PY35 = sys.version_info[:2] == (3, 5) IS_PY2 = sys.version_info[0] == 2 @pytest.mark.isolated def test_isolation(): subprocess.check_call([sys.executable, '-c', 'import build.env']) with build.env.IsolatedEnvBuilder() as env: with pytest.raises(subprocess.CalledProcessError): debug = 'import sys; import os; print(os.linesep.join(sys.path));' subprocess.check_call([env.executable, '-c', '{} import build.env'.format(debug)]) @pytest.mark.isolated def test_isolated_environment_install(mocker): with build.env.IsolatedEnvBuilder() as env: mocker.patch('subprocess.check_call') env.install([]) subprocess.check_call.assert_not_called() env.install(['some', 'requirements']) if not IS_PY35: subprocess.check_call.assert_called() args = subprocess.check_call.call_args[0][0][:-1] assert args == [ env.executable, '-{}m'.format('E' if IS_PY2 else 'I'), 'pip', 'install', '--use-pep517', '--no-warn-script-location', '-r', ] @pytest.mark.skipif(IS_PY2, reason='venv module used on Python 3 only') @pytest.mark.skipif(IS_PYPY3, reason='PyPy3 uses get path to create and provision venv') @pytest.mark.skipif(sys.platform != 'darwin', reason='workaround for Apple Python') def test_can_get_venv_paths_with_conflicting_default_scheme(mocker): mocker.patch.object(build.env, 'virtualenv', None) get_scheme_names = mocker.patch('sysconfig.get_scheme_names', return_value=('osx_framework_library',)) with build.env.IsolatedEnvBuilder(): pass assert get_scheme_names.call_count == 1 @pytest.mark.skipif(IS_PY2, reason='venv module used on Python 3 only') @pytest.mark.skipif(IS_PYPY3, reason='PyPy3 uses get path to create and provision venv') def test_executable_missing_post_creation(mocker): mocker.patch.object(build.env, 'virtualenv', None) original_get_paths = sysconfig.get_paths def _get_paths(vars): # noqa shutil.rmtree(vars['base']) return original_get_paths(vars=vars) 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(): pass assert get_paths.call_count == 1 def test_isolated_env_abstract(): with pytest.raises(TypeError): build.env.IsolatedEnv() def test_isolated_env_has_executable_still_abstract(): class Env(build.env.IsolatedEnv): # noqa @property def executable(self): raise NotImplementedError with pytest.raises(TypeError): Env() def test_isolated_env_has_install_still_abstract(): class Env(build.env.IsolatedEnv): # noqa def install(self, requirements): raise NotImplementedError with pytest.raises(TypeError): Env() @pytest.mark.isolated def test_default_pip_is_never_too_old(): with build.env.IsolatedEnvBuilder() as env: version = subprocess.check_output( [env.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']) @pytest.mark.skipif(IS_PY35, reason="Python 3.5 does not run on macOS 11, and pip can't upgrade to 21 there") @pytest.mark.skipif(IS_PY2, reason='venv module used on Python 3 only') def test_pip_needs_upgrade_mac_os_11(mocker, pip_version, arch): SimpleNamespace = collections.namedtuple('SimpleNamespace', 'version') check_call = mocker.patch('subprocess.check_call') 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),)) mocker.patch.object(build.env, 'virtualenv', None) # hide virtualenv min_version = Version('20.3' if arch == 'x86_64' else '21.0.1') with build.env.IsolatedEnvBuilder(): if Version(pip_version) < min_version: upgrade_call, uninstall_call = check_call.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,) = check_call.call_args_list assert uninstall_call[0][0][1:] == ['-m', 'pip', 'uninstall', 'setuptools', '-y'] @pytest.mark.isolated @pytest.mark.skipif(IS_PY2, reason='venv module used on Python 3 only') @pytest.mark.skipif(IS_PYPY3 and os.name == 'nt', reason='Isolated tests not supported on PyPy3 + Windows') @pytest.mark.parametrize('has_symlink', [True, False] if os.name == 'nt' else [True]) def test_venv_symlink(mocker, has_symlink): if has_symlink: mocker.patch('os.symlink') mocker.patch('os.unlink') else: 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() assert supports_symlink is has_symlink