diff --git a/AUTHORS b/AUTHORS index abac9f010..e75baa8cd 100644 --- a/AUTHORS +++ b/AUTHORS @@ -40,6 +40,7 @@ Aron Curzon Aviral Verma Aviv Palivoda Barney Gale +Ben Gartner Ben Webb Benjamin Peterson Bernard Pratz diff --git a/changelog/8192.bugfix.rst b/changelog/8192.bugfix.rst new file mode 100644 index 000000000..5b26ecbe4 --- /dev/null +++ b/changelog/8192.bugfix.rst @@ -0,0 +1,3 @@ +``testdir.makefile` now silently accepts values which don't start with ``.`` to maintain backward compatibility with older pytest versions. + +``pytester.makefile`` now issues a clearer error if the ``.`` is missing in the ``ext`` argument. diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index 4544d2c2b..95b22b3b2 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -64,6 +64,7 @@ from _pytest.reports import TestReport from _pytest.tmpdir import TempPathFactory from _pytest.warning_types import PytestWarning + if TYPE_CHECKING: from typing_extensions import Literal @@ -750,6 +751,11 @@ class Pytester: ) -> Path: items = list(files.items()) + if ext and not ext.startswith("."): + raise ValueError( + f"pytester.makefile expects a file extension, try .{ext} instead of {ext}" + ) + def to_text(s: Union[Any, bytes]) -> str: return s.decode(encoding) if isinstance(s, bytes) else str(s) @@ -1559,6 +1565,14 @@ class Testdir: def makefile(self, ext, *args, **kwargs) -> py.path.local: """See :meth:`Pytester.makefile`.""" + if ext and not ext.startswith("."): + # pytester.makefile is going to throw a ValueError in a way that + # testdir.makefile did not, because + # pathlib.Path is stricter suffixes than py.path + # This ext arguments is likely user error, but since testdir has + # allowed this, we will prepend "." as a workaround to avoid breaking + # testdir usage that worked before + ext = "." + ext return py.path.local(str(self._pytester.makefile(ext, *args, **kwargs))) def makeconftest(self, source) -> py.path.local: diff --git a/testing/test_pytester.py b/testing/test_pytester.py index 57d6f4fd9..5823d5115 100644 --- a/testing/test_pytester.py +++ b/testing/test_pytester.py @@ -17,6 +17,7 @@ from _pytest.pytester import LineMatcher from _pytest.pytester import Pytester from _pytest.pytester import SysModulesSnapshot from _pytest.pytester import SysPathsSnapshot +from _pytest.pytester import Testdir def test_make_hook_recorder(pytester: Pytester) -> None: @@ -816,3 +817,33 @@ def test_makefile_joins_absolute_path(pytester: Pytester) -> None: def test_testtmproot(testdir) -> None: """Check test_tmproot is a py.path attribute for backward compatibility.""" assert testdir.test_tmproot.check(dir=1) + + +def test_testdir_makefile_dot_prefixes_extension_silently( + testdir: Testdir, +) -> None: + """For backwards compat #8192""" + p1 = testdir.makefile("foo.bar", "") + assert ".foo.bar" in str(p1) + + +def test_pytester_makefile_dot_prefixes_extension_with_warning( + pytester: Pytester, +) -> None: + with pytest.raises( + ValueError, + match="pytester.makefile expects a file extension, try .foo.bar instead of foo.bar", + ): + pytester.makefile("foo.bar", "") + + +def test_testdir_makefile_ext_none_raises_type_error(testdir) -> None: + """For backwards compat #8192""" + with pytest.raises(TypeError): + testdir.makefile(None, "") + + +def test_testdir_makefile_ext_empty_string_makes_file(testdir) -> None: + """For backwards compat #8192""" + p1 = testdir.makefile("", "") + assert "test_testdir_makefile" in str(p1)