@@ -29,7 +29,7 @@ use crate::managed::ManagedPythonInstallations;
29
29
use crate :: microsoft_store:: find_microsoft_store_pythons;
30
30
use crate :: virtualenv:: Error as VirtualEnvError ;
31
31
use crate :: virtualenv:: {
32
- conda_environment_from_env, virtualenv_from_env , virtualenv_from_working_dir ,
32
+ conda_environment_from_env, virtualenv_from_dir , virtualenv_from_env ,
33
33
virtualenv_python_executable, CondaEnvironmentKind ,
34
34
} ;
35
35
#[ cfg( windows) ]
@@ -250,8 +250,9 @@ pub enum Error {
250
250
/// - Discovered virtual environment (e.g. `.venv` in a parent directory)
251
251
///
252
252
/// Notably, "system" environments are excluded. See [`python_executables_from_installed`].
253
- fn python_executables_from_virtual_environments < ' a > (
254
- ) -> impl Iterator < Item = Result < ( PythonSource , PathBuf ) , Error > > + ' a {
253
+ fn python_executables_from_virtual_environments (
254
+ discovery_root : & Path ,
255
+ ) -> impl Iterator < Item = Result < ( PythonSource , PathBuf ) , Error > > + ' _ {
255
256
let from_active_environment = iter:: once_with ( || {
256
257
virtualenv_from_env ( )
257
258
. into_iter ( )
@@ -269,8 +270,8 @@ fn python_executables_from_virtual_environments<'a>(
269
270
} )
270
271
. flatten ( ) ;
271
272
272
- let from_discovered_environment = iter:: once_with ( || {
273
- virtualenv_from_working_dir ( )
273
+ let from_discovered_environment = iter:: once_with ( move || {
274
+ virtualenv_from_dir ( discovery_root )
274
275
. map ( |path| {
275
276
path. map ( virtualenv_python_executable)
276
277
. map ( |path| ( PythonSource :: DiscoveredEnvironment , path) )
@@ -420,6 +421,7 @@ fn python_executables<'a>(
420
421
implementation : Option < & ' a ImplementationName > ,
421
422
environments : EnvironmentPreference ,
422
423
preference : PythonPreference ,
424
+ discovery_root : & ' a Path ,
423
425
) -> Box < dyn Iterator < Item = Result < ( PythonSource , PathBuf ) , Error > > + ' a > {
424
426
// Always read from `UV_INTERNAL__PARENT_INTERPRETER` — it could be a system interpreter
425
427
let from_parent_interpreter = iter:: once_with ( || {
@@ -438,7 +440,7 @@ fn python_executables<'a>(
438
440
} )
439
441
. flatten ( ) ;
440
442
441
- let from_virtual_environments = python_executables_from_virtual_environments ( ) ;
443
+ let from_virtual_environments = python_executables_from_virtual_environments ( discovery_root ) ;
442
444
let from_installed = python_executables_from_installed ( version, implementation, preference) ;
443
445
444
446
// Limit the search to the relevant environment preference; this avoids unnecessary work like
@@ -615,16 +617,22 @@ fn python_interpreters<'a>(
615
617
environments : EnvironmentPreference ,
616
618
preference : PythonPreference ,
617
619
cache : & ' a Cache ,
620
+ discovery_root : & ' a Path ,
618
621
) -> impl Iterator < Item = Result < ( PythonSource , Interpreter ) , Error > > + ' a {
619
622
python_interpreters_from_executables (
620
623
// Perform filtering on the discovered executables based on their source. This avoids
621
624
// unnecessary interpreter queries, which are generally expensive. We'll filter again
622
625
// with `interpreter_satisfies_environment_preference` after querying.
623
- python_executables ( version, implementation, environments, preference) . filter_ok (
624
- move |( source, path) | {
625
- source_satisfies_environment_preference ( * source, path, environments)
626
- } ,
627
- ) ,
626
+ python_executables (
627
+ version,
628
+ implementation,
629
+ environments,
630
+ preference,
631
+ discovery_root,
632
+ )
633
+ . filter_ok ( move |( source, path) | {
634
+ source_satisfies_environment_preference ( * source, path, environments)
635
+ } ) ,
628
636
cache,
629
637
)
630
638
. filter_ok ( move |( source, interpreter) | {
@@ -862,6 +870,7 @@ pub fn find_python_installations<'a>(
862
870
environments : EnvironmentPreference ,
863
871
preference : PythonPreference ,
864
872
cache : & ' a Cache ,
873
+ discovery_root : & ' a Path ,
865
874
) -> Box < dyn Iterator < Item = Result < FindPythonResult , Error > > + ' a > {
866
875
let sources = DiscoveryPreferences {
867
876
python_preference : preference,
@@ -942,8 +951,15 @@ pub fn find_python_installations<'a>(
942
951
}
943
952
PythonRequest :: Any => Box :: new ( {
944
953
debug ! ( "Searching for any Python interpreter in {sources}" ) ;
945
- python_interpreters ( & VersionRequest :: Any , None , environments, preference, cache)
946
- . map_ok ( |tuple| Ok ( PythonInstallation :: from_tuple ( tuple) ) )
954
+ python_interpreters (
955
+ & VersionRequest :: Any ,
956
+ None ,
957
+ environments,
958
+ preference,
959
+ cache,
960
+ discovery_root,
961
+ )
962
+ . map_ok ( |tuple| Ok ( PythonInstallation :: from_tuple ( tuple) ) )
947
963
} ) ,
948
964
PythonRequest :: Default => Box :: new ( {
949
965
debug ! ( "Searching for default Python interpreter in {sources}" ) ;
@@ -953,6 +969,7 @@ pub fn find_python_installations<'a>(
953
969
environments,
954
970
preference,
955
971
cache,
972
+ discovery_root,
956
973
)
957
974
. map_ok ( |tuple| Ok ( PythonInstallation :: from_tuple ( tuple) ) )
958
975
} ) ,
@@ -962,8 +979,15 @@ pub fn find_python_installations<'a>(
962
979
} ;
963
980
Box :: new ( {
964
981
debug ! ( "Searching for {request} in {sources}" ) ;
965
- python_interpreters ( version, None , environments, preference, cache)
966
- . map_ok ( |tuple| Ok ( PythonInstallation :: from_tuple ( tuple) ) )
982
+ python_interpreters (
983
+ version,
984
+ None ,
985
+ environments,
986
+ preference,
987
+ cache,
988
+ discovery_root,
989
+ )
990
+ . map_ok ( |tuple| Ok ( PythonInstallation :: from_tuple ( tuple) ) )
967
991
} )
968
992
}
969
993
PythonRequest :: Implementation ( implementation) => Box :: new ( {
@@ -974,6 +998,7 @@ pub fn find_python_installations<'a>(
974
998
environments,
975
999
preference,
976
1000
cache,
1001
+ discovery_root,
977
1002
)
978
1003
. filter_ok ( |( _source, interpreter) | {
979
1004
interpreter
@@ -994,6 +1019,7 @@ pub fn find_python_installations<'a>(
994
1019
environments,
995
1020
preference,
996
1021
cache,
1022
+ discovery_root,
997
1023
)
998
1024
. filter_ok ( |( _source, interpreter) | {
999
1025
interpreter
@@ -1017,6 +1043,7 @@ pub fn find_python_installations<'a>(
1017
1043
environments,
1018
1044
preference,
1019
1045
cache,
1046
+ discovery_root,
1020
1047
)
1021
1048
. filter_ok ( |( _source, interpreter) | request. satisfied_by_interpreter ( interpreter) )
1022
1049
. map_ok ( |tuple| Ok ( PythonInstallation :: from_tuple ( tuple) ) )
@@ -1034,8 +1061,10 @@ pub(crate) fn find_python_installation(
1034
1061
environments : EnvironmentPreference ,
1035
1062
preference : PythonPreference ,
1036
1063
cache : & Cache ,
1064
+ discovery_root : & Path ,
1037
1065
) -> Result < FindPythonResult , Error > {
1038
- let installations = find_python_installations ( request, environments, preference, cache) ;
1066
+ let installations =
1067
+ find_python_installations ( request, environments, preference, cache, discovery_root) ;
1039
1068
let mut first_prerelease = None ;
1040
1069
let mut first_error = None ;
1041
1070
for result in installations {
@@ -1136,7 +1165,13 @@ pub fn find_best_python_installation(
1136
1165
1137
1166
// First, check for an exact match (or the first available version if no Python version was provided)
1138
1167
debug ! ( "Looking for exact match for request {request}" ) ;
1139
- let result = find_python_installation ( request, environments, preference, cache) ;
1168
+ let result = find_python_installation (
1169
+ request,
1170
+ environments,
1171
+ preference,
1172
+ cache,
1173
+ crate :: current_dir ( ) ?. as_path ( ) ,
1174
+ ) ;
1140
1175
match result {
1141
1176
Ok ( Ok ( installation) ) => {
1142
1177
warn_on_unsupported_python ( installation. interpreter ( ) ) ;
@@ -1164,7 +1199,13 @@ pub fn find_best_python_installation(
1164
1199
_ => None ,
1165
1200
} {
1166
1201
debug ! ( "Looking for relaxed patch version {request}" ) ;
1167
- let result = find_python_installation ( & request, environments, preference, cache) ;
1202
+ let result = find_python_installation (
1203
+ & request,
1204
+ environments,
1205
+ preference,
1206
+ cache,
1207
+ crate :: current_dir ( ) ?. as_path ( ) ,
1208
+ ) ;
1168
1209
match result {
1169
1210
Ok ( Ok ( installation) ) => {
1170
1211
warn_on_unsupported_python ( installation. interpreter ( ) ) ;
@@ -1180,16 +1221,21 @@ pub fn find_best_python_installation(
1180
1221
// If a Python version was requested but cannot be fulfilled, just take any version
1181
1222
debug ! ( "Looking for a default Python installation" ) ;
1182
1223
let request = PythonRequest :: Default ;
1183
- Ok (
1184
- find_python_installation ( & request, environments, preference, cache) ?. map_err ( |err| {
1185
- // Use a more general error in this case since we looked for multiple versions
1186
- PythonNotFound {
1187
- request,
1188
- python_preference : err. python_preference ,
1189
- environment_preference : err. environment_preference ,
1190
- }
1191
- } ) ,
1192
- )
1224
+ Ok ( find_python_installation (
1225
+ & request,
1226
+ environments,
1227
+ preference,
1228
+ cache,
1229
+ crate :: current_dir ( ) ?. as_path ( ) ,
1230
+ ) ?
1231
+ . map_err ( |err| {
1232
+ // Use a more general error in this case since we looked for multiple versions
1233
+ PythonNotFound {
1234
+ request,
1235
+ python_preference : err. python_preference ,
1236
+ environment_preference : err. environment_preference ,
1237
+ }
1238
+ } ) )
1193
1239
}
1194
1240
1195
1241
/// Display a warning if the Python version of the [`Interpreter`] is unsupported by uv.
0 commit comments