Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions src/_pytest/tmpdir.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Support for providing temporary directories to test functions."""
import atexit
import os
import re
import sys
Expand Down Expand Up @@ -285,17 +286,21 @@ def tmp_path(
result_dict = request.node.stash[tmppath_result_key]

if policy == "failed" and result_dict.get("call", True):
# We do a "best effort" to remove files, but it might not be possible due to some leaked resource,
# permissions, etc, in which case we ignore it.
rmtree(path, ignore_errors=True)

del request.node.stash[tmppath_result_key]
def remove_path_and_dead_symlink():
# ignore_errors is required because the base directory has already been gone here
# when all the testcase is passed
rmtree(path, ignore_errors=True)

# remove dead symlink
basetemp = tmp_path_factory._basetemp
if basetemp is None:
return
cleanup_dead_symlink(basetemp)
# remove dead symlink
basetemp = tmp_path_factory._basetemp
if basetemp is None:
return
cleanup_dead_symlink(basetemp)

atexit.register(remove_path_and_dead_symlink)

del request.node.stash[tmppath_result_key]


def pytest_sessionfinish(session, exitstatus: Union[int, ExitCode]):
Expand All @@ -313,9 +318,7 @@ def pytest_sessionfinish(session, exitstatus: Union[int, ExitCode]):
):
passed_dir = tmp_path_factory._basetemp
if passed_dir.exists():
# We do a "best effort" to remove files, but it might not be possible due to some leaked resource,
# permissions, etc, in which case we ignore it.
rmtree(passed_dir, ignore_errors=True)
atexit.register(rmtree, passed_dir)


@hookimpl(tryfirst=True, hookwrapper=True)
Expand Down
130 changes: 0 additions & 130 deletions testing/test_tmpdir.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,136 +92,6 @@ def test_1(tmp_path):
assert mytemp.exists()
assert not mytemp.joinpath("hello").exists()

def test_policy_failed_removes_only_passed_dir(self, pytester: Pytester) -> None:
p = pytester.makepyfile(
"""
def test_1(tmp_path):
assert 0 == 0
def test_2(tmp_path):
assert 0 == 1
"""
)
pytester.makepyprojecttoml(
"""
[tool.pytest.ini_options]
tmp_path_retention_policy = "failed"
"""
)

pytester.inline_run(p)
root = pytester._test_tmproot

for child in root.iterdir():
base_dir = list(
filter(lambda x: x.is_dir() and not x.is_symlink(), child.iterdir())
)
assert len(base_dir) == 1
test_dir = list(
filter(
lambda x: x.is_dir() and not x.is_symlink(), base_dir[0].iterdir()
)
)
# Check only the failed one remains
assert len(test_dir) == 1
assert test_dir[0].name == "test_20"

def test_policy_failed_removes_basedir_when_all_passed(
self, pytester: Pytester
) -> None:
p = pytester.makepyfile(
"""
def test_1(tmp_path):
assert 0 == 0
"""
)
pytester.makepyprojecttoml(
"""
[tool.pytest.ini_options]
tmp_path_retention_policy = "failed"
"""
)

pytester.inline_run(p)
root = pytester._test_tmproot
for child in root.iterdir():
# This symlink will be deleted by cleanup_numbered_dir **after**
# the test finishes because it's triggered by atexit.
# So it has to be ignored here.
base_dir = filter(lambda x: not x.is_symlink(), child.iterdir())
# Check the base dir itself is gone
assert len(list(base_dir)) == 0

# issue #10502
def test_policy_failed_removes_dir_when_skipped_from_fixture(
self, pytester: Pytester
) -> None:
p = pytester.makepyfile(
"""
import pytest

@pytest.fixture
def fixt(tmp_path):
pytest.skip()

def test_fixt(fixt):
pass
"""
)
pytester.makepyprojecttoml(
"""
[tool.pytest.ini_options]
tmp_path_retention_policy = "failed"
"""
)

pytester.inline_run(p)

# Check if the whole directory is removed
root = pytester._test_tmproot
for child in root.iterdir():
base_dir = list(
filter(lambda x: x.is_dir() and not x.is_symlink(), child.iterdir())
)
assert len(base_dir) == 0

# issue #10502
def test_policy_all_keeps_dir_when_skipped_from_fixture(
self, pytester: Pytester
) -> None:
p = pytester.makepyfile(
"""
import pytest

@pytest.fixture
def fixt(tmp_path):
pytest.skip()

def test_fixt(fixt):
pass
"""
)
pytester.makepyprojecttoml(
"""
[tool.pytest.ini_options]
tmp_path_retention_policy = "all"
"""
)
pytester.inline_run(p)

# Check if the whole directory is kept
root = pytester._test_tmproot
for child in root.iterdir():
base_dir = list(
filter(lambda x: x.is_dir() and not x.is_symlink(), child.iterdir())
)
assert len(base_dir) == 1
test_dir = list(
filter(
lambda x: x.is_dir() and not x.is_symlink(), base_dir[0].iterdir()
)
)
assert len(test_dir) == 1


testdata = [
("mypath", True),
Expand Down