diff --git a/src/poetry/core/utils/helpers.py b/src/poetry/core/utils/helpers.py index aa5354feb..d9127831b 100644 --- a/src/poetry/core/utils/helpers.py +++ b/src/poetry/core/utils/helpers.py @@ -37,8 +37,10 @@ def temporary_directory(*args: Any, **kwargs: Any) -> Iterator[Path]: yield Path(name) else: name = tempfile.mkdtemp(*args, **kwargs) - yield Path(name) - robust_rmtree(name) + try: + yield Path(name) + finally: + robust_rmtree(name) def parse_requires(requires: str) -> list[str]: diff --git a/tests/utils/test_helpers.py b/tests/utils/test_helpers.py index fbdde65ce..6de9c20cf 100644 --- a/tests/utils/test_helpers.py +++ b/tests/utils/test_helpers.py @@ -127,6 +127,7 @@ def test_utils_helpers_readme_content_type( assert readme_content_type(readme) == content_type +@pytest.mark.skipif(sys.version_info < (3, 10), reason="Requires Python 3.10 or higher") def test_temporary_directory_python_3_10_or_newer(mocker: MockerFixture) -> None: mocked_rmtree = mocker.patch("shutil.rmtree") mocked_temp_dir = mocker.patch("tempfile.TemporaryDirectory") @@ -134,7 +135,6 @@ def test_temporary_directory_python_3_10_or_newer(mocker: MockerFixture) -> None mocked_temp_dir.return_value.__enter__.return_value = "hello from test" - mocker.patch.object(sys, "version_info", (3, 10)) with temporary_directory() as tmp: assert tmp == Path("hello from test") @@ -143,6 +143,31 @@ def test_temporary_directory_python_3_10_or_newer(mocker: MockerFixture) -> None mocked_temp_dir.assert_called_with(ignore_cleanup_errors=True) +@pytest.mark.skipif(sys.version_info < (3, 10), reason="Requires Python 3.10 or higher") +def test_temporary_directory_python_3_10_or_newer_ensure_cleanup_on_error( + mocker: MockerFixture, +) -> None: + mocked_rmtree = mocker.patch("shutil.rmtree") + mocked_temp_dir = mocker.patch("tempfile.TemporaryDirectory") + mocked_mkdtemp = mocker.patch("tempfile.mkdtemp") + + mocked_temp_dir.return_value.__enter__.return_value = "hello from test" + + with pytest.raises( + Exception, match="Something went wrong" + ), temporary_directory() as tmp: + assert tmp == Path("hello from test") + + raise Exception("Something went wrong") + + assert not mocked_rmtree.called + assert not mocked_mkdtemp.called + mocked_temp_dir.assert_called_with(ignore_cleanup_errors=True) + + +@pytest.mark.skipif( + sys.version_info >= (3, 10), reason="Not supported on Python 3.10 or higher" +) def test_temporary_directory_python_3_9_or_older(mocker: MockerFixture) -> None: mocked_rmtree = mocker.patch("shutil.rmtree") mocked_temp_dir = mocker.patch("tempfile.TemporaryDirectory") @@ -150,7 +175,6 @@ def test_temporary_directory_python_3_9_or_older(mocker: MockerFixture) -> None: mocked_mkdtemp.return_value = "hello from test" - mocker.patch.object(sys, "version_info", (3, 9)) with temporary_directory() as tmp: assert tmp == Path("hello from test") @@ -159,6 +183,30 @@ def test_temporary_directory_python_3_9_or_older(mocker: MockerFixture) -> None: assert not mocked_temp_dir.called +@pytest.mark.skipif( + sys.version_info >= (3, 10), reason="Not supported on Python 3.10 or higher" +) +def test_temporary_directory_python_3_9_or_older_ensure_cleanup_on_error( + mocker: MockerFixture, +) -> None: + mocked_rmtree = mocker.patch("shutil.rmtree") + mocked_temp_dir = mocker.patch("tempfile.TemporaryDirectory") + mocked_mkdtemp = mocker.patch("tempfile.mkdtemp") + + mocked_mkdtemp.return_value = "hello from test" + + with pytest.raises( + Exception, match="Something went wrong" + ), temporary_directory() as tmp: + assert tmp == Path("hello from test") + + raise Exception("Something went wrong") + + assert mocked_rmtree.called + assert mocked_mkdtemp.called + assert not mocked_temp_dir.called + + def test_robust_rmtree(mocker: MockerFixture) -> None: mocked_rmtree = mocker.patch("shutil.rmtree")