Example #1
0
def _check_initialpaths_for_relpath(session: "Session",
                                    fspath: LEGACY_PATH) -> Optional[str]:
    for initial_path in session._initialpaths:
        initial_path_ = legacy_path(initial_path)
        if fspath.common(initial_path_) == initial_path_:
            return fspath.relto(initial_path_)
    return None
Example #2
0
    def _collectfile(self,
                     fspath: Path,
                     handle_dupes: bool = True) -> Sequence[nodes.Collector]:
        path = legacy_path(fspath)
        assert (fspath.is_file(
        )), "{!r} is not a file (isdir={!r}, exists={!r}, islink={!r})".format(
            fspath, fspath.is_dir(), fspath.exists(), fspath.is_symlink())
        ihook = self.gethookproxy(fspath)
        if not self.isinitpath(fspath):
            if ihook.pytest_ignore_collect(fspath=fspath,
                                           path=path,
                                           config=self.config):
                return ()

        if handle_dupes:
            keepduplicates = self.config.getoption("keepduplicates")
            if not keepduplicates:
                duplicate_paths = self.config.pluginmanager._duplicatepaths
                if fspath in duplicate_paths:
                    return ()
                else:
                    duplicate_paths.add(fspath)

        return ihook.pytest_collect_file(
            fspath=fspath, path=path,
            parent=self)  # type: ignore[no-any-return]
Example #3
0
def test_hookproxy_warnings_for_pathlib(tmp_path, hooktype, request):
    path = legacy_path(tmp_path)

    PATH_WARN_MATCH = r".*path: py\.path\.local\) argument is deprecated, please use \(collection_path: pathlib\.Path.*"
    if hooktype == "ihook":
        hooks = request.node.ihook
    else:
        hooks = request.config.hook

    with pytest.warns(PytestDeprecationWarning, match=PATH_WARN_MATCH) as r:
        l1 = sys._getframe().f_lineno
        hooks.pytest_ignore_collect(config=request.config,
                                    path=path,
                                    collection_path=tmp_path)
        l2 = sys._getframe().f_lineno

    (record, ) = r
    assert record.filename == __file__
    assert l1 < record.lineno < l2

    hooks.pytest_ignore_collect(config=request.config,
                                collection_path=tmp_path)

    # Passing entirely *different* paths is an outright error.
    with pytest.raises(ValueError, match=r"path.*fspath.*need to be equal"):
        with pytest.warns(PytestDeprecationWarning,
                          match=PATH_WARN_MATCH) as r:
            hooks.pytest_ignore_collect(config=request.config,
                                        path=path,
                                        collection_path=Path("/bla/bla"))
Example #4
0
def test_subclassing_both_item_and_collector_deprecated(
        request, tmp_path: Path) -> None:
    """
    Verifies we warn on diamond inheritance
    as well as correctly managing legacy inheritance ctors with missing args
    as found in plugins
    """

    with pytest.warns(
            PytestWarning,
            match=
        ("(?m)SoWrong is an Item subclass and should not be a collector, however its bases File are collectors.\n"
         "Please split the Collectors and the Item into separate node types.\n.*"
         ),
    ):

        class SoWrong(nodes.File, nodes.Item):
            def __init__(self, fspath, parent):
                """Legacy ctor with legacy call # don't wana see"""
                super().__init__(fspath, parent)

    with pytest.warns(
            PytestWarning,
            match=".*SoWrong.* not using a cooperative constructor.*"):
        SoWrong.from_parent(request.session,
                            fspath=legacy_path(tmp_path / "broken.txt"))
Example #5
0
def test_subclassing_both_item_and_collector_deprecated(
        request, tmp_path: Path) -> None:
    """
    Verifies we warn on diamond inheritance as well as correctly managing legacy
    inheritance constructors with missing args as found in plugins.
    """

    # We do not expect any warnings messages to issued during class definition.
    with warnings.catch_warnings():
        warnings.simplefilter("error")

        class SoWrong(nodes.Item, nodes.File):
            def __init__(self, fspath, parent):
                """Legacy ctor with legacy call # don't wana see"""
                super().__init__(fspath, parent)

    with pytest.warns(PytestWarning) as rec:
        SoWrong.from_parent(request.session,
                            fspath=legacy_path(tmp_path / "broken.txt"))
    messages = [str(x.message) for x in rec]
    assert any(
        re.search(".*SoWrong.* not using a cooperative constructor.*", x)
        for x in messages)
    assert any(
        re.search("(?m)SoWrong .* should not be a collector", x)
        for x in messages)
Example #6
0
    def stardir(self) -> LEGACY_PATH:
        """The path from which pytest was invoked.

        Prefer to use ``startpath`` which is a :class:`pathlib.Path`.

        :type: LEGACY_PATH
        """
        return legacy_path(self.startpath)
Example #7
0
def _imply_path(path: Optional[Path],
                fspath: Optional[LEGACY_PATH]) -> Tuple[Path, LEGACY_PATH]:
    if path is not None:
        if fspath is not None:
            _check_path(path, fspath)
        else:
            fspath = legacy_path(path)
        return path, fspath
    else:
        assert fspath is not None
        return Path(fspath), fspath
Example #8
0
def test_node_ctor_fspath_argument_is_deprecated(pytester: Pytester) -> None:
    mod = pytester.getmodulecol("")

    with pytest.warns(
        pytest.PytestDeprecationWarning,
        match=re.escape("The (fspath: py.path.local) argument to File is deprecated."),
    ):
        pytest.File.from_parent(
            parent=mod.parent,
            fspath=legacy_path("bla"),
        )
Example #9
0
 def _recurse(self, direntry: "os.DirEntry[str]") -> bool:
     if direntry.name == "__pycache__":
         return False
     fspath = Path(direntry.path)
     path = legacy_path(fspath)
     ihook = self.gethookproxy(fspath.parent)
     if ihook.pytest_ignore_collect(fspath=fspath,
                                    path=path,
                                    config=self.config):
         return False
     norecursepatterns = self.config.getini("norecursedirs")
     if any(fnmatch_ex(pat, fspath) for pat in norecursepatterns):
         return False
     return True
Example #10
0
def test__check_initialpaths_for_relpath() -> None:
    """Ensure that it handles dirs, and does not always use dirname."""
    cwd = Path.cwd()

    class FakeSession1:
        _initialpaths = frozenset({cwd})

    session = cast(pytest.Session, FakeSession1)

    assert nodes._check_initialpaths_for_relpath(session,
                                                 legacy_path(cwd)) == ""

    sub = cwd / "file"

    class FakeSession2:
        _initialpaths = frozenset({cwd})

    session = cast(pytest.Session, FakeSession2)

    assert nodes._check_initialpaths_for_relpath(session,
                                                 legacy_path(sub)) == "file"

    outside = legacy_path("/outside")
    assert nodes._check_initialpaths_for_relpath(session, outside) is None
Example #11
0
def tmpdir(tmp_path: Path) -> LEGACY_PATH:
    """Return a temporary directory path object which is unique to each test
    function invocation, created as a sub directory of the base temporary
    directory.

    By default, a new base temporary directory is created each test session,
    and old bases are removed after 3 sessions, to aid in debugging. If
    ``--basetemp`` is used then it is cleared each session. See :ref:`base
    temporary directory`.

    The returned object is a `legacy_path`_ object.

    .. _legacy_path: https://py.readthedocs.io/en/latest/path.html
    """
    return legacy_path(tmp_path)
Example #12
0
def _imply_path(path: Optional[Path],
                fspath: Optional[LEGACY_PATH]) -> Tuple[Path, LEGACY_PATH]:
    if path is not None:
        if fspath is not None:
            if Path(fspath) != path:
                raise ValueError(
                    f"Path({fspath!r}) != {path!r}\n"
                    "if both path and fspath are given they need to be equal")
            assert Path(fspath) == path, f"{fspath} != {path}"
        else:
            fspath = legacy_path(path)
        return path, fspath

    else:
        assert fspath is not None
        return Path(fspath), fspath
Example #13
0
 def test_paths_support(self, pytester: Pytester) -> None:
     """Report attributes which are py.path or pathlib objects should become strings."""
     pytester.makepyfile(
         """
         def test_a():
             assert False
     """
     )
     reprec = pytester.inline_run()
     reports = reprec.getreports("pytest_runtest_logreport")
     assert len(reports) == 3
     test_a_call = reports[1]
     test_a_call.path1 = legacy_path(pytester.path)  # type: ignore[attr-defined]
     test_a_call.path2 = pytester.path  # type: ignore[attr-defined]
     data = test_a_call._to_json()
     assert data["path1"] == str(pytester.path)
     assert data["path2"] == str(pytester.path)
Example #14
0
    def makedir(self, name: str) -> LEGACY_PATH:
        """Return a directory path object with the given name.

        If the directory does not yet exist, it will be created. You can use
        it to manage files to e.g. store/retrieve database dumps across test
        sessions.

        :param name:
            Must be a string not containing a ``/`` separator.
            Make sure the name contains your plugin or application
            identifiers to prevent clashes with other cache users.
        """
        path = Path(name)
        if len(path.parts) > 1:
            raise ValueError("name is not allowed to contain path separators")
        res = self._cachedir.joinpath(self._CACHE_PREFIX_DIRS, path)
        res.mkdir(exist_ok=True, parents=True)
        return legacy_path(res)
Example #15
0
def test_hookproxy_warnings_for_fspath(tmp_path, hooktype, request):
    path = legacy_path(tmp_path)

    PATH_WARN_MATCH = r".*path: py\.path\.local\) argument is deprecated, please use \(fspath: pathlib\.Path.*"
    if hooktype == "ihook":
        hooks = request.node.ihook
    else:
        hooks = request.config.hook

    with pytest.warns(PytestDeprecationWarning, match=PATH_WARN_MATCH) as r:
        l1 = sys._getframe().f_lineno
        hooks.pytest_ignore_collect(config=request.config,
                                    path=path,
                                    fspath=tmp_path)
        l2 = sys._getframe().f_lineno

    (record, ) = r
    assert record.filename == __file__
    assert l1 < record.lineno < l2

    hooks.pytest_ignore_collect(config=request.config, fspath=tmp_path)
Example #16
0
 def test_parse2(self, parser: parseopt.Parser) -> None:
     args = parser.parse([legacy_path(".")])
     assert getattr(args, parseopt.FILE_OR_DIR)[0] == legacy_path(".")
Example #17
0
 def getbasetemp(self) -> LEGACY_PATH:
     """Backward compat wrapper for ``_tmppath_factory.getbasetemp``."""
     return legacy_path(self._tmppath_factory.getbasetemp().resolve())
Example #18
0
 def mktemp(self, basename: str, numbered: bool = True) -> LEGACY_PATH:
     """Same as :meth:`TempPathFactory.mktemp`, but returns a ``_pytest.compat.LEGACY_PATH`` object."""
     return legacy_path(self._tmppath_factory.mktemp(basename, numbered).resolve())
Example #19
0
 def reportinfo(self):
     assert self.dtest is not None
     return legacy_path(self.path), self.dtest.lineno, "[doctest] %s" % self.name
Example #20
0
    def makedir(self, name: str) -> LEGACY_PATH:
        """Return a directory path object with the given name.

        Same as :func:`mkdir`, but returns a legacy py path instance.
        """
        return legacy_path(self.mkdir(name))
Example #21
0
 def fspath(self) -> LEGACY_PATH:
     """(deprecated) returns a legacy_path copy of self.path"""
     return legacy_path(self.path)
Example #22
0
 def fspath(self) -> LEGACY_PATH:
     """(deprecated) returns a legacy_path copy of self.path"""
     warnings.warn(NODE_FSPATH.format(type=type(self).__name__),
                   stacklevel=2)
     return legacy_path(self.path)
Example #23
0
    def reportinfo(self) -> Tuple[Union[LEGACY_PATH, str], Optional[int], str]:

        # TODO: enable Path objects in reportinfo
        return legacy_path(self.path), None, ""
Example #24
0
 def test_parse_known_args(self, parser: parseopt.Parser) -> None:
     parser.parse_known_args([legacy_path(".")])
     parser.addoption("--hello", action="store_true")
     ns = parser.parse_known_args(["x", "--y", "--hello", "this"])
     assert ns.hello
     assert ns.file_or_dir == ["x"]