@@ -26,8 +26,8 @@ use crate::microsoft_store::find_microsoft_store_pythons;
26
26
#[ cfg( windows) ]
27
27
use crate :: py_launcher:: { registry_pythons, WindowsPython } ;
28
28
use crate :: virtualenv:: {
29
- conda_prefix_from_env , virtualenv_from_env, virtualenv_from_working_dir,
30
- virtualenv_python_executable,
29
+ conda_environment_from_env , virtualenv_from_env, virtualenv_from_working_dir,
30
+ virtualenv_python_executable, CondaEnvironmentKind ,
31
31
} ;
32
32
use crate :: { Interpreter , PythonVersion } ;
33
33
@@ -179,6 +179,8 @@ pub enum PythonSource {
179
179
ActiveEnvironment ,
180
180
/// A conda environment was active e.g. via `CONDA_PREFIX`
181
181
CondaPrefix ,
182
+ /// A base conda environment was active e.g. via `CONDA_PREFIX`
183
+ BaseCondaPrefix ,
182
184
/// An environment was discovered e.g. via `.venv`
183
185
DiscoveredEnvironment ,
184
186
/// An executable was found in the search path i.e. `PATH`
@@ -227,27 +229,27 @@ pub enum Error {
227
229
SourceNotAllowed ( PythonRequest , PythonSource , PythonPreference ) ,
228
230
}
229
231
230
- /// Lazily iterate over Python executables in mutable environments.
232
+ /// Lazily iterate over Python executables in mutable virtual environments.
231
233
///
232
234
/// The following sources are supported:
233
235
///
234
236
/// - Active virtual environment (via `VIRTUAL_ENV`)
235
- /// - Active conda environment (via `CONDA_PREFIX`)
236
237
/// - Discovered virtual environment (e.g. `.venv` in a parent directory)
237
238
///
238
239
/// Notably, "system" environments are excluded. See [`python_executables_from_installed`].
239
- fn python_executables_from_environments < ' a > (
240
+ fn python_executables_from_virtual_environments < ' a > (
240
241
) -> impl Iterator < Item = Result < ( PythonSource , PathBuf ) , Error > > + ' a {
241
- let from_virtual_environment = std:: iter:: once_with ( || {
242
+ let from_active_environment = std:: iter:: once_with ( || {
242
243
virtualenv_from_env ( )
243
244
. into_iter ( )
244
245
. map ( virtualenv_python_executable)
245
246
. map ( |path| Ok ( ( PythonSource :: ActiveEnvironment , path) ) )
246
247
} )
247
248
. flatten ( ) ;
248
249
250
+ // N.B. we prefer the conda environment over discovered virtual environments
249
251
let from_conda_environment = std:: iter:: once_with ( || {
250
- conda_prefix_from_env ( )
252
+ conda_environment_from_env ( CondaEnvironmentKind :: Child )
251
253
. into_iter ( )
252
254
. map ( virtualenv_python_executable)
253
255
. map ( |path| Ok ( ( PythonSource :: CondaPrefix , path) ) )
@@ -265,7 +267,7 @@ fn python_executables_from_environments<'a>(
265
267
} )
266
268
. flatten_ok ( ) ;
267
269
268
- from_virtual_environment
270
+ from_active_environment
269
271
. chain ( from_conda_environment)
270
272
. chain ( from_discovered_environment)
271
273
}
@@ -400,23 +402,35 @@ fn python_executables<'a>(
400
402
} )
401
403
. flatten ( ) ;
402
404
403
- let from_environments = python_executables_from_environments ( ) ;
405
+ // Check if the the base conda environment is active
406
+ let from_base_conda_environment = std:: iter:: once_with ( || {
407
+ conda_environment_from_env ( CondaEnvironmentKind :: Base )
408
+ . into_iter ( )
409
+ . map ( virtualenv_python_executable)
410
+ . map ( |path| Ok ( ( PythonSource :: BaseCondaPrefix , path) ) )
411
+ } )
412
+ . flatten ( ) ;
413
+
414
+ let from_virtual_environments = python_executables_from_virtual_environments ( ) ;
404
415
let from_installed = python_executables_from_installed ( version, implementation, preference) ;
405
416
406
417
// Limit the search to the relevant environment preference; we later validate that they match
407
418
// the preference but queries are expensive and we query less interpreters this way.
408
419
match environments {
409
420
EnvironmentPreference :: OnlyVirtual => {
410
- Box :: new ( from_parent_interpreter. chain ( from_environments ) )
421
+ Box :: new ( from_parent_interpreter. chain ( from_virtual_environments ) )
411
422
}
412
423
EnvironmentPreference :: ExplicitSystem | EnvironmentPreference :: Any => Box :: new (
413
424
from_parent_interpreter
414
- . chain ( from_environments)
425
+ . chain ( from_virtual_environments)
426
+ . chain ( from_base_conda_environment)
427
+ . chain ( from_installed) ,
428
+ ) ,
429
+ EnvironmentPreference :: OnlySystem => Box :: new (
430
+ from_parent_interpreter
431
+ . chain ( from_base_conda_environment)
415
432
. chain ( from_installed) ,
416
433
) ,
417
- EnvironmentPreference :: OnlySystem => {
418
- Box :: new ( from_parent_interpreter. chain ( from_installed) )
419
- }
420
434
}
421
435
}
422
436
@@ -611,8 +625,8 @@ fn satisfies_environment_preference(
611
625
) -> bool {
612
626
match (
613
627
preference,
614
- // Conda environments are not conformant virtual environments but we treat them as such
615
- interpreter. is_virtualenv ( ) || matches ! ( source, PythonSource :: CondaPrefix ) ,
628
+ // Conda environments are not conformant virtual environments but we treat them as such.
629
+ interpreter. is_virtualenv ( ) || ( matches ! ( source, PythonSource :: CondaPrefix ) ) ,
616
630
) {
617
631
( EnvironmentPreference :: Any , _) => true ,
618
632
( EnvironmentPreference :: OnlyVirtual , true ) => true ,
@@ -1493,6 +1507,7 @@ impl PythonSource {
1493
1507
Self :: Managed | Self :: Registry | Self :: MicrosoftStore => false ,
1494
1508
Self :: SearchPath
1495
1509
| Self :: CondaPrefix
1510
+ | Self :: BaseCondaPrefix
1496
1511
| Self :: ProvidedPath
1497
1512
| Self :: ParentInterpreter
1498
1513
| Self :: ActiveEnvironment
@@ -1505,6 +1520,7 @@ impl PythonSource {
1505
1520
match self {
1506
1521
Self :: Managed | Self :: Registry | Self :: SearchPath | Self :: MicrosoftStore => false ,
1507
1522
Self :: CondaPrefix
1523
+ | Self :: BaseCondaPrefix
1508
1524
| Self :: ProvidedPath
1509
1525
| Self :: ParentInterpreter
1510
1526
| Self :: ActiveEnvironment
@@ -1826,6 +1842,7 @@ impl VersionRequest {
1826
1842
Self :: Default => match source {
1827
1843
PythonSource :: ParentInterpreter
1828
1844
| PythonSource :: CondaPrefix
1845
+ | PythonSource :: BaseCondaPrefix
1829
1846
| PythonSource :: ProvidedPath
1830
1847
| PythonSource :: DiscoveredEnvironment
1831
1848
| PythonSource :: ActiveEnvironment => Self :: Any ,
@@ -2217,7 +2234,7 @@ impl fmt::Display for PythonSource {
2217
2234
match self {
2218
2235
Self :: ProvidedPath => f. write_str ( "provided path" ) ,
2219
2236
Self :: ActiveEnvironment => f. write_str ( "active virtual environment" ) ,
2220
- Self :: CondaPrefix => f. write_str ( "conda prefix" ) ,
2237
+ Self :: CondaPrefix | Self :: BaseCondaPrefix => f. write_str ( "conda prefix" ) ,
2221
2238
Self :: DiscoveredEnvironment => f. write_str ( "virtual environment" ) ,
2222
2239
Self :: SearchPath => f. write_str ( "search path" ) ,
2223
2240
Self :: Registry => f. write_str ( "registry" ) ,
0 commit comments