@@ -22,14 +22,32 @@ def setUp(self):
2222 self .temp_dir = tempfile .mkdtemp ()
2323 self .environments_dir = Path (self .temp_dir ) / "envs"
2424 self .environments_dir .mkdir (exist_ok = True )
25-
25+
2626 # Create manager instance for testing
2727 self .manager = PythonEnvironmentManager (environments_dir = self .environments_dir )
2828
29+ # Track environments created during this test for cleanup
30+ self .created_environments = []
31+
2932 def tearDown (self ):
3033 """Clean up test environment."""
34+ # Clean up any conda/mamba environments created during this test
35+ if hasattr (self , 'manager' ) and self .manager .is_available ():
36+ for env_name in self .created_environments :
37+ try :
38+ if self .manager .environment_exists (env_name ):
39+ self .manager .remove_python_environment (env_name )
40+ except Exception :
41+ pass # Best effort cleanup
42+
43+ # Clean up temporary directory
3144 shutil .rmtree (self .temp_dir , ignore_errors = True )
3245
46+ def _track_environment (self , env_name ):
47+ """Track an environment for cleanup in tearDown."""
48+ if env_name not in self .created_environments :
49+ self .created_environments .append (env_name )
50+
3351 @regression_test
3452 @patch ('hatch.python_environment_manager.PythonEnvironmentManager._conda_env_exists' , return_value = True )
3553 @patch ('hatch.python_environment_manager.PythonEnvironmentManager._get_conda_env_name' , return_value = 'hatch_test_env' )
@@ -349,26 +367,61 @@ def setUpClass(cls):
349367 cls .temp_dir = tempfile .mkdtemp ()
350368 cls .environments_dir = Path (cls .temp_dir ) / "envs"
351369 cls .environments_dir .mkdir (exist_ok = True )
352-
370+
353371 # Create manager instance for integration testing
354372 cls .manager = PythonEnvironmentManager (environments_dir = cls .environments_dir )
355373
374+ # Track all environments created during integration tests
375+ cls .all_created_environments = set ()
376+
356377 # Skip all tests if conda/mamba is not available
357378 if not cls .manager .is_available ():
358379 raise unittest .SkipTest ("Conda/mamba not available for integration tests" )
359380
381+ def setUp (self ):
382+ """Set up individual test."""
383+ # Track environments created during this specific test
384+ self .test_environments = []
385+
386+ def tearDown (self ):
387+ """Clean up individual test."""
388+ # Clean up environments created during this specific test
389+ for env_name in self .test_environments :
390+ try :
391+ if self .manager .environment_exists (env_name ):
392+ self .manager .remove_python_environment (env_name )
393+ self .all_created_environments .discard (env_name )
394+ except Exception :
395+ pass # Best effort cleanup
396+
397+ def _track_environment (self , env_name ):
398+ """Track an environment for cleanup."""
399+ if env_name not in self .test_environments :
400+ self .test_environments .append (env_name )
401+ self .all_created_environments .add (env_name )
402+
360403 @classmethod
361404 def tearDownClass (cls ):
362405 """Clean up class-level test environment."""
363- # Clean up any test environments that might have been created
406+ # Clean up any remaining test environments
364407 try :
365- test_envs = ["test_integration_env" , "test_python_311" , "test_python_312" , "test_diagnostics_env" ]
366- for env_name in test_envs :
408+ # Clean up tracked environments
409+ for env_name in list (cls .all_created_environments ):
410+ if cls .manager .environment_exists (env_name ):
411+ cls .manager .remove_python_environment (env_name )
412+
413+ # Clean up known test environment patterns (fallback)
414+ known_patterns = [
415+ "test_integration_env" , "test_python_311" , "test_python_312" , "test_diagnostics_env" ,
416+ "test_env_1" , "test_env_2" , "test_env_3" , "test_env_4" , "test_env_5" ,
417+ "test_python_39" , "test_python_310" , "test_python_312" , "test_cache_env1" , "test_cache_env2"
418+ ]
419+ for env_name in known_patterns :
367420 if cls .manager .environment_exists (env_name ):
368421 cls .manager .remove_python_environment (env_name )
369422 except Exception :
370423 pass # Best effort cleanup
371-
424+
372425 shutil .rmtree (cls .temp_dir , ignore_errors = True )
373426
374427 @integration_test (scope = "system" )
@@ -418,11 +471,12 @@ def test_manager_diagnostics_real(self):
418471 def test_create_and_remove_python_environment_real (self ):
419472 """Test real Python environment creation and removal."""
420473 env_name = "test_integration_env"
421-
474+ self ._track_environment (env_name )
475+
422476 # Ensure environment doesn't exist initially
423477 if self .manager .environment_exists (env_name ):
424478 self .manager .remove_python_environment (env_name )
425-
479+
426480 # Create environment
427481 result = self .manager .create_python_environment (env_name )
428482 self .assertTrue (result , "Failed to create Python environment" )
@@ -454,6 +508,7 @@ def test_create_and_remove_python_environment_real(self):
454508 def test_create_python_environment_with_version_real (self ):
455509 """Test real Python environment creation with specific version."""
456510 env_name = "test_python_311"
511+ self ._track_environment (env_name )
457512 python_version = "3.11"
458513
459514 # Ensure environment doesn't exist initially
@@ -553,6 +608,10 @@ def test_list_environments_real(self):
553608 test_envs = ["test_env_1" , "test_env_2" ]
554609 final_names = ["hatch_test_env_1" , "hatch_test_env_2" ]
555610
611+ # Track environments for cleanup
612+ for env_name in test_envs :
613+ self ._track_environment (env_name )
614+
556615 # Clean up any existing test environments
557616 for env_name in test_envs :
558617 if self .manager .environment_exists (env_name ):
@@ -645,14 +704,32 @@ def setUp(self):
645704 self .temp_dir = tempfile .mkdtemp ()
646705 self .environments_dir = Path (self .temp_dir ) / "envs"
647706 self .environments_dir .mkdir (exist_ok = True )
648-
707+
649708 # Create manager instance for testing
650709 self .manager = PythonEnvironmentManager (environments_dir = self .environments_dir )
651710
711+ # Track environments created during this test for cleanup
712+ self .created_environments = []
713+
652714 def tearDown (self ):
653715 """Clean up test environment."""
716+ # Clean up any conda/mamba environments created during this test
717+ if hasattr (self , 'manager' ) and self .manager .is_available ():
718+ for env_name in self .created_environments :
719+ try :
720+ if self .manager .environment_exists (env_name ):
721+ self .manager .remove_python_environment (env_name )
722+ except Exception :
723+ pass # Best effort cleanup
724+
725+ # Clean up temporary directory
654726 shutil .rmtree (self .temp_dir , ignore_errors = True )
655727
728+ def _track_environment (self , env_name ):
729+ """Track an environment for cleanup in tearDown."""
730+ if env_name not in self .created_environments :
731+ self .created_environments .append (env_name )
732+
656733 @regression_test
657734 @patch ('subprocess.run' )
658735 def test_launch_shell_with_command (self , mock_run ):
0 commit comments