@@ -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
@@ -185,6 +185,8 @@ pub enum PythonSource {
185
185
ActiveEnvironment ,
186
186
/// A conda environment was active e.g. via `CONDA_PREFIX`
187
187
CondaPrefix ,
188
+ /// A base conda environment was active e.g. via `CONDA_PREFIX`
189
+ BaseCondaPrefix ,
188
190
/// An environment was discovered e.g. via `.venv`
189
191
DiscoveredEnvironment ,
190
192
/// An executable was found in the search path i.e. `PATH`
@@ -233,27 +235,27 @@ pub enum Error {
233
235
SourceNotAllowed ( PythonRequest , PythonSource , PythonPreference ) ,
234
236
}
235
237
236
- /// Lazily iterate over Python executables in mutable environments.
238
+ /// Lazily iterate over Python executables in mutable virtual environments.
237
239
///
238
240
/// The following sources are supported:
239
241
///
240
242
/// - Active virtual environment (via `VIRTUAL_ENV`)
241
- /// - Active conda environment (via `CONDA_PREFIX`)
242
243
/// - Discovered virtual environment (e.g. `.venv` in a parent directory)
243
244
///
244
245
/// Notably, "system" environments are excluded. See [`python_executables_from_installed`].
245
- fn python_executables_from_environments < ' a > (
246
+ fn python_executables_from_virtual_environments < ' a > (
246
247
) -> impl Iterator < Item = Result < ( PythonSource , PathBuf ) , Error > > + ' a {
247
- let from_virtual_environment = std:: iter:: once_with ( || {
248
+ let from_active_environment = std:: iter:: once_with ( || {
248
249
virtualenv_from_env ( )
249
250
. into_iter ( )
250
251
. map ( virtualenv_python_executable)
251
252
. map ( |path| Ok ( ( PythonSource :: ActiveEnvironment , path) ) )
252
253
} )
253
254
. flatten ( ) ;
254
255
256
+ // N.B. we prefer the conda environment over discovered virtual environments
255
257
let from_conda_environment = std:: iter:: once_with ( || {
256
- conda_prefix_from_env ( )
258
+ conda_environment_from_env ( CondaEnvironmentKind :: Child )
257
259
. into_iter ( )
258
260
. map ( virtualenv_python_executable)
259
261
. map ( |path| Ok ( ( PythonSource :: CondaPrefix , path) ) )
@@ -271,7 +273,7 @@ fn python_executables_from_environments<'a>(
271
273
} )
272
274
. flatten_ok ( ) ;
273
275
274
- from_virtual_environment
276
+ from_active_environment
275
277
. chain ( from_conda_environment)
276
278
. chain ( from_discovered_environment)
277
279
}
@@ -406,23 +408,35 @@ fn python_executables<'a>(
406
408
} )
407
409
. flatten ( ) ;
408
410
409
- let from_environments = python_executables_from_environments ( ) ;
411
+ // Check if the the base conda environment is active
412
+ let from_base_conda_environment = std:: iter:: once_with ( || {
413
+ conda_environment_from_env ( CondaEnvironmentKind :: Base )
414
+ . into_iter ( )
415
+ . map ( virtualenv_python_executable)
416
+ . map ( |path| Ok ( ( PythonSource :: BaseCondaPrefix , path) ) )
417
+ } )
418
+ . flatten ( ) ;
419
+
420
+ let from_virtual_environments = python_executables_from_virtual_environments ( ) ;
410
421
let from_installed = python_executables_from_installed ( version, implementation, preference) ;
411
422
412
423
// Limit the search to the relevant environment preference; we later validate that they match
413
424
// the preference but queries are expensive and we query less interpreters this way.
414
425
match environments {
415
426
EnvironmentPreference :: OnlyVirtual => {
416
- Box :: new ( from_parent_interpreter. chain ( from_environments ) )
427
+ Box :: new ( from_parent_interpreter. chain ( from_virtual_environments ) )
417
428
}
418
429
EnvironmentPreference :: ExplicitSystem | EnvironmentPreference :: Any => Box :: new (
419
430
from_parent_interpreter
420
- . chain ( from_environments)
431
+ . chain ( from_virtual_environments)
432
+ . chain ( from_base_conda_environment)
433
+ . chain ( from_installed) ,
434
+ ) ,
435
+ EnvironmentPreference :: OnlySystem => Box :: new (
436
+ from_parent_interpreter
437
+ . chain ( from_base_conda_environment)
421
438
. chain ( from_installed) ,
422
439
) ,
423
- EnvironmentPreference :: OnlySystem => {
424
- Box :: new ( from_parent_interpreter. chain ( from_installed) )
425
- }
426
440
}
427
441
}
428
442
@@ -617,8 +631,8 @@ fn satisfies_environment_preference(
617
631
) -> bool {
618
632
match (
619
633
preference,
620
- // Conda environments are not conformant virtual environments but we treat them as such
621
- interpreter. is_virtualenv ( ) || matches ! ( source, PythonSource :: CondaPrefix ) ,
634
+ // Conda environments are not conformant virtual environments but we treat them as such.
635
+ interpreter. is_virtualenv ( ) || ( matches ! ( source, PythonSource :: CondaPrefix ) ) ,
622
636
) {
623
637
( EnvironmentPreference :: Any , _) => true ,
624
638
( EnvironmentPreference :: OnlyVirtual , true ) => true ,
@@ -1515,6 +1529,7 @@ impl PythonSource {
1515
1529
Self :: Managed | Self :: Registry | Self :: MicrosoftStore => false ,
1516
1530
Self :: SearchPath
1517
1531
| Self :: CondaPrefix
1532
+ | Self :: BaseCondaPrefix
1518
1533
| Self :: ProvidedPath
1519
1534
| Self :: ParentInterpreter
1520
1535
| Self :: ActiveEnvironment
@@ -1527,6 +1542,7 @@ impl PythonSource {
1527
1542
match self {
1528
1543
Self :: Managed | Self :: Registry | Self :: SearchPath | Self :: MicrosoftStore => false ,
1529
1544
Self :: CondaPrefix
1545
+ | Self :: BaseCondaPrefix
1530
1546
| Self :: ProvidedPath
1531
1547
| Self :: ParentInterpreter
1532
1548
| Self :: ActiveEnvironment
@@ -1846,6 +1862,7 @@ impl VersionRequest {
1846
1862
Self :: Default => match source {
1847
1863
PythonSource :: ParentInterpreter
1848
1864
| PythonSource :: CondaPrefix
1865
+ | PythonSource :: BaseCondaPrefix
1849
1866
| PythonSource :: ProvidedPath
1850
1867
| PythonSource :: DiscoveredEnvironment
1851
1868
| PythonSource :: ActiveEnvironment => Self :: Any ,
@@ -2256,7 +2273,7 @@ impl fmt::Display for PythonSource {
2256
2273
match self {
2257
2274
Self :: ProvidedPath => f. write_str ( "provided path" ) ,
2258
2275
Self :: ActiveEnvironment => f. write_str ( "active virtual environment" ) ,
2259
- Self :: CondaPrefix => f. write_str ( "conda prefix" ) ,
2276
+ Self :: CondaPrefix | Self :: BaseCondaPrefix => f. write_str ( "conda prefix" ) ,
2260
2277
Self :: DiscoveredEnvironment => f. write_str ( "virtual environment" ) ,
2261
2278
Self :: SearchPath => f. write_str ( "search path" ) ,
2262
2279
Self :: Registry => f. write_str ( "registry" ) ,
0 commit comments