Fix tmp_path crash when skipping from fixture
This commit is contained in:
parent
cca029d55e
commit
1bbdf7d48f
|
@ -5,11 +5,15 @@ import sys
|
|||
import tempfile
|
||||
from pathlib import Path
|
||||
from shutil import rmtree
|
||||
from typing import Dict
|
||||
from typing import Generator
|
||||
from typing import Optional
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import Union
|
||||
|
||||
from _pytest.nodes import Item
|
||||
from _pytest.stash import StashKey
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing_extensions import Literal
|
||||
|
||||
|
@ -33,6 +37,8 @@ from _pytest.fixtures import fixture
|
|||
from _pytest.fixtures import FixtureRequest
|
||||
from _pytest.monkeypatch import MonkeyPatch
|
||||
|
||||
tmppath_result_key = StashKey[Dict[str, bool]]()
|
||||
|
||||
|
||||
@final
|
||||
@attr.s(init=False)
|
||||
|
@ -273,11 +279,16 @@ def tmp_path(
|
|||
# Remove the tmpdir if the policy is "failed" and the test passed.
|
||||
tmp_path_factory: TempPathFactory = request.session.config._tmp_path_factory # type: ignore
|
||||
policy = tmp_path_factory._retention_policy
|
||||
if policy == "failed" and request.node._tmp_path_result_call.passed:
|
||||
result_dict = request.node.stash[tmppath_result_key]
|
||||
|
||||
# "call" might be skipped so check if it exists first
|
||||
if "call" not in result_dict or (policy == "failed" and result_dict["call"]):
|
||||
# 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]
|
||||
|
||||
# remove dead symlink
|
||||
basetemp = tmp_path_factory._basetemp
|
||||
if basetemp is None:
|
||||
|
@ -306,7 +317,11 @@ def pytest_sessionfinish(session, exitstatus: Union[int, ExitCode]):
|
|||
|
||||
|
||||
@hookimpl(tryfirst=True, hookwrapper=True)
|
||||
def pytest_runtest_makereport(item, call):
|
||||
def pytest_runtest_makereport(item: Item, call):
|
||||
outcome = yield
|
||||
result = outcome.get_result()
|
||||
setattr(item, "_tmp_path_result_" + result.when, result)
|
||||
|
||||
if tmppath_result_key not in item.stash:
|
||||
item.stash[tmppath_result_key] = {result.when: result.passed}
|
||||
else:
|
||||
item.stash[tmppath_result_key][result.when] = result.passed
|
||||
|
|
|
@ -12,6 +12,7 @@ import attr
|
|||
import pytest
|
||||
from _pytest import pathlib
|
||||
from _pytest.config import Config
|
||||
from _pytest.config import ExitCode
|
||||
from _pytest.monkeypatch import MonkeyPatch
|
||||
from _pytest.pathlib import cleanup_numbered_dir
|
||||
from _pytest.pathlib import create_cleanup_lock
|
||||
|
@ -139,6 +140,24 @@ class TestConfigTmpPath:
|
|||
# Check the base dir itself is gone
|
||||
assert len(list(base_dir)) == 0
|
||||
|
||||
# issue #10502
|
||||
def test_delete_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
|
||||
"""
|
||||
)
|
||||
|
||||
reprec = pytester.inline_run(p)
|
||||
assert reprec.ret == ExitCode.OK
|
||||
|
||||
|
||||
testdata = [
|
||||
("mypath", True),
|
||||
|
|
Loading…
Reference in New Issue