@@ -63,23 +63,6 @@ pub(crate) async fn query_python_info(python: &Path) -> Result<PythonInfo> {
6363 } )
6464}
6565
66- fn to_uv_python_request ( request : & LanguageRequest ) -> Option < String > {
67- match request {
68- LanguageRequest :: Any => None ,
69- LanguageRequest :: Python ( request) => match request {
70- PythonRequest :: Any => None ,
71- PythonRequest :: Major ( major) => Some ( format ! ( "{major}" ) ) ,
72- PythonRequest :: MajorMinor ( major, minor) => Some ( format ! ( "{major}.{minor}" ) ) ,
73- PythonRequest :: MajorMinorPatch ( major, minor, patch) => {
74- Some ( format ! ( "{major}.{minor}.{patch}" ) )
75- }
76- PythonRequest :: Range ( _, raw) => Some ( raw. clone ( ) ) ,
77- PythonRequest :: Path ( path) => Some ( path. to_string_lossy ( ) . to_string ( ) ) ,
78- } ,
79- _ => unreachable ! ( ) ,
80- }
81- }
82-
8366impl LanguageImpl for Python {
8467 async fn install (
8568 & self ,
@@ -102,10 +85,8 @@ impl LanguageImpl for Python {
10285
10386 debug ! ( %hook, target = %info. env_path. display( ) , "Installing environment" ) ;
10487
105- let python_request = to_uv_python_request ( & hook. language_request ) ;
106-
10788 // Create venv (auto download Python if needed)
108- Self :: create_venv_with_retry ( & uv, store, & info, python_request . as_ref ( ) )
89+ Self :: create_venv ( & uv, store, & info, & hook . language_request )
10990 . await
11091 . context ( "Failed to create Python virtual environment" ) ?;
11192
@@ -223,12 +204,29 @@ impl LanguageImpl for Python {
223204 }
224205}
225206
207+ fn to_uv_python_request ( request : & LanguageRequest ) -> Option < String > {
208+ match request {
209+ LanguageRequest :: Any { .. } => None ,
210+ LanguageRequest :: Python ( request) => match request {
211+ PythonRequest :: Any => None ,
212+ PythonRequest :: Major ( major) => Some ( format ! ( "{major}" ) ) ,
213+ PythonRequest :: MajorMinor ( major, minor) => Some ( format ! ( "{major}.{minor}" ) ) ,
214+ PythonRequest :: MajorMinorPatch ( major, minor, patch) => {
215+ Some ( format ! ( "{major}.{minor}.{patch}" ) )
216+ }
217+ PythonRequest :: Range ( _, raw) => Some ( raw. clone ( ) ) ,
218+ PythonRequest :: Path ( path) => Some ( path. to_string_lossy ( ) . to_string ( ) ) ,
219+ } ,
220+ _ => unreachable ! ( ) ,
221+ }
222+ }
223+
226224impl Python {
227- async fn create_venv_with_retry (
225+ async fn create_venv (
228226 uv : & Uv ,
229227 store : & Store ,
230228 info : & InstallInfo ,
231- python_request : Option < & String > ,
229+ python_request : & LanguageRequest ,
232230 ) -> Result < ( ) > {
233231 // Try creating venv without downloads first
234232 match Self :: create_venv_command ( uv, store, info, python_request, false , false )
@@ -246,6 +244,12 @@ impl Python {
246244 Err ( e @ process:: Error :: Status { .. } ) => {
247245 // Check if we can retry with downloads
248246 if Self :: can_retry_with_downloads ( & e) {
247+ if !python_request. allows_download ( ) {
248+ anyhow:: bail!(
249+ "No suitable system Python version found and downloads are disabled"
250+ ) ;
251+ }
252+
249253 debug ! (
250254 "Retrying venv creation with managed Python downloads: `{}`" ,
251255 info. env_path. display( )
@@ -270,7 +274,7 @@ impl Python {
270274 uv : & Uv ,
271275 store : & Store ,
272276 info : & InstallInfo ,
273- python_request : Option < & String > ,
277+ python_request : & LanguageRequest ,
274278 set_install_dir : bool ,
275279 allow_downloads : bool ,
276280 ) -> Cmd {
@@ -297,7 +301,7 @@ impl Python {
297301 cmd. arg ( "--no-python-downloads" ) ;
298302 }
299303
300- if let Some ( python) = python_request {
304+ if let Some ( python) = to_uv_python_request ( python_request) {
301305 cmd. arg ( "--python" ) . arg ( python) ;
302306 }
303307
0 commit comments