1
1
# SPDX-License-Identifier: MIT
2
- import collections
3
2
import logging
4
3
import platform
5
4
import subprocess
6
5
import sys
7
6
import sysconfig
8
7
8
+ from types import SimpleNamespace
9
+
9
10
import pytest
11
+ import pytest_mock
10
12
11
13
from packaging .version import Version
12
14
@@ -27,16 +29,16 @@ def test_isolation():
27
29
28
30
@pytest .mark .isolated
29
31
@pytest .mark .usefixtures ('local_pip' )
30
- def test_isolated_environment_install (mocker ):
32
+ def test_isolated_environment_install (mocker : pytest_mock . MockerFixture ):
31
33
with build .env .DefaultIsolatedEnv () as env :
32
- mocker .patch ('build.env.run_subprocess' )
34
+ run_subprocess = mocker .patch ('build.env.run_subprocess' )
33
35
34
36
env .install ([])
35
- build . env . run_subprocess .assert_not_called ()
37
+ run_subprocess .assert_not_called ()
36
38
37
39
env .install (['some' , 'requirements' ])
38
- build . env . run_subprocess .assert_called ()
39
- args = build . env . run_subprocess .call_args [0 ][0 ][:- 1 ]
40
+ run_subprocess .assert_called ()
41
+ args = run_subprocess .call_args [0 ][0 ][:- 1 ]
40
42
assert args == [
41
43
env .python_executable ,
42
44
'-Im' ,
@@ -50,15 +52,19 @@ def test_isolated_environment_install(mocker):
50
52
51
53
@pytest .mark .skipif (IS_PYPY3 , reason = 'PyPy3 uses get path to create and provision venv' )
52
54
@pytest .mark .skipif (sys .platform != 'darwin' , reason = 'workaround for Apple Python' )
53
- def test_can_get_venv_paths_with_conflicting_default_scheme (mocker ):
55
+ def test_can_get_venv_paths_with_conflicting_default_scheme (
56
+ mocker : pytest_mock .MockerFixture ,
57
+ ):
54
58
get_scheme_names = mocker .patch ('sysconfig.get_scheme_names' , return_value = ('osx_framework_library' ,))
55
59
with build .env .DefaultIsolatedEnv ():
56
60
pass
57
61
assert get_scheme_names .call_count == 1
58
62
59
63
60
64
@pytest .mark .skipif ('posix_local' not in sysconfig .get_scheme_names (), reason = 'workaround for Debian/Ubuntu Python' )
61
- def test_can_get_venv_paths_with_posix_local_default_scheme (mocker ):
65
+ def test_can_get_venv_paths_with_posix_local_default_scheme (
66
+ mocker : pytest_mock .MockerFixture ,
67
+ ):
62
68
get_paths = mocker .spy (sysconfig , 'get_paths' )
63
69
# We should never call this, but we patch it to ensure failure if we do
64
70
get_default_scheme = mocker .patch ('sysconfig.get_default_scheme' , return_value = 'posix_local' )
@@ -68,7 +74,9 @@ def test_can_get_venv_paths_with_posix_local_default_scheme(mocker):
68
74
assert get_default_scheme .call_count == 0
69
75
70
76
71
- def test_executable_missing_post_creation (mocker ):
77
+ def test_executable_missing_post_creation (
78
+ mocker : pytest_mock .MockerFixture ,
79
+ ):
72
80
venv_create = mocker .patch ('venv.EnvBuilder.create' )
73
81
with pytest .raises (RuntimeError , match = 'Virtual environment creation failed, executable .* missing' ):
74
82
with build .env .DefaultIsolatedEnv ():
@@ -80,36 +88,36 @@ def test_isolated_env_abstract():
80
88
with pytest .raises (TypeError ):
81
89
build .env .IsolatedEnv ()
82
90
83
-
84
- def test_isolated_env_has_executable_still_abstract ():
85
- class Env (build .env .IsolatedEnv ):
91
+ class PartialEnv (build .env .IsolatedEnv ):
86
92
@property
87
93
def executable (self ):
88
94
raise NotImplementedError
89
95
90
96
with pytest .raises (TypeError ):
91
- Env ()
97
+ PartialEnv ()
92
98
93
-
94
- def test_isolated_env_has_install_still_abstract ():
95
- class Env (build .env .IsolatedEnv ):
96
- def install (self , requirements ):
97
- raise NotImplementedError
99
+ class PartialEnv (build .env .IsolatedEnv ):
100
+ def make_extra_environ (self ):
101
+ return super ().make_extra_environ ()
98
102
99
103
with pytest .raises (TypeError ):
100
- Env ()
104
+ PartialEnv ()
101
105
102
106
103
107
@pytest .mark .pypy3323bug
104
- def test_isolated_env_log (mocker , caplog , package_test_flit ):
105
- mocker .patch ('build.env.run_subprocess' )
108
+ @pytest .mark .usefixtures ('package_test_flit' )
109
+ def test_isolated_env_log (
110
+ caplog : pytest .LogCaptureFixture ,
111
+ mocker : pytest_mock .MockerFixture ,
112
+ ):
106
113
caplog .set_level (logging .DEBUG )
114
+ mocker .patch ('build.env.run_subprocess' )
107
115
108
116
with build .env .DefaultIsolatedEnv () as env :
109
117
env .install (['something' ])
110
118
111
119
assert [(record .levelname , record .message ) for record in caplog .records ] == [
112
- ('INFO' , 'Creating venv isolated environment...' ),
120
+ ('INFO' , 'Creating isolated environment: venv ...' ),
113
121
('INFO' , 'Installing packages in isolated environment:\n - something' ),
114
122
]
115
123
@@ -130,32 +138,33 @@ def test_default_pip_is_never_too_old():
130
138
@pytest .mark .parametrize ('pip_version' , ['20.2.0' , '20.3.0' , '21.0.0' , '21.0.1' ])
131
139
@pytest .mark .parametrize ('arch' , ['x86_64' , 'arm64' ])
132
140
@pytest .mark .usefixtures ('local_pip' )
133
- def test_pip_needs_upgrade_mac_os_11 (mocker , pip_version , arch ):
134
- SimpleNamespace = collections .namedtuple ('SimpleNamespace' , 'version' )
135
-
136
- _subprocess = mocker .patch ('build.env.run_subprocess' )
141
+ def test_pip_needs_upgrade_mac_os_11 (
142
+ mocker : pytest_mock .MockerFixture ,
143
+ pip_version : str ,
144
+ arch : str ,
145
+ ):
146
+ run_subprocess = mocker .patch ('build.env.run_subprocess' )
137
147
mocker .patch ('platform.system' , return_value = 'Darwin' )
138
- mocker .patch ('platform.machine' , return_value = arch )
139
- mocker .patch ('platform.mac_ver' , return_value = ('11.0' , ('' , '' , '' ), '' ))
148
+ mocker .patch ('platform.mac_ver' , return_value = ('11.0' , ('' , '' , '' ), arch ))
140
149
mocker .patch ('build._compat.importlib.metadata.distributions' , return_value = (SimpleNamespace (version = pip_version ),))
141
150
142
151
min_version = Version ('20.3' if arch == 'x86_64' else '21.0.1' )
143
152
with build .env .DefaultIsolatedEnv ():
144
153
if Version (pip_version ) < min_version :
145
- print (_subprocess .call_args_list )
146
- upgrade_call , uninstall_call = _subprocess .call_args_list
154
+ upgrade_call , uninstall_call = run_subprocess .call_args_list
147
155
answer = 'pip>=20.3.0' if arch == 'x86_64' else 'pip>=21.0.1'
148
- assert upgrade_call [0 ][0 ][1 :] == ['-m ' , 'pip' , 'install' , answer ]
149
- assert uninstall_call [0 ][0 ][1 :] == ['-m ' , 'pip' , 'uninstall' , 'setuptools ' , '-y ' ]
156
+ assert upgrade_call [0 ][0 ][1 :] == ['-Im ' , 'pip' , 'install' , answer ]
157
+ assert uninstall_call [0 ][0 ][1 :] == ['-Im ' , 'pip' , 'uninstall' , '-y ' , 'setuptools ' ]
150
158
else :
151
- (uninstall_call ,) = _subprocess .call_args_list
152
- assert uninstall_call [0 ][0 ][1 :] == ['-m ' , 'pip' , 'uninstall' , 'setuptools ' , '-y ' ]
159
+ (uninstall_call ,) = run_subprocess .call_args_list
160
+ assert uninstall_call [0 ][0 ][1 :] == ['-Im ' , 'pip' , 'uninstall' , '-y ' , 'setuptools ' ]
153
161
154
162
155
- @pytest .mark .isolated
156
- @pytest .mark .skipif (IS_PYPY3 and sys .platform .startswith ('win' ), reason = 'Isolated tests not supported on PyPy3 + Windows' )
157
163
@pytest .mark .parametrize ('has_symlink' , [True , False ] if sys .platform .startswith ('win' ) else [True ])
158
- def test_venv_symlink (mocker , has_symlink ):
164
+ def test_venv_symlink (
165
+ mocker : pytest_mock .MockerFixture ,
166
+ has_symlink : bool ,
167
+ ):
159
168
if has_symlink :
160
169
mocker .patch ('os.symlink' )
161
170
mocker .patch ('os.unlink' )
0 commit comments