@@ -24,7 +24,7 @@ use crate::microsoft_store::find_microsoft_store_pythons;
24
24
#[ cfg( windows) ]
25
25
use crate :: py_launcher:: { registry_pythons, WindowsPython } ;
26
26
use crate :: virtualenv:: {
27
- conda_prefix_from_env , virtualenv_from_env, virtualenv_from_working_dir,
27
+ conda_environment_from_env , virtualenv_from_env, virtualenv_from_working_dir,
28
28
virtualenv_python_executable,
29
29
} ;
30
30
use crate :: which:: is_executable;
@@ -171,6 +171,8 @@ pub enum PythonSource {
171
171
ActiveEnvironment ,
172
172
/// A conda environment was active e.g. via `CONDA_PREFIX`
173
173
CondaPrefix ,
174
+ /// A base conda environment was active e.g. via `CONDA_PREFIX`
175
+ BaseCondaPrefix ,
174
176
/// An environment was discovered e.g. via `.venv`
175
177
DiscoveredEnvironment ,
176
178
/// An executable was found in the search path i.e. `PATH`
@@ -215,27 +217,27 @@ pub enum Error {
215
217
SourceNotAllowed ( PythonRequest , PythonSource , PythonPreference ) ,
216
218
}
217
219
218
- /// Lazily iterate over Python executables in mutable environments.
220
+ /// Lazily iterate over Python executables in mutable virtual environments.
219
221
///
220
222
/// The following sources are supported:
221
223
///
222
224
/// - Active virtual environment (via `VIRTUAL_ENV`)
223
- /// - Active conda environment (via `CONDA_PREFIX`)
224
225
/// - Discovered virtual environment (e.g. `.venv` in a parent directory)
225
226
///
226
227
/// Notably, "system" environments are excluded. See [`python_executables_from_installed`].
227
- fn python_executables_from_environments < ' a > (
228
+ fn python_executables_from_virtual_environments < ' a > (
228
229
) -> impl Iterator < Item = Result < ( PythonSource , PathBuf ) , Error > > + ' a {
229
- let from_virtual_environment = std:: iter:: once_with ( || {
230
+ let from_active_environment = std:: iter:: once_with ( || {
230
231
virtualenv_from_env ( )
231
232
. into_iter ( )
232
233
. map ( virtualenv_python_executable)
233
234
. map ( |path| Ok ( ( PythonSource :: ActiveEnvironment , path) ) )
234
235
} )
235
236
. flatten ( ) ;
236
237
238
+ // N.B. we prefer the conda environment over discovered virtual environments
237
239
let from_conda_environment = std:: iter:: once_with ( || {
238
- conda_prefix_from_env ( )
240
+ conda_environment_from_env ( false )
239
241
. into_iter ( )
240
242
. map ( virtualenv_python_executable)
241
243
. map ( |path| Ok ( ( PythonSource :: CondaPrefix , path) ) )
@@ -253,7 +255,7 @@ fn python_executables_from_environments<'a>(
253
255
} )
254
256
. flatten_ok ( ) ;
255
257
256
- from_virtual_environment
258
+ from_active_environment
257
259
. chain ( from_conda_environment)
258
260
. chain ( from_discovered_environment)
259
261
}
@@ -396,23 +398,35 @@ fn python_executables<'a>(
396
398
} )
397
399
. flatten ( ) ;
398
400
399
- let from_environments = python_executables_from_environments ( ) ;
401
+ // Check if the the base conda environment is active
402
+ let from_base_conda_environment = std:: iter:: once_with ( || {
403
+ conda_environment_from_env ( true )
404
+ . into_iter ( )
405
+ . map ( virtualenv_python_executable)
406
+ . map ( |path| Ok ( ( PythonSource :: BaseCondaPrefix , path) ) )
407
+ } )
408
+ . flatten ( ) ;
409
+
410
+ let from_virtual_environments = python_executables_from_virtual_environments ( ) ;
400
411
let from_installed = python_executables_from_installed ( version, implementation, preference) ;
401
412
402
413
// Limit the search to the relevant environment preference; we later validate that they match
403
414
// the preference but queries are expensive and we query less interpreters this way.
404
415
match environments {
405
416
EnvironmentPreference :: OnlyVirtual => {
406
- Box :: new ( from_parent_interpreter. chain ( from_environments ) )
417
+ Box :: new ( from_parent_interpreter. chain ( from_virtual_environments ) )
407
418
}
408
419
EnvironmentPreference :: ExplicitSystem | EnvironmentPreference :: Any => Box :: new (
409
420
from_parent_interpreter
410
- . chain ( from_environments)
421
+ . chain ( from_virtual_environments)
422
+ . chain ( from_base_conda_environment)
423
+ . chain ( from_installed) ,
424
+ ) ,
425
+ EnvironmentPreference :: OnlySystem => Box :: new (
426
+ from_parent_interpreter
427
+ . chain ( from_base_conda_environment)
411
428
. chain ( from_installed) ,
412
429
) ,
413
- EnvironmentPreference :: OnlySystem => {
414
- Box :: new ( from_parent_interpreter. chain ( from_installed) )
415
- }
416
430
}
417
431
}
418
432
@@ -607,8 +621,8 @@ fn satisfies_environment_preference(
607
621
) -> bool {
608
622
match (
609
623
preference,
610
- // Conda environments are not conformant virtual environments but we treat them as such
611
- interpreter. is_virtualenv ( ) || matches ! ( source, PythonSource :: CondaPrefix ) ,
624
+ // Conda environments are not conformant virtual environments but we treat them as such.
625
+ interpreter. is_virtualenv ( ) || ( matches ! ( source, PythonSource :: CondaPrefix ) ) ,
612
626
) {
613
627
( EnvironmentPreference :: Any , _) => true ,
614
628
( EnvironmentPreference :: OnlyVirtual , true ) => true ,
@@ -1458,6 +1472,7 @@ impl PythonSource {
1458
1472
Self :: Managed | Self :: Registry | Self :: MicrosoftStore => false ,
1459
1473
Self :: SearchPath
1460
1474
| Self :: CondaPrefix
1475
+ | Self :: BaseCondaPrefix
1461
1476
| Self :: ProvidedPath
1462
1477
| Self :: ParentInterpreter
1463
1478
| Self :: ActiveEnvironment
@@ -1470,6 +1485,7 @@ impl PythonSource {
1470
1485
match self {
1471
1486
Self :: Managed | Self :: Registry | Self :: SearchPath | Self :: MicrosoftStore => false ,
1472
1487
Self :: CondaPrefix
1488
+ | Self :: BaseCondaPrefix
1473
1489
| Self :: ProvidedPath
1474
1490
| Self :: ParentInterpreter
1475
1491
| Self :: ActiveEnvironment
@@ -2076,7 +2092,7 @@ impl fmt::Display for PythonSource {
2076
2092
match self {
2077
2093
Self :: ProvidedPath => f. write_str ( "provided path" ) ,
2078
2094
Self :: ActiveEnvironment => f. write_str ( "active virtual environment" ) ,
2079
- Self :: CondaPrefix => f. write_str ( "conda prefix" ) ,
2095
+ Self :: CondaPrefix | Self :: BaseCondaPrefix => f. write_str ( "conda prefix" ) ,
2080
2096
Self :: DiscoveredEnvironment => f. write_str ( "virtual environment" ) ,
2081
2097
Self :: SearchPath => f. write_str ( "search path" ) ,
2082
2098
Self :: Registry => f. write_str ( "registry" ) ,
0 commit comments