@@ -192,18 +192,25 @@ fn get_conda_env_name(
192192 // E.g. conda env is = <conda install>/envs/<env name>
193193 // Then we can use `<conda install>/bin/conda activate -n <env name>`
194194 //
195- // Check the history file when:
196- // 1. conda_dir is known but prefix is not under it (external environment)
197- // 2. conda_dir is unknown (we need to check history to determine if it's name or path based)
198- // This ensures path-based environments (created with --prefix) return None for name,
199- // so activation uses the full path instead of incorrectly trying name-based activation.
200- let should_check_history = match conda_dir {
201- Some ( dir) => !prefix. starts_with ( dir) ,
202- None => true ,
203- } ;
204-
205- if should_check_history {
206- name = get_conda_env_name_from_history_file ( env_path, prefix) ;
195+ // Handle three cases:
196+ // 1. conda_dir known, prefix is under it → name-based activation works, return folder name
197+ // 2. conda_dir known, prefix NOT under it → external env, check history to distinguish -n vs -p
198+ // 3. conda_dir unknown → can't do name-based activation without knowing conda installation,
199+ // return None so activation uses full path (fixes issue #329 for path-based envs)
200+ match conda_dir {
201+ Some ( dir) => {
202+ if !prefix. starts_with ( dir) {
203+ // External environment - check history to see if created with -n or -p
204+ name = get_conda_env_name_from_history_file ( env_path, prefix) ;
205+ }
206+ // else: env is under conda_dir/envs/, name-based activation works
207+ }
208+ None => {
209+ // No known conda installation directory
210+ // Name-based activation requires knowing which conda to use, so return None
211+ // This ensures path-based activation is used (correct for --prefix envs too)
212+ name = None ;
213+ }
207214 }
208215
209216 name
@@ -440,13 +447,37 @@ mod tests {
440447 ) ) ;
441448 }
442449
443- /// Test that path-based conda environments (created with --prefix) return None for name
444- /// when conda_dir is unknown. This ensures VS Code uses path-based activation.
445- /// Regression test for https://github.com/microsoft/python-environment-tools/issues/329
450+ /// Test that when conda_dir is unknown, we return None for name.
451+ /// This is correct because name-based activation requires knowing which conda installation
452+ /// to use. Without conda_dir, activation must use the full path.
453+ /// This also fixes issue #329 where path-based envs incorrectly got a name.
446454 #[ test]
447- fn path_based_env_returns_none_name_when_conda_dir_unknown ( ) {
448- // Create a temp directory structure simulating a path-based conda env
449- let temp_dir = std:: env:: temp_dir ( ) . join ( "pet_test_path_based_env" ) ;
455+ fn env_returns_none_name_when_conda_dir_unknown ( ) {
456+ // Create a temp directory structure simulating a conda env
457+ let temp_dir = std:: env:: temp_dir ( ) . join ( "pet_test_conda_dir_unknown" ) ;
458+ let conda_meta_dir = temp_dir. join ( "myenv" ) . join ( "conda-meta" ) ;
459+ std:: fs:: create_dir_all ( & conda_meta_dir) . unwrap ( ) ;
460+
461+ let env_path = temp_dir. join ( "myenv" ) ;
462+
463+ // When conda_dir is None, name should be None (can't do named activation)
464+ let name = get_conda_env_name ( & env_path, & env_path, & None ) ;
465+ assert ! (
466+ name. is_none( ) ,
467+ "When conda_dir is unknown, name should be None for path-based activation, got {:?}" ,
468+ name
469+ ) ;
470+
471+ // Cleanup
472+ let _ = std:: fs:: remove_dir_all ( & temp_dir) ;
473+ }
474+
475+ /// Test that external environments (not under conda_dir) created with --prefix
476+ /// return None for name, so activation uses path instead of name.
477+ #[ test]
478+ fn external_path_based_env_returns_none_name ( ) {
479+ // Create a temp directory simulating an external path-based conda env
480+ let temp_dir = std:: env:: temp_dir ( ) . join ( "pet_test_external_path_env" ) ;
450481 let conda_meta_dir = temp_dir. join ( ".conda" ) . join ( "conda-meta" ) ;
451482 std:: fs:: create_dir_all ( & conda_meta_dir) . unwrap ( ) ;
452483
@@ -459,25 +490,26 @@ mod tests {
459490 . unwrap ( ) ;
460491
461492 let env_path = temp_dir. join ( ".conda" ) ;
493+ // conda_dir is known but env is NOT under it (external environment)
494+ let conda_dir = Some ( std:: path:: PathBuf :: from ( "/some/other/conda" ) ) ;
462495
463- // When conda_dir is None and env was created with --prefix, name should be None
464- let name = get_conda_env_name ( & env_path, & env_path, & None ) ;
496+ let name = get_conda_env_name ( & env_path, & env_path, & conda_dir) ;
465497 assert ! (
466498 name. is_none( ) ,
467- "Path-based env should return None for name, got {:?}" ,
499+ "Path-based external env should return None for name, got {:?}" ,
468500 name
469501 ) ;
470502
471503 // Cleanup
472504 let _ = std:: fs:: remove_dir_all ( & temp_dir) ;
473505 }
474506
475- /// Test that name-based conda environments (created with -n) return the name
476- /// even when conda_dir is unknown .
507+ /// Test that external environments (not under conda_dir) created with -n
508+ /// return the name for name-based activation .
477509 #[ test]
478- fn name_based_env_returns_name_when_conda_dir_unknown ( ) {
479- // Create a temp directory structure simulating a name-based conda env
480- let temp_dir = std:: env:: temp_dir ( ) . join ( "pet_test_name_based_env " ) ;
510+ fn external_name_based_env_returns_name ( ) {
511+ // Create a temp directory simulating an external name-based conda env
512+ let temp_dir = std:: env:: temp_dir ( ) . join ( "pet_test_external_name_env " ) ;
481513 let conda_meta_dir = temp_dir. join ( "myenv" ) . join ( "conda-meta" ) ;
482514 std:: fs:: create_dir_all ( & conda_meta_dir) . unwrap ( ) ;
483515
@@ -490,13 +522,14 @@ mod tests {
490522 . unwrap ( ) ;
491523
492524 let env_path = temp_dir. join ( "myenv" ) ;
525+ // conda_dir is known but env is NOT under it (external environment)
526+ let conda_dir = Some ( std:: path:: PathBuf :: from ( "/some/other/conda" ) ) ;
493527
494- // When conda_dir is None but env was created with -n, name should be returned
495- let name = get_conda_env_name ( & env_path, & env_path, & None ) ;
528+ let name = get_conda_env_name ( & env_path, & env_path, & conda_dir) ;
496529 assert_eq ! (
497530 name,
498531 Some ( "myenv" . to_string( ) ) ,
499- "Name-based env should return the name"
532+ "Name-based external env should return the name"
500533 ) ;
501534
502535 // Cleanup
0 commit comments