testing: convert some tmpdir to tmp_path

The tmpdir fixture (and its factory variant) is soft-deprecated in favor
of the tmp_path fixture.
This commit is contained in:
Ran Benita 2020-12-19 15:16:01 +02:00
parent a218413008
commit 4faed28261
2 changed files with 121 additions and 92 deletions

View File

@ -8,6 +8,7 @@ import pytest
from _pytest.config import ExitCode from _pytest.config import ExitCode
from _pytest.monkeypatch import MonkeyPatch from _pytest.monkeypatch import MonkeyPatch
from _pytest.pytester import Pytester from _pytest.pytester import Pytester
from _pytest.tmpdir import TempPathFactory
pytest_plugins = ("pytester",) pytest_plugins = ("pytester",)
@ -139,9 +140,11 @@ class TestNewAPI:
pytester.runpytest() pytester.runpytest()
assert pytester.path.joinpath(rel_cache_dir).is_dir() assert pytester.path.joinpath(rel_cache_dir).is_dir()
def test_custom_abs_cache_dir(self, pytester: Pytester, tmpdir_factory) -> None: def test_custom_abs_cache_dir(
tmp = str(tmpdir_factory.mktemp("tmp")) self, pytester: Pytester, tmp_path_factory: TempPathFactory
abs_cache_dir = os.path.join(tmp, "custom_cache_dir") ) -> None:
tmp = tmp_path_factory.mktemp("tmp")
abs_cache_dir = tmp / "custom_cache_dir"
pytester.makeini( pytester.makeini(
""" """
[pytest] [pytest]
@ -152,7 +155,7 @@ class TestNewAPI:
) )
pytester.makepyfile(test_errored="def test_error():\n assert False") pytester.makepyfile(test_errored="def test_error():\n assert False")
pytester.runpytest() pytester.runpytest()
assert Path(abs_cache_dir).is_dir() assert abs_cache_dir.is_dir()
def test_custom_cache_dir_with_env_var( def test_custom_cache_dir_with_env_var(
self, pytester: Pytester, monkeypatch: MonkeyPatch self, pytester: Pytester, monkeypatch: MonkeyPatch
@ -185,9 +188,9 @@ def test_cache_reportheader(env, pytester: Pytester, monkeypatch: MonkeyPatch) -
def test_cache_reportheader_external_abspath( def test_cache_reportheader_external_abspath(
pytester: Pytester, tmpdir_factory pytester: Pytester, tmp_path_factory: TempPathFactory
) -> None: ) -> None:
external_cache = tmpdir_factory.mktemp( external_cache = tmp_path_factory.mktemp(
"test_cache_reportheader_external_abspath_abs" "test_cache_reportheader_external_abspath_abs"
) )

View File

@ -1,8 +1,11 @@
import os.path import os.path
import pickle
import sys import sys
import unittest.mock import unittest.mock
from pathlib import Path from pathlib import Path
from textwrap import dedent from textwrap import dedent
from types import ModuleType
from typing import Generator
import py import py
@ -20,6 +23,7 @@ from _pytest.pathlib import maybe_delete_a_numbered_dir
from _pytest.pathlib import resolve_package_path from _pytest.pathlib import resolve_package_path
from _pytest.pathlib import symlink_or_skip from _pytest.pathlib import symlink_or_skip
from _pytest.pathlib import visit from _pytest.pathlib import visit
from _pytest.tmpdir import TempPathFactory
class TestFNMatcherPort: class TestFNMatcherPort:
@ -96,38 +100,40 @@ class TestImportPath:
""" """
@pytest.fixture(scope="session") @pytest.fixture(scope="session")
def path1(self, tmpdir_factory): def path1(self, tmp_path_factory: TempPathFactory) -> Generator[Path, None, None]:
path = tmpdir_factory.mktemp("path") path = tmp_path_factory.mktemp("path")
self.setuptestfs(path) self.setuptestfs(path)
yield path yield path
assert path.join("samplefile").check() assert path.joinpath("samplefile").exists()
def setuptestfs(self, path): def setuptestfs(self, path: Path) -> None:
# print "setting up test fs for", repr(path) # print "setting up test fs for", repr(path)
samplefile = path.ensure("samplefile") samplefile = path / "samplefile"
samplefile.write("samplefile\n") samplefile.write_text("samplefile\n")
execfile = path.ensure("execfile") execfile = path / "execfile"
execfile.write("x=42") execfile.write_text("x=42")
execfilepy = path.ensure("execfile.py") execfilepy = path / "execfile.py"
execfilepy.write("x=42") execfilepy.write_text("x=42")
d = {1: 2, "hello": "world", "answer": 42} d = {1: 2, "hello": "world", "answer": 42}
path.ensure("samplepickle").dump(d) path.joinpath("samplepickle").write_bytes(pickle.dumps(d, 1))
sampledir = path.ensure("sampledir", dir=1) sampledir = path / "sampledir"
sampledir.ensure("otherfile") sampledir.mkdir()
sampledir.joinpath("otherfile").touch()
otherdir = path.ensure("otherdir", dir=1) otherdir = path / "otherdir"
otherdir.ensure("__init__.py") otherdir.mkdir()
otherdir.joinpath("__init__.py").touch()
module_a = otherdir.ensure("a.py") module_a = otherdir / "a.py"
module_a.write("from .b import stuff as result\n") module_a.write_text("from .b import stuff as result\n")
module_b = otherdir.ensure("b.py") module_b = otherdir / "b.py"
module_b.write('stuff="got it"\n') module_b.write_text('stuff="got it"\n')
module_c = otherdir.ensure("c.py") module_c = otherdir / "c.py"
module_c.write( module_c.write_text(
dedent( dedent(
""" """
import py; import py;
@ -136,8 +142,8 @@ class TestImportPath:
""" """
) )
) )
module_d = otherdir.ensure("d.py") module_d = otherdir / "d.py"
module_d.write( module_d.write_text(
dedent( dedent(
""" """
import py; import py;
@ -147,122 +153,141 @@ class TestImportPath:
) )
) )
def test_smoke_test(self, path1): def test_smoke_test(self, path1: Path) -> None:
obj = import_path(path1.join("execfile.py")) obj = import_path(path1 / "execfile.py")
assert obj.x == 42 # type: ignore[attr-defined] assert obj.x == 42 # type: ignore[attr-defined]
assert obj.__name__ == "execfile" assert obj.__name__ == "execfile"
def test_renamed_dir_creates_mismatch(self, tmpdir, monkeypatch): def test_renamed_dir_creates_mismatch(
p = tmpdir.ensure("a", "test_x123.py") self, tmp_path: Path, monkeypatch: MonkeyPatch
) -> None:
tmp_path.joinpath("a").mkdir()
p = tmp_path.joinpath("a", "test_x123.py")
p.touch()
import_path(p) import_path(p)
tmpdir.join("a").move(tmpdir.join("b")) tmp_path.joinpath("a").rename(tmp_path.joinpath("b"))
with pytest.raises(ImportPathMismatchError): with pytest.raises(ImportPathMismatchError):
import_path(tmpdir.join("b", "test_x123.py")) import_path(tmp_path.joinpath("b", "test_x123.py"))
# Errors can be ignored. # Errors can be ignored.
monkeypatch.setenv("PY_IGNORE_IMPORTMISMATCH", "1") monkeypatch.setenv("PY_IGNORE_IMPORTMISMATCH", "1")
import_path(tmpdir.join("b", "test_x123.py")) import_path(tmp_path.joinpath("b", "test_x123.py"))
# PY_IGNORE_IMPORTMISMATCH=0 does not ignore error. # PY_IGNORE_IMPORTMISMATCH=0 does not ignore error.
monkeypatch.setenv("PY_IGNORE_IMPORTMISMATCH", "0") monkeypatch.setenv("PY_IGNORE_IMPORTMISMATCH", "0")
with pytest.raises(ImportPathMismatchError): with pytest.raises(ImportPathMismatchError):
import_path(tmpdir.join("b", "test_x123.py")) import_path(tmp_path.joinpath("b", "test_x123.py"))
def test_messy_name(self, tmpdir): def test_messy_name(self, tmp_path: Path) -> None:
# http://bitbucket.org/hpk42/py-trunk/issue/129 # http://bitbucket.org/hpk42/py-trunk/issue/129
path = tmpdir.ensure("foo__init__.py") path = tmp_path / "foo__init__.py"
path.touch()
module = import_path(path) module = import_path(path)
assert module.__name__ == "foo__init__" assert module.__name__ == "foo__init__"
def test_dir(self, tmpdir): def test_dir(self, tmp_path: Path) -> None:
p = tmpdir.join("hello_123") p = tmp_path / "hello_123"
p_init = p.ensure("__init__.py") p.mkdir()
p_init = p / "__init__.py"
p_init.touch()
m = import_path(p) m = import_path(p)
assert m.__name__ == "hello_123" assert m.__name__ == "hello_123"
m = import_path(p_init) m = import_path(p_init)
assert m.__name__ == "hello_123" assert m.__name__ == "hello_123"
def test_a(self, path1): def test_a(self, path1: Path) -> None:
otherdir = path1.join("otherdir") otherdir = path1 / "otherdir"
mod = import_path(otherdir.join("a.py")) mod = import_path(otherdir / "a.py")
assert mod.result == "got it" # type: ignore[attr-defined] assert mod.result == "got it" # type: ignore[attr-defined]
assert mod.__name__ == "otherdir.a" assert mod.__name__ == "otherdir.a"
def test_b(self, path1): def test_b(self, path1: Path) -> None:
otherdir = path1.join("otherdir") otherdir = path1 / "otherdir"
mod = import_path(otherdir.join("b.py")) mod = import_path(otherdir / "b.py")
assert mod.stuff == "got it" # type: ignore[attr-defined] assert mod.stuff == "got it" # type: ignore[attr-defined]
assert mod.__name__ == "otherdir.b" assert mod.__name__ == "otherdir.b"
def test_c(self, path1): def test_c(self, path1: Path) -> None:
otherdir = path1.join("otherdir") otherdir = path1 / "otherdir"
mod = import_path(otherdir.join("c.py")) mod = import_path(otherdir / "c.py")
assert mod.value == "got it" # type: ignore[attr-defined] assert mod.value == "got it" # type: ignore[attr-defined]
def test_d(self, path1): def test_d(self, path1: Path) -> None:
otherdir = path1.join("otherdir") otherdir = path1 / "otherdir"
mod = import_path(otherdir.join("d.py")) mod = import_path(otherdir / "d.py")
assert mod.value2 == "got it" # type: ignore[attr-defined] assert mod.value2 == "got it" # type: ignore[attr-defined]
def test_import_after(self, tmpdir): def test_import_after(self, tmp_path: Path) -> None:
tmpdir.ensure("xxxpackage", "__init__.py") tmp_path.joinpath("xxxpackage").mkdir()
mod1path = tmpdir.ensure("xxxpackage", "module1.py") tmp_path.joinpath("xxxpackage", "__init__.py").touch()
mod1path = tmp_path.joinpath("xxxpackage", "module1.py")
mod1path.touch()
mod1 = import_path(mod1path) mod1 = import_path(mod1path)
assert mod1.__name__ == "xxxpackage.module1" assert mod1.__name__ == "xxxpackage.module1"
from xxxpackage import module1 from xxxpackage import module1
assert module1 is mod1 assert module1 is mod1
def test_check_filepath_consistency(self, monkeypatch, tmpdir): def test_check_filepath_consistency(
self, monkeypatch: MonkeyPatch, tmp_path: Path
) -> None:
name = "pointsback123" name = "pointsback123"
ModuleType = type(os) p = tmp_path.joinpath(name + ".py")
p = tmpdir.ensure(name + ".py") p.touch()
for ending in (".pyc", ".pyo"): for ending in (".pyc", ".pyo"):
mod = ModuleType(name) mod = ModuleType(name)
pseudopath = tmpdir.ensure(name + ending) pseudopath = tmp_path.joinpath(name + ending)
pseudopath.touch()
mod.__file__ = str(pseudopath) mod.__file__ = str(pseudopath)
monkeypatch.setitem(sys.modules, name, mod) monkeypatch.setitem(sys.modules, name, mod)
newmod = import_path(p) newmod = import_path(p)
assert mod == newmod assert mod == newmod
monkeypatch.undo() monkeypatch.undo()
mod = ModuleType(name) mod = ModuleType(name)
pseudopath = tmpdir.ensure(name + "123.py") pseudopath = tmp_path.joinpath(name + "123.py")
pseudopath.touch()
mod.__file__ = str(pseudopath) mod.__file__ = str(pseudopath)
monkeypatch.setitem(sys.modules, name, mod) monkeypatch.setitem(sys.modules, name, mod)
with pytest.raises(ImportPathMismatchError) as excinfo: with pytest.raises(ImportPathMismatchError) as excinfo:
import_path(p) import_path(p)
modname, modfile, orig = excinfo.value.args modname, modfile, orig = excinfo.value.args
assert modname == name assert modname == name
assert modfile == pseudopath assert modfile == str(pseudopath)
assert orig == p assert orig == p
assert issubclass(ImportPathMismatchError, ImportError) assert issubclass(ImportPathMismatchError, ImportError)
def test_issue131_on__init__(self, tmpdir): def test_issue131_on__init__(self, tmp_path: Path) -> None:
# __init__.py files may be namespace packages, and thus the # __init__.py files may be namespace packages, and thus the
# __file__ of an imported module may not be ourselves # __file__ of an imported module may not be ourselves
# see issue # see issue
p1 = tmpdir.ensure("proja", "__init__.py") tmp_path.joinpath("proja").mkdir()
p2 = tmpdir.ensure("sub", "proja", "__init__.py") p1 = tmp_path.joinpath("proja", "__init__.py")
p1.touch()
tmp_path.joinpath("sub", "proja").mkdir(parents=True)
p2 = tmp_path.joinpath("sub", "proja", "__init__.py")
p2.touch()
m1 = import_path(p1) m1 = import_path(p1)
m2 = import_path(p2) m2 = import_path(p2)
assert m1 == m2 assert m1 == m2
def test_ensuresyspath_append(self, tmpdir): def test_ensuresyspath_append(self, tmp_path: Path) -> None:
root1 = tmpdir.mkdir("root1") root1 = tmp_path / "root1"
file1 = root1.ensure("x123.py") root1.mkdir()
file1 = root1 / "x123.py"
file1.touch()
assert str(root1) not in sys.path assert str(root1) not in sys.path
import_path(file1, mode="append") import_path(file1, mode="append")
assert str(root1) == sys.path[-1] assert str(root1) == sys.path[-1]
assert str(root1) not in sys.path[:-1] assert str(root1) not in sys.path[:-1]
def test_invalid_path(self, tmpdir): def test_invalid_path(self, tmp_path: Path) -> None:
with pytest.raises(ImportError): with pytest.raises(ImportError):
import_path(tmpdir.join("invalid.py")) import_path(tmp_path / "invalid.py")
@pytest.fixture @pytest.fixture
def simple_module(self, tmpdir): def simple_module(self, tmp_path: Path) -> Path:
fn = tmpdir.join("mymod.py") fn = tmp_path / "mymod.py"
fn.write( fn.write_text(
dedent( dedent(
""" """
def foo(x): return 40 + x def foo(x): return 40 + x
@ -271,19 +296,21 @@ class TestImportPath:
) )
return fn return fn
def test_importmode_importlib(self, simple_module): def test_importmode_importlib(self, simple_module: Path) -> None:
"""`importlib` mode does not change sys.path.""" """`importlib` mode does not change sys.path."""
module = import_path(simple_module, mode="importlib") module = import_path(simple_module, mode="importlib")
assert module.foo(2) == 42 # type: ignore[attr-defined] assert module.foo(2) == 42 # type: ignore[attr-defined]
assert simple_module.dirname not in sys.path assert str(simple_module.parent) not in sys.path
def test_importmode_twice_is_different_module(self, simple_module): def test_importmode_twice_is_different_module(self, simple_module: Path) -> None:
"""`importlib` mode always returns a new module.""" """`importlib` mode always returns a new module."""
module1 = import_path(simple_module, mode="importlib") module1 = import_path(simple_module, mode="importlib")
module2 = import_path(simple_module, mode="importlib") module2 = import_path(simple_module, mode="importlib")
assert module1 is not module2 assert module1 is not module2
def test_no_meta_path_found(self, simple_module, monkeypatch): def test_no_meta_path_found(
self, simple_module: Path, monkeypatch: MonkeyPatch
) -> None:
"""Even without any meta_path should still import module.""" """Even without any meta_path should still import module."""
monkeypatch.setattr(sys, "meta_path", []) monkeypatch.setattr(sys, "meta_path", [])
module = import_path(simple_module, mode="importlib") module = import_path(simple_module, mode="importlib")
@ -299,7 +326,7 @@ class TestImportPath:
import_path(simple_module, mode="importlib") import_path(simple_module, mode="importlib")
def test_resolve_package_path(tmp_path): def test_resolve_package_path(tmp_path: Path) -> None:
pkg = tmp_path / "pkg1" pkg = tmp_path / "pkg1"
pkg.mkdir() pkg.mkdir()
(pkg / "__init__.py").touch() (pkg / "__init__.py").touch()
@ -309,7 +336,7 @@ def test_resolve_package_path(tmp_path):
assert resolve_package_path(pkg.joinpath("subdir", "__init__.py")) == pkg assert resolve_package_path(pkg.joinpath("subdir", "__init__.py")) == pkg
def test_package_unimportable(tmp_path): def test_package_unimportable(tmp_path: Path) -> None:
pkg = tmp_path / "pkg1-1" pkg = tmp_path / "pkg1-1"
pkg.mkdir() pkg.mkdir()
pkg.joinpath("__init__.py").touch() pkg.joinpath("__init__.py").touch()
@ -323,7 +350,7 @@ def test_package_unimportable(tmp_path):
assert not resolve_package_path(pkg) assert not resolve_package_path(pkg)
def test_access_denied_during_cleanup(tmp_path, monkeypatch): def test_access_denied_during_cleanup(tmp_path: Path, monkeypatch: MonkeyPatch) -> None:
"""Ensure that deleting a numbered dir does not fail because of OSErrors (#4262).""" """Ensure that deleting a numbered dir does not fail because of OSErrors (#4262)."""
path = tmp_path / "temp-1" path = tmp_path / "temp-1"
path.mkdir() path.mkdir()
@ -338,7 +365,7 @@ def test_access_denied_during_cleanup(tmp_path, monkeypatch):
assert not lock_path.is_file() assert not lock_path.is_file()
def test_long_path_during_cleanup(tmp_path): def test_long_path_during_cleanup(tmp_path: Path) -> None:
"""Ensure that deleting long path works (particularly on Windows (#6775)).""" """Ensure that deleting long path works (particularly on Windows (#6775))."""
path = (tmp_path / ("a" * 250)).resolve() path = (tmp_path / ("a" * 250)).resolve()
if sys.platform == "win32": if sys.platform == "win32":
@ -354,14 +381,14 @@ def test_long_path_during_cleanup(tmp_path):
assert not os.path.isdir(extended_path) assert not os.path.isdir(extended_path)
def test_get_extended_length_path_str(): def test_get_extended_length_path_str() -> None:
assert get_extended_length_path_str(r"c:\foo") == r"\\?\c:\foo" assert get_extended_length_path_str(r"c:\foo") == r"\\?\c:\foo"
assert get_extended_length_path_str(r"\\share\foo") == r"\\?\UNC\share\foo" assert get_extended_length_path_str(r"\\share\foo") == r"\\?\UNC\share\foo"
assert get_extended_length_path_str(r"\\?\UNC\share\foo") == r"\\?\UNC\share\foo" assert get_extended_length_path_str(r"\\?\UNC\share\foo") == r"\\?\UNC\share\foo"
assert get_extended_length_path_str(r"\\?\c:\foo") == r"\\?\c:\foo" assert get_extended_length_path_str(r"\\?\c:\foo") == r"\\?\c:\foo"
def test_suppress_error_removing_lock(tmp_path): def test_suppress_error_removing_lock(tmp_path: Path) -> None:
"""ensure_deletable should be resilient if lock file cannot be removed (#5456, #7491)""" """ensure_deletable should be resilient if lock file cannot be removed (#5456, #7491)"""
path = tmp_path / "dir" path = tmp_path / "dir"
path.mkdir() path.mkdir()
@ -406,15 +433,14 @@ def test_commonpath() -> None:
assert commonpath(path, path.parent.parent) == path.parent.parent assert commonpath(path, path.parent.parent) == path.parent.parent
def test_visit_ignores_errors(tmpdir) -> None: def test_visit_ignores_errors(tmp_path: Path) -> None:
symlink_or_skip("recursive", tmpdir.join("recursive")) symlink_or_skip("recursive", tmp_path / "recursive")
tmpdir.join("foo").write_binary(b"") tmp_path.joinpath("foo").write_bytes(b"")
tmpdir.join("bar").write_binary(b"") tmp_path.joinpath("bar").write_bytes(b"")
assert [entry.name for entry in visit(tmpdir, recurse=lambda entry: False)] == [ assert [
"bar", entry.name for entry in visit(str(tmp_path), recurse=lambda entry: False)
"foo", ] == ["bar", "foo"]
]
@pytest.mark.skipif(not sys.platform.startswith("win"), reason="Windows only") @pytest.mark.skipif(not sys.platform.startswith("win"), reason="Windows only")