11import sys
22import textwrap
3- from collections import defaultdict
4- from contextlib import contextmanager
5- from pathlib import Path
63
74import pytest
85
@@ -14,16 +11,17 @@ def test_pep514():
1411
1512 interpreters = list (discover_pythons ())
1613 assert interpreters == [
17- ("ContinuumAnalytics" , 3 , 7 , 32 , "C:\\ Users\\ user\\ Miniconda3\\ python.exe" , None ),
18- ("ContinuumAnalytics" , 3 , 7 , 64 , "C:\\ Users\\ user\\ Miniconda3-64\\ python.exe" , None ),
19- ("PythonCore" , 3 , 6 , 64 , "C:\\ Users\\ user\\ AppData\\ Local\\ Programs\\ Python\\ Python36\\ python.exe" , None ),
20- ("PythonCore" , 3 , 6 , 64 , "C:\\ Users\\ user\\ AppData\\ Local\\ Programs\\ Python\\ Python36\\ python.exe" , None ),
21- ("PythonCore" , 3 , 5 , 64 , "C:\\ Users\\ user\\ AppData\\ Local\\ Programs\\ Python\\ Python35\\ python.exe" , None ),
22- ("PythonCore" , 3 , 6 , 64 , "C:\\ Users\\ user\\ AppData\\ Local\\ Programs\\ Python\\ Python36\\ python.exe" , None ),
23- ("PythonCore" , 3 , 7 , 32 , "C:\\ Users\\ user\\ AppData\\ Local\\ Programs\\ Python\\ Python37-32\\ python.exe" , None ),
24- ("PythonCore" , 3 , 9 , 64 , "C:\\ Users\\ user\\ AppData\\ Local\\ Programs\\ Python\\ Python36\\ python.exe" , None ),
14+ ("ContinuumAnalytics" , 3 , 10 , 32 , "C:\\ Users\\ user\\ Miniconda3\\ python.exe" , None ),
15+ ("ContinuumAnalytics" , 3 , 10 , 64 , "C:\\ Users\\ user\\ Miniconda3-64\\ python.exe" , None ),
16+ ("PythonCore" , 3 , 9 , 64 , "C:\\ Users\\ user\\ AppData\\ Local\\ Programs\\ Python\\ Python39\\ python.exe" , None ),
17+ ("PythonCore" , 3 , 9 , 64 , "C:\\ Users\\ user\\ AppData\\ Local\\ Programs\\ Python\\ Python39\\ python.exe" , None ),
18+ ("PythonCore" , 3 , 8 , 64 , "C:\\ Users\\ user\\ AppData\\ Local\\ Programs\\ Python\\ Python38\\ python.exe" , None ),
19+ ("PythonCore" , 3 , 9 , 64 , "C:\\ Users\\ user\\ AppData\\ Local\\ Programs\\ Python\\ Python39\\ python.exe" , None ),
20+ ("PythonCore" , 3 , 10 , 32 , "C:\\ Users\\ user\\ AppData\\ Local\\ Programs\\ Python\\ Python310-32\\ python.exe" , None ),
21+ ("PythonCore" , 3 , 12 , 64 , "C:\\ Users\\ user\\ AppData\\ Local\\ Programs\\ Python\\ Python312\\ python.exe" , None ),
22+ ("CompanyA" , 3 , 6 , 64 , "Z:\\ CompanyA\\ Python\\ 3.6\\ python.exe" , None ),
2523 ("PythonCore" , 2 , 7 , 64 , "C:\\ Python27\\ python.exe" , None ),
26- ("PythonCore" , 3 , 4 , 64 , "C:\\ Python34 \\ python.exe" , None ),
24+ ("PythonCore" , 3 , 7 , 64 , "C:\\ Python37 \\ python.exe" , None ),
2725 ]
2826
2927
@@ -36,16 +34,17 @@ def test_pep514_run(capsys, caplog):
3634 out , err = capsys .readouterr ()
3735 expected = textwrap .dedent (
3836 r"""
39- ('ContinuumAnalytics', 3, 7, 32, 'C:\\Users\\user\\Miniconda3\\python.exe', None)
40- ('ContinuumAnalytics', 3, 7, 64, 'C:\\Users\\user\\Miniconda3-64\\python.exe', None)
37+ ('CompanyA', 3, 6, 64, 'Z:\\CompanyA\\Python\\3.6\\python.exe', None)
38+ ('ContinuumAnalytics', 3, 10, 32, 'C:\\Users\\user\\Miniconda3\\python.exe', None)
39+ ('ContinuumAnalytics', 3, 10, 64, 'C:\\Users\\user\\Miniconda3-64\\python.exe', None)
4140 ('PythonCore', 2, 7, 64, 'C:\\Python27\\python.exe', None)
42- ('PythonCore', 3, 4, 64 , 'C:\\Python34 \\python.exe', None)
43- ('PythonCore', 3, 5 , 64, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python35 \\python.exe', None)
44- ('PythonCore', 3, 6 , 64, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python36 \\python.exe', None)
45- ('PythonCore', 3, 6 , 64, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python36 \\python.exe', None)
46- ('PythonCore', 3, 6 , 64, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python36 \\python.exe', None)
47- ('PythonCore', 3, 7, 32 , 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python37-32 \\python.exe', None)
48- ('PythonCore', 3, 9, 64, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python36 \\python.exe', None)
41+ ('PythonCore', 3, 10, 32 , 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310-32 \\python.exe', None)
42+ ('PythonCore', 3, 12 , 64, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python312 \\python.exe', None)
43+ ('PythonCore', 3, 7 , 64, 'C:\\Python37 \\python.exe', None)
44+ ('PythonCore', 3, 8 , 64, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python38 \\python.exe', None)
45+ ('PythonCore', 3, 9 , 64, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python39 \\python.exe', None)
46+ ('PythonCore', 3, 9, 64 , 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python39 \\python.exe', None)
47+ ('PythonCore', 3, 9, 64, 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python39 \\python.exe', None)
4948 """ ,
5049 ).strip ()
5150 assert out .strip () == expected
@@ -56,136 +55,9 @@ def test_pep514_run(capsys, caplog):
5655 f"{ prefix } HKEY_CURRENT_USER/PythonCore/3.2/SysArchitecture error: arch is not string: 100" ,
5756 f"{ prefix } HKEY_CURRENT_USER/PythonCore/3.3 error: no ExecutablePath or default for it" ,
5857 f"{ prefix } HKEY_CURRENT_USER/PythonCore/3.3 error: could not load exe with value None" ,
59- f"{ prefix } HKEY_CURRENT_USER/PythonCore/3.8 /InstallPath error: missing" ,
60- f"{ prefix } HKEY_CURRENT_USER/PythonCore/3.9 /SysVersion error: invalid format magic" ,
58+ f"{ prefix } HKEY_CURRENT_USER/PythonCore/3.11 /InstallPath error: missing" ,
59+ f"{ prefix } HKEY_CURRENT_USER/PythonCore/3.12 /SysVersion error: invalid format magic" ,
6160 f"{ prefix } HKEY_CURRENT_USER/PythonCore/3.X/SysVersion error: version is not string: 2778" ,
6261 f"{ prefix } HKEY_CURRENT_USER/PythonCore/3.X error: invalid format 3.X" ,
6362 ]
6463 assert caplog .messages == expected_logs
65-
66-
67- @pytest .fixture ()
68- def _mock_registry (mocker ):
69- from virtualenv .discovery .windows .pep514 import winreg
70-
71- loc , glob = {}, {}
72- mock_value_str = (Path (__file__ ).parent / "winreg-mock-values.py" ).read_text ()
73- exec (mock_value_str , glob , loc )
74- enum_collect = loc ["enum_collect" ]
75- value_collect = loc ["value_collect" ]
76- key_open = loc ["key_open" ]
77- hive_open = loc ["hive_open" ]
78-
79- def _e (key , at ):
80- key_id = key .value if isinstance (key , Key ) else key
81- result = enum_collect [key_id ][at ]
82- if isinstance (result , OSError ):
83- raise result
84- return result
85-
86- mocker .patch .object (winreg , "EnumKey" , side_effect = _e )
87-
88- def _v (key , value_name ):
89- key_id = key .value if isinstance (key , Key ) else key
90- result = value_collect [key_id ][value_name ]
91- if isinstance (result , OSError ):
92- raise result
93- return result
94-
95- mocker .patch .object (winreg , "QueryValueEx" , side_effect = _v )
96-
97- class Key :
98- def __init__ (self , value ):
99- self .value = value
100-
101- def __enter__ (self ):
102- return self
103-
104- def __exit__ (self , exc_type , exc_val , exc_tb ): # noqa: U100
105- return None
106-
107- @contextmanager
108- def _o (* args ):
109- if len (args ) == 2 :
110- key , value = args
111- key_id = key .value if isinstance (key , Key ) else key
112- result = Key (key_open [key_id ][value ]) # this needs to be something that can be with-ed, so let's wrap it
113- elif len (args ) == 4 :
114- result = hive_open [args ]
115- else :
116- raise RuntimeError
117- value = result .value if isinstance (result , Key ) else result
118- if isinstance (value , OSError ):
119- raise value
120- yield result
121-
122- mocker .patch .object (winreg , "OpenKeyEx" , side_effect = _o )
123- mocker .patch ("os.path.exists" , return_value = True )
124-
125-
126- @pytest .fixture ()
127- def _collect_winreg_access (mocker ):
128- # noinspection PyUnresolvedReferences
129- from winreg import EnumKey , OpenKeyEx , QueryValueEx
130-
131- from virtualenv .discovery .windows .pep514 import winreg
132-
133- hive_open = {}
134- key_open = defaultdict (dict )
135-
136- @contextmanager
137- def _c (* args ):
138- res = None
139- key_id = id (args [0 ]) if len (args ) == 2 else None
140- try :
141- with OpenKeyEx (* args ) as c :
142- res = id (c )
143- yield c
144- except Exception as exception :
145- res = exception
146- raise exception
147- finally :
148- if len (args ) == 4 :
149- hive_open [args ] = res
150- elif len (args ) == 2 :
151- key_open [key_id ][args [1 ]] = res
152-
153- enum_collect = defaultdict (list )
154-
155- def _e (key , at ):
156- result = None
157- key_id = id (key )
158- try :
159- result = EnumKey (key , at )
160- return result
161- except Exception as exception :
162- result = exception
163- raise result
164- finally :
165- enum_collect [key_id ].append (result )
166-
167- value_collect = defaultdict (dict )
168-
169- def _v (key , value_name ):
170- result = None
171- key_id = id (key )
172- try :
173- result = QueryValueEx (key , value_name )
174- return result
175- except Exception as exception :
176- result = exception
177- raise result
178- finally :
179- value_collect [key_id ][value_name ] = result
180-
181- mocker .patch .object (winreg , "EnumKey" , side_effect = _e )
182- mocker .patch .object (winreg , "QueryValueEx" , side_effect = _v )
183- mocker .patch .object (winreg , "OpenKeyEx" , side_effect = _c )
184-
185- yield
186-
187- print ("" )
188- print (f"hive_open = { hive_open } " )
189- print (f"key_open = { dict (key_open .items ())} " )
190- print (f"value_collect = { dict (value_collect .items ())} " )
191- print (f"enum_collect = { dict (enum_collect .items ())} " )
0 commit comments