99
1010from platformdirs import user_data_path
1111
12+ from virtualenv .info import IS_WIN , fs_path_id
13+
1214from .discover import Discover
13- from .info import IS_WIN , fs_path_id
1415from .py_info import PythonInfo
1516from .py_spec import PythonSpec
1617
1718if TYPE_CHECKING :
1819 from argparse import ArgumentParser
1920 from collections .abc import Callable , Generator , Iterable , Mapping , Sequence
2021
21- from .app_data import AppData
22+ from virtualenv .app_data . base import AppData
2223LOGGER = logging .getLogger (__name__ )
2324
2425
@@ -27,8 +28,8 @@ class Builtin(Discover):
2728 app_data : AppData
2829 try_first_with : Sequence [str ]
2930
30- def __init__ (self , options , cache = None ) -> None :
31- super ().__init__ (options , cache )
31+ def __init__ (self , options ) -> None :
32+ super ().__init__ (options )
3233 self .python_spec = options .python or [sys .executable ]
3334 if self ._env .get ("VIRTUALENV_PYTHON" ):
3435 self .python_spec = self .python_spec [1 :] + self .python_spec [:1 ] # Rotate the list
@@ -60,7 +61,7 @@ def add_parser_arguments(cls, parser: ArgumentParser) -> None:
6061
6162 def run (self ) -> PythonInfo | None :
6263 for python_spec in self .python_spec :
63- result = get_interpreter (python_spec , self .try_first_with , self .app_data , self .cache , self . _env )
64+ result = get_interpreter (python_spec , self .try_first_with , self .app_data , self ._env )
6465 if result is not None :
6566 return result
6667 return None
@@ -71,36 +72,13 @@ def __repr__(self) -> str:
7172
7273
7374def get_interpreter (
74- key ,
75- try_first_with : Iterable [str ],
76- app_data : AppData | None = None ,
77- cache = None ,
78- env : Mapping [str , str ] | None = None ,
75+ key , try_first_with : Iterable [str ], app_data : AppData | None = None , env : Mapping [str , str ] | None = None
7976) -> PythonInfo | None :
80- """
81- Find an interpreter that matches a given specification.
82-
83- :param key: the specification of the interpreter to find
84- :param try_first_with: a list of interpreters to try first
85- :param app_data: the application data folder
86- :param cache: a cache of python information
87- :param env: the environment to use
88- :return: the interpreter if found, otherwise None
89- """
90- if cache is None :
91- # Import locally to avoid a circular dependency
92- from virtualenv .app_data import AppDataDisabled # noqa: PLC0415
93- from virtualenv .cache import FileCache # noqa: PLC0415
94-
95- if app_data is None :
96- app_data = AppDataDisabled ()
97- cache = FileCache (store_factory = app_data .py_info , clearer = app_data .py_info_clear )
98-
9977 spec = PythonSpec .from_string_spec (key )
10078 LOGGER .info ("find interpreter for spec %r" , spec )
10179 proposed_paths = set ()
10280 env = os .environ if env is None else env
103- for interpreter , impl_must_match in propose_interpreters (spec , try_first_with , app_data , cache , env ):
81+ for interpreter , impl_must_match in propose_interpreters (spec , try_first_with , app_data , env ):
10482 key = interpreter .system_executable , impl_must_match
10583 if key in proposed_paths :
10684 continue
@@ -116,7 +94,6 @@ def propose_interpreters( # noqa: C901, PLR0912, PLR0915
11694 spec : PythonSpec ,
11795 try_first_with : Iterable [str ],
11896 app_data : AppData | None = None ,
119- cache = None ,
12097 env : Mapping [str , str ] | None = None ,
12198) -> Generator [tuple [PythonInfo , bool ], None , None ]:
12299 # 0. if it's a path and exists, and is absolute path, this is the only option we consider
@@ -132,7 +109,7 @@ def propose_interpreters( # noqa: C901, PLR0912, PLR0915
132109 exe_id = fs_path_id (exe_raw )
133110 if exe_id not in tested_exes :
134111 tested_exes .add (exe_id )
135- yield PythonInfo .from_exe (exe_raw , app_data , cache , env = env ), True
112+ yield PythonInfo .from_exe (exe_raw , app_data , env = env ), True
136113 return
137114
138115 # 1. try with first
@@ -148,7 +125,7 @@ def propose_interpreters( # noqa: C901, PLR0912, PLR0915
148125 if exe_id in tested_exes :
149126 continue
150127 tested_exes .add (exe_id )
151- yield PythonInfo .from_exe (exe_raw , app_data , cache , env = env ), True
128+ yield PythonInfo .from_exe (exe_raw , app_data , env = env ), True
152129
153130 # 1. if it's a path and exists
154131 if spec .path is not None :
@@ -161,12 +138,12 @@ def propose_interpreters( # noqa: C901, PLR0912, PLR0915
161138 exe_id = fs_path_id (exe_raw )
162139 if exe_id not in tested_exes :
163140 tested_exes .add (exe_id )
164- yield PythonInfo .from_exe (exe_raw , app_data , cache , env = env ), True
141+ yield PythonInfo .from_exe (exe_raw , app_data , env = env ), True
165142 if spec .is_abs :
166143 return
167144 else :
168145 # 2. otherwise try with the current
169- current_python = PythonInfo .current_system (app_data , cache )
146+ current_python = PythonInfo .current_system (app_data )
170147 exe_raw = str (current_python .executable )
171148 exe_id = fs_path_id (exe_raw )
172149 if exe_id not in tested_exes :
@@ -177,7 +154,7 @@ def propose_interpreters( # noqa: C901, PLR0912, PLR0915
177154 if IS_WIN :
178155 from .windows import propose_interpreters # noqa: PLC0415
179156
180- for interpreter in propose_interpreters (spec , app_data , cache , env ):
157+ for interpreter in propose_interpreters (spec , app_data , env ):
181158 exe_raw = str (interpreter .executable )
182159 exe_id = fs_path_id (exe_raw )
183160 if exe_id in tested_exes :
@@ -195,7 +172,7 @@ def propose_interpreters( # noqa: C901, PLR0912, PLR0915
195172 if exe_id in tested_exes :
196173 continue
197174 tested_exes .add (exe_id )
198- interpreter = PathPythonInfo .from_exe (exe_raw , app_data , cache , raise_on_error = False , env = env )
175+ interpreter = PathPythonInfo .from_exe (exe_raw , app_data , raise_on_error = False , env = env )
199176 if interpreter is not None :
200177 yield interpreter , impl_must_match
201178
@@ -208,7 +185,7 @@ def propose_interpreters( # noqa: C901, PLR0912, PLR0915
208185 uv_python_path = user_data_path ("uv" ) / "python"
209186
210187 for exe_path in uv_python_path .glob ("*/bin/python" ):
211- interpreter = PathPythonInfo .from_exe (str (exe_path ), app_data , cache , raise_on_error = False , env = env )
188+ interpreter = PathPythonInfo .from_exe (str (exe_path ), app_data , raise_on_error = False , env = env )
212189 if interpreter is not None :
213190 yield interpreter , True
214191
0 commit comments