@@ -93,18 +93,18 @@ def test_pep514_run(capsys, caplog):
93
93
out , err = capsys .readouterr ()
94
94
expected = textwrap .dedent (
95
95
r"""
96
- ('CompanyA', 3, 6, 64, False, 'Z:\\CompanyA\\Python\\3.6\\python .exe', None)
97
- ('ContinuumAnalytics', 3, 10, 32, False, 'C:\\Users\\user\\Miniconda3\\python .exe', None)
98
- ('ContinuumAnalytics', 3, 10, 64, False, 'C:\\Users\\user\\Miniconda3-64\\python .exe', None)
96
+ ('CompanyA', 3, 6, 64, False, 'Z:\\CompanyA\\Python\\3.6\\python3 .exe', None)
97
+ ('ContinuumAnalytics', 3, 10, 32, False, 'C:\\Users\\user\\Miniconda3\\python3 .exe', None)
98
+ ('ContinuumAnalytics', 3, 10, 64, False, 'C:\\Users\\user\\Miniconda3-64\\python3 .exe', None)
99
99
('PythonCore', 2, 7, 64, False, 'C:\\Python27\\python.exe', None)
100
- ('PythonCore', 3, 10, 32, False, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310-32\\python .exe', None)
101
- ('PythonCore', 3, 12, 64, False, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python312\\python .exe', None)
100
+ ('PythonCore', 3, 10, 32, False, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310-32\\python3 .exe', None)
101
+ ('PythonCore', 3, 12, 64, False, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python312\\python3 .exe', None)
102
102
('PythonCore', 3, 13, 64, True, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python313\\python3.13t.exe', None)
103
- ('PythonCore', 3, 7, 64, False, 'C:\\Python37\\python .exe', None)
104
- ('PythonCore', 3, 8, 64, False, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python38\\python .exe', None)
105
- ('PythonCore', 3, 9, 64, False, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python39\\python .exe', None)
106
- ('PythonCore', 3, 9, 64, False, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python39\\python .exe', None)
107
- ('PythonCore', 3, 9, 64, False, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python39\\python .exe', None)
103
+ ('PythonCore', 3, 7, 64, False, 'C:\\Python37\\python3 .exe', None)
104
+ ('PythonCore', 3, 8, 64, False, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python38\\python3 .exe', None)
105
+ ('PythonCore', 3, 9, 64, False, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python39\\python3 .exe', None)
106
+ ('PythonCore', 3, 9, 64, False, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python39\\python3 .exe', None)
107
+ ('PythonCore', 3, 9, 64, False, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python39\\python3 .exe', None)
108
108
""" , # noqa: E501
109
109
).strip ()
110
110
assert out .strip () == expected
@@ -123,35 +123,25 @@ def test_pep514_run(capsys, caplog):
123
123
assert caplog .messages == expected_logs
124
124
125
125
126
+ @pytest .mark .usefixtures ("_mock_registry" )
126
127
@pytest .mark .skipif (sys .platform != "win32" , reason = "no Windows registry" )
127
128
def test_pep514_python3_fallback (mocker , tmp_path ):
128
- from virtualenv .discovery .windows . pep514 import discover_pythons , winreg # noqa: PLC0415
129
+ from virtualenv .discovery .windows import pep514 # noqa: PLC0415
129
130
130
- # Create a mock python3.exe
131
+ # Create a mock python3.exe, but no python.exe
131
132
python3_exe = tmp_path / "python3.exe"
132
133
python3_exe .touch ()
134
+ mocker .patch ("os.path.exists" , lambda path : str (path ) == str (python3_exe ))
133
135
134
136
# Mock the registry to return our test python distribution
135
- def open_key_ex (key , sub_key , * args , ** kwargs ):
136
- if sub_key == r"Software\Python\PythonCore\3.9-32" :
137
- return mocker .MagicMock ()
138
- if sub_key == r"Software\Python\PythonCore\3.9-32\InstallPath" :
139
- return mocker .MagicMock ()
140
- return winreg .OpenKeyEx (key , sub_key , * args , ** kwargs )
141
-
142
- def query_value_ex (key , value_name , * args , ** kwargs ):
143
- if value_name == "ExecutablePath" :
144
- return None # No executable path, forcing a fallback
145
- if value_name is None :
146
- return str (tmp_path )
147
- return winreg .QueryValueEx (key , value_name , * args , ** kwargs )
137
+ mocker .patch .object (pep514 , "get_value" , side_effect = lambda key , name : {None : str (tmp_path )}.get (name ))
138
+ mocker .patch .object (pep514 .winreg , "OpenKeyEx" , return_value = mocker .MagicMock ())
139
+ mocker .patch .object (pep514 .winreg , "EnumKey" , side_effect = [["PythonCore" ], ["3.9-32" ], ["InstallPath" ]])
140
+ mocker .patch .object (pep514 , "load_version_data" , return_value = (3 , 9 , 0 ))
141
+ mocker .patch .object (pep514 , "load_arch_data" , return_value = 64 )
142
+ mocker .patch .object (pep514 , "load_threaded" , return_value = False )
143
+ mocker .patch .object (pep514 , "msg" )
148
144
149
- mocker .patch ("winreg.OpenKeyEx" , side_effect = open_key_ex )
150
- mocker .patch ("winreg.QueryValueEx" , side_effect = query_value_ex )
151
- mocker .patch ("os.path.exists" , return_value = True )
145
+ interpreters = list (pep514 .discover_pythons ())
152
146
153
- # Mock EnumKey to inject our test distribution
154
- mocker .patch ("winreg.EnumKey" , return_value = ["3.9-32" ])
155
-
156
- interpreters = list (discover_pythons ())
157
- assert any (str (python3_exe ) in i for i in interpreters )
147
+ assert interpreters == [("PythonCore" , 3 , 9 , 64 , False , str (python3_exe ), None )]
0 commit comments