@@ -2,23 +2,60 @@ use anstream::println;
22use anyhow:: Result ;
33
44use uv_cache:: Cache ;
5- use uv_fs:: Simplified ;
6- use uv_python:: { EnvironmentPreference , PythonInstallation , PythonPreference , PythonRequest } ;
5+ use uv_fs:: { Simplified , CWD } ;
6+ use uv_python:: {
7+ EnvironmentPreference , PythonInstallation , PythonPreference , PythonRequest , PythonVersionFile ,
8+ VersionRequest ,
9+ } ;
10+ use uv_resolver:: RequiresPython ;
11+ use uv_warnings:: warn_user_once;
12+ use uv_workspace:: { DiscoveryOptions , VirtualProject , WorkspaceError } ;
713
8- use crate :: commands:: ExitStatus ;
14+ use crate :: commands:: { project :: find_requires_python , ExitStatus } ;
915
1016/// Find a Python interpreter.
1117pub ( crate ) async fn find (
1218 request : Option < String > ,
19+ no_project : bool ,
20+ no_config : bool ,
1321 python_preference : PythonPreference ,
1422 cache : & Cache ,
1523) -> Result < ExitStatus > {
16- let request = match request {
17- Some ( request) => PythonRequest :: parse ( & request) ,
18- None => PythonRequest :: Any ,
19- } ;
24+ // (1) Explicit request from user
25+ let mut request = request. map ( |request| PythonRequest :: parse ( & request) ) ;
26+
27+ // (2) Request from `.python-version`
28+ if request. is_none ( ) {
29+ request = PythonVersionFile :: discover ( & * CWD , no_config)
30+ . await ?
31+ . and_then ( PythonVersionFile :: into_version) ;
32+ }
33+
34+ // (3) `Requires-Python` in `pyproject.toml`
35+ if request. is_none ( ) && !no_project {
36+ let project = match VirtualProject :: discover ( & CWD , & DiscoveryOptions :: default ( ) ) . await {
37+ Ok ( project) => Some ( project) ,
38+ Err ( WorkspaceError :: MissingProject ( _) ) => None ,
39+ Err ( WorkspaceError :: MissingPyprojectToml ) => None ,
40+ Err ( WorkspaceError :: NonWorkspace ( _) ) => None ,
41+ Err ( err) => {
42+ warn_user_once ! ( "{err}" ) ;
43+ None
44+ }
45+ } ;
46+
47+ if let Some ( project) = project {
48+ request = find_requires_python ( project. workspace ( ) ) ?
49+ . as_ref ( )
50+ . map ( RequiresPython :: specifiers)
51+ . map ( |specifiers| {
52+ PythonRequest :: Version ( VersionRequest :: Range ( specifiers. clone ( ) ) )
53+ } ) ;
54+ }
55+ }
56+
2057 let python = PythonInstallation :: find (
21- & request,
58+ & request. unwrap_or_default ( ) ,
2259 EnvironmentPreference :: OnlySystem ,
2360 python_preference,
2461 cache,
0 commit comments