Revert "Remove deprecated py.path (`fspath`) node constructor arguments"
This reverts commit 6c89f9261c
.
This commit is contained in:
parent
86945f9a1f
commit
303cd0d48a
|
@ -200,6 +200,7 @@ nitpick_ignore = [
|
||||||
("py:class", "_tracing.TagTracerSub"),
|
("py:class", "_tracing.TagTracerSub"),
|
||||||
("py:class", "warnings.WarningMessage"),
|
("py:class", "warnings.WarningMessage"),
|
||||||
# Undocumented type aliases
|
# Undocumented type aliases
|
||||||
|
("py:class", "LEGACY_PATH"),
|
||||||
("py:class", "_PluggyPlugin"),
|
("py:class", "_PluggyPlugin"),
|
||||||
# TypeVars
|
# TypeVars
|
||||||
("py:class", "_pytest._code.code.E"),
|
("py:class", "_pytest._code.code.E"),
|
||||||
|
|
|
@ -19,6 +19,45 @@ Below is a complete list of all pytest features which are considered deprecated.
|
||||||
:class:`~pytest.PytestWarning` or subclasses, which can be filtered using :ref:`standard warning filters <warnings>`.
|
:class:`~pytest.PytestWarning` or subclasses, which can be filtered using :ref:`standard warning filters <warnings>`.
|
||||||
|
|
||||||
|
|
||||||
|
.. _node-ctor-fspath-deprecation:
|
||||||
|
|
||||||
|
``fspath`` argument for Node constructors replaced with ``pathlib.Path``
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. deprecated:: 7.0
|
||||||
|
|
||||||
|
In order to support the transition from ``py.path.local`` to :mod:`pathlib`,
|
||||||
|
the ``fspath`` argument to :class:`~_pytest.nodes.Node` constructors like
|
||||||
|
:func:`pytest.Function.from_parent()` and :func:`pytest.Class.from_parent()`
|
||||||
|
is now deprecated.
|
||||||
|
|
||||||
|
Plugins which construct nodes should pass the ``path`` argument, of type
|
||||||
|
:class:`pathlib.Path`, instead of the ``fspath`` argument.
|
||||||
|
|
||||||
|
Plugins which implement custom items and collectors are encouraged to replace
|
||||||
|
``fspath`` parameters (``py.path.local``) with ``path`` parameters
|
||||||
|
(``pathlib.Path``), and drop any other usage of the ``py`` library if possible.
|
||||||
|
|
||||||
|
If possible, plugins with custom items should use :ref:`cooperative
|
||||||
|
constructors <uncooperative-constructors-deprecated>` to avoid hardcoding
|
||||||
|
arguments they only pass on to the superclass.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
The name of the :class:`~_pytest.nodes.Node` arguments and attributes (the
|
||||||
|
new attribute being ``path``) is **the opposite** of the situation for
|
||||||
|
hooks, :ref:`outlined below <legacy-path-hooks-deprecated>` (the old
|
||||||
|
argument being ``path``).
|
||||||
|
|
||||||
|
This is an unfortunate artifact due to historical reasons, which should be
|
||||||
|
resolved in future versions as we slowly get rid of the :pypi:`py`
|
||||||
|
dependency (see :issue:`9283` for a longer discussion).
|
||||||
|
|
||||||
|
Due to the ongoing migration of methods like :meth:`~pytest.Item.reportinfo`
|
||||||
|
which still is expected to return a ``py.path.local`` object, nodes still have
|
||||||
|
both ``fspath`` (``py.path.local``) and ``path`` (``pathlib.Path``) attributes,
|
||||||
|
no matter what argument was used in the constructor. We expect to deprecate the
|
||||||
|
``fspath`` attribute in a future release.
|
||||||
|
|
||||||
.. _legacy-path-hooks-deprecated:
|
.. _legacy-path-hooks-deprecated:
|
||||||
|
|
||||||
Configuring hook specs/impls using markers
|
Configuring hook specs/impls using markers
|
||||||
|
@ -208,46 +247,6 @@ an appropriate period of deprecation has passed.
|
||||||
|
|
||||||
Some breaking changes which could not be deprecated are also listed.
|
Some breaking changes which could not be deprecated are also listed.
|
||||||
|
|
||||||
.. _node-ctor-fspath-deprecation:
|
|
||||||
|
|
||||||
``fspath`` argument for Node constructors replaced with ``pathlib.Path``
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. deprecated:: 7.0
|
|
||||||
|
|
||||||
In order to support the transition from ``py.path.local`` to :mod:`pathlib`,
|
|
||||||
the ``fspath`` argument to :class:`~_pytest.nodes.Node` constructors like
|
|
||||||
:func:`pytest.Function.from_parent()` and :func:`pytest.Class.from_parent()`
|
|
||||||
is now deprecated.
|
|
||||||
|
|
||||||
Plugins which construct nodes should pass the ``path`` argument, of type
|
|
||||||
:class:`pathlib.Path`, instead of the ``fspath`` argument.
|
|
||||||
|
|
||||||
Plugins which implement custom items and collectors are encouraged to replace
|
|
||||||
``fspath`` parameters (``py.path.local``) with ``path`` parameters
|
|
||||||
(``pathlib.Path``), and drop any other usage of the ``py`` library if possible.
|
|
||||||
|
|
||||||
If possible, plugins with custom items should use :ref:`cooperative
|
|
||||||
constructors <uncooperative-constructors-deprecated>` to avoid hardcoding
|
|
||||||
arguments they only pass on to the superclass.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
The name of the :class:`~_pytest.nodes.Node` arguments and attributes (the
|
|
||||||
new attribute being ``path``) is **the opposite** of the situation for
|
|
||||||
hooks, :ref:`outlined below <legacy-path-hooks-deprecated>` (the old
|
|
||||||
argument being ``path``).
|
|
||||||
|
|
||||||
This is an unfortunate artifact due to historical reasons, which should be
|
|
||||||
resolved in future versions as we slowly get rid of the :pypi:`py`
|
|
||||||
dependency (see :issue:`9283` for a longer discussion).
|
|
||||||
|
|
||||||
Due to the ongoing migration of methods like :meth:`~pytest.Item.reportinfo`
|
|
||||||
which still is expected to return a ``py.path.local`` object, nodes still have
|
|
||||||
both ``fspath`` (``py.path.local``) and ``path`` (``pathlib.Path``) attributes,
|
|
||||||
no matter what argument was used in the constructor. We expect to deprecate the
|
|
||||||
``fspath`` attribute in a future release.
|
|
||||||
|
|
||||||
|
|
||||||
``py.path.local`` arguments for hooks replaced with ``pathlib.Path``
|
``py.path.local`` arguments for hooks replaced with ``pathlib.Path``
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# mypy: allow-untyped-defs
|
# mypy: allow-untyped-defs
|
||||||
"""Python version compatibility code."""
|
"""Python version compatibility code."""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import dataclasses
|
import dataclasses
|
||||||
|
@ -16,6 +17,22 @@ from typing import Callable
|
||||||
from typing import Final
|
from typing import Final
|
||||||
from typing import NoReturn
|
from typing import NoReturn
|
||||||
|
|
||||||
|
import py
|
||||||
|
|
||||||
|
|
||||||
|
#: constant to prepare valuing pylib path replacements/lazy proxies later on
|
||||||
|
# intended for removal in pytest 8.0 or 9.0
|
||||||
|
|
||||||
|
# fmt: off
|
||||||
|
# intentional space to create a fake difference for the verification
|
||||||
|
LEGACY_PATH = py.path. local
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
|
||||||
|
def legacy_path(path: str | os.PathLike[str]) -> LEGACY_PATH:
|
||||||
|
"""Internal wrapper to prepare lazy proxies for legacy_path instances"""
|
||||||
|
return LEGACY_PATH(path)
|
||||||
|
|
||||||
|
|
||||||
# fmt: off
|
# fmt: off
|
||||||
# Singleton type for NOTSET, as described in:
|
# Singleton type for NOTSET, as described in:
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from ..compat import LEGACY_PATH
|
||||||
|
|
||||||
|
|
||||||
|
def _check_path(path: Path, fspath: LEGACY_PATH) -> 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"
|
||||||
|
)
|
|
@ -36,6 +36,14 @@ YIELD_FIXTURE = PytestDeprecationWarning(
|
||||||
PRIVATE = PytestDeprecationWarning("A private pytest class or function was used.")
|
PRIVATE = PytestDeprecationWarning("A private pytest class or function was used.")
|
||||||
|
|
||||||
|
|
||||||
|
NODE_CTOR_FSPATH_ARG = UnformattedWarning(
|
||||||
|
PytestRemovedIn9Warning,
|
||||||
|
"The (fspath: py.path.local) argument to {node_type_name} is deprecated. "
|
||||||
|
"Please use the (path: pathlib.Path) argument instead.\n"
|
||||||
|
"See https://docs.pytest.org/en/latest/deprecations.html"
|
||||||
|
"#fspath-argument-for-node-constructors-replaced-with-pathlib-path",
|
||||||
|
)
|
||||||
|
|
||||||
HOOK_LEGACY_MARKING = UnformattedWarning(
|
HOOK_LEGACY_MARKING = UnformattedWarning(
|
||||||
PytestDeprecationWarning,
|
PytestDeprecationWarning,
|
||||||
"The hook{type} {fullname} uses old-style configuration options (marks or attributes).\n"
|
"The hook{type} {fullname} uses old-style configuration options (marks or attributes).\n"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# mypy: allow-untyped-defs
|
# mypy: allow-untyped-defs
|
||||||
"""Add backward compatibility support for the legacy py path type."""
|
"""Add backward compatibility support for the legacy py path type."""
|
||||||
|
|
||||||
import dataclasses
|
import dataclasses
|
||||||
import os
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import shlex
|
import shlex
|
||||||
import subprocess
|
import subprocess
|
||||||
|
@ -14,9 +14,9 @@ from typing import Union
|
||||||
|
|
||||||
from iniconfig import SectionWrapper
|
from iniconfig import SectionWrapper
|
||||||
|
|
||||||
import py
|
|
||||||
|
|
||||||
from _pytest.cacheprovider import Cache
|
from _pytest.cacheprovider import Cache
|
||||||
|
from _pytest.compat import LEGACY_PATH
|
||||||
|
from _pytest.compat import legacy_path
|
||||||
from _pytest.config import Config
|
from _pytest.config import Config
|
||||||
from _pytest.config import hookimpl
|
from _pytest.config import hookimpl
|
||||||
from _pytest.config import PytestPluginManager
|
from _pytest.config import PytestPluginManager
|
||||||
|
@ -39,20 +39,6 @@ if TYPE_CHECKING:
|
||||||
import pexpect
|
import pexpect
|
||||||
|
|
||||||
|
|
||||||
#: constant to prepare valuing pylib path replacements/lazy proxies later on
|
|
||||||
# intended for removal in pytest 8.0 or 9.0
|
|
||||||
|
|
||||||
# fmt: off
|
|
||||||
# intentional space to create a fake difference for the verification
|
|
||||||
LEGACY_PATH = py.path. local
|
|
||||||
# fmt: on
|
|
||||||
|
|
||||||
|
|
||||||
def legacy_path(path: Union[str, "os.PathLike[str]"]) -> LEGACY_PATH:
|
|
||||||
"""Internal wrapper to prepare lazy proxies for legacy_path instances"""
|
|
||||||
return LEGACY_PATH(path)
|
|
||||||
|
|
||||||
|
|
||||||
@final
|
@final
|
||||||
class Testdir:
|
class Testdir:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -557,6 +557,7 @@ class Session(nodes.Collector):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
name="",
|
name="",
|
||||||
path=config.rootpath,
|
path=config.rootpath,
|
||||||
|
fspath=None,
|
||||||
parent=None,
|
parent=None,
|
||||||
config=config,
|
config=config,
|
||||||
session=self,
|
session=self,
|
||||||
|
|
|
@ -3,6 +3,7 @@ import abc
|
||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
from inspect import signature
|
from inspect import signature
|
||||||
import os
|
import os
|
||||||
|
import pathlib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
@ -29,8 +30,11 @@ from _pytest._code import getfslineno
|
||||||
from _pytest._code.code import ExceptionInfo
|
from _pytest._code.code import ExceptionInfo
|
||||||
from _pytest._code.code import TerminalRepr
|
from _pytest._code.code import TerminalRepr
|
||||||
from _pytest._code.code import Traceback
|
from _pytest._code.code import Traceback
|
||||||
|
from _pytest.compat import LEGACY_PATH
|
||||||
from _pytest.config import Config
|
from _pytest.config import Config
|
||||||
from _pytest.config import ConftestImportFailure
|
from _pytest.config import ConftestImportFailure
|
||||||
|
from _pytest.config.compat import _check_path
|
||||||
|
from _pytest.deprecated import NODE_CTOR_FSPATH_ARG
|
||||||
from _pytest.mark.structures import Mark
|
from _pytest.mark.structures import Mark
|
||||||
from _pytest.mark.structures import MarkDecorator
|
from _pytest.mark.structures import MarkDecorator
|
||||||
from _pytest.mark.structures import NodeKeywords
|
from _pytest.mark.structures import NodeKeywords
|
||||||
|
@ -55,6 +59,29 @@ tracebackcutdir = Path(_pytest.__file__).parent
|
||||||
|
|
||||||
|
|
||||||
_T = TypeVar("_T")
|
_T = TypeVar("_T")
|
||||||
|
|
||||||
|
|
||||||
|
def _imply_path(
|
||||||
|
node_type: Type["Node"],
|
||||||
|
path: Optional[Path],
|
||||||
|
fspath: Optional[LEGACY_PATH],
|
||||||
|
) -> Path:
|
||||||
|
if fspath is not None:
|
||||||
|
warnings.warn(
|
||||||
|
NODE_CTOR_FSPATH_ARG.format(
|
||||||
|
node_type_name=node_type.__name__,
|
||||||
|
),
|
||||||
|
stacklevel=6,
|
||||||
|
)
|
||||||
|
if path is not None:
|
||||||
|
if fspath is not None:
|
||||||
|
_check_path(path, fspath)
|
||||||
|
return path
|
||||||
|
else:
|
||||||
|
assert fspath is not None
|
||||||
|
return Path(fspath)
|
||||||
|
|
||||||
|
|
||||||
_NodeType = TypeVar("_NodeType", bound="Node")
|
_NodeType = TypeVar("_NodeType", bound="Node")
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,6 +137,13 @@ class Node(abc.ABC, metaclass=NodeMeta):
|
||||||
leaf nodes.
|
leaf nodes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Implemented in the legacypath plugin.
|
||||||
|
#: A ``LEGACY_PATH`` copy of the :attr:`path` attribute. Intended for usage
|
||||||
|
#: for methods not migrated to ``pathlib.Path`` yet, such as
|
||||||
|
#: :meth:`Item.reportinfo <pytest.Item.reportinfo>`. Will be deprecated in
|
||||||
|
#: a future release, prefer using :attr:`path` instead.
|
||||||
|
fspath: LEGACY_PATH
|
||||||
|
|
||||||
# Use __slots__ to make attribute access faster.
|
# Use __slots__ to make attribute access faster.
|
||||||
# Note that __dict__ is still available.
|
# Note that __dict__ is still available.
|
||||||
__slots__ = (
|
__slots__ = (
|
||||||
|
@ -129,6 +163,7 @@ class Node(abc.ABC, metaclass=NodeMeta):
|
||||||
parent: "Optional[Node]" = None,
|
parent: "Optional[Node]" = None,
|
||||||
config: Optional[Config] = None,
|
config: Optional[Config] = None,
|
||||||
session: "Optional[Session]" = None,
|
session: "Optional[Session]" = None,
|
||||||
|
fspath: Optional[LEGACY_PATH] = None,
|
||||||
path: Optional[Path] = None,
|
path: Optional[Path] = None,
|
||||||
nodeid: Optional[str] = None,
|
nodeid: Optional[str] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -154,11 +189,10 @@ class Node(abc.ABC, metaclass=NodeMeta):
|
||||||
raise TypeError("session or parent must be provided")
|
raise TypeError("session or parent must be provided")
|
||||||
self.session = parent.session
|
self.session = parent.session
|
||||||
|
|
||||||
if path is None:
|
if path is None and fspath is None:
|
||||||
path = getattr(parent, "path", None)
|
path = getattr(parent, "path", None)
|
||||||
assert path is not None
|
|
||||||
#: Filesystem path where this node was collected from (can be None).
|
#: Filesystem path where this node was collected from (can be None).
|
||||||
self.path = path
|
self.path: pathlib.Path = _imply_path(type(self), path, fspath=fspath)
|
||||||
|
|
||||||
# The explicit annotation is to avoid publicly exposing NodeKeywords.
|
# The explicit annotation is to avoid publicly exposing NodeKeywords.
|
||||||
#: Keywords/markers collected from all scopes.
|
#: Keywords/markers collected from all scopes.
|
||||||
|
@ -529,6 +563,7 @@ class FSCollector(Collector, abc.ABC):
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
fspath: Optional[LEGACY_PATH] = None,
|
||||||
path_or_parent: Optional[Union[Path, Node]] = None,
|
path_or_parent: Optional[Union[Path, Node]] = None,
|
||||||
path: Optional[Path] = None,
|
path: Optional[Path] = None,
|
||||||
name: Optional[str] = None,
|
name: Optional[str] = None,
|
||||||
|
@ -544,8 +579,8 @@ class FSCollector(Collector, abc.ABC):
|
||||||
elif isinstance(path_or_parent, Path):
|
elif isinstance(path_or_parent, Path):
|
||||||
assert path is None
|
assert path is None
|
||||||
path = path_or_parent
|
path = path_or_parent
|
||||||
assert path is not None
|
|
||||||
|
|
||||||
|
path = _imply_path(type(self), path, fspath=fspath)
|
||||||
if name is None:
|
if name is None:
|
||||||
name = path.name
|
name = path.name
|
||||||
if parent is not None and parent.path != path:
|
if parent is not None and parent.path != path:
|
||||||
|
@ -585,11 +620,12 @@ class FSCollector(Collector, abc.ABC):
|
||||||
cls,
|
cls,
|
||||||
parent,
|
parent,
|
||||||
*,
|
*,
|
||||||
|
fspath: Optional[LEGACY_PATH] = None,
|
||||||
path: Optional[Path] = None,
|
path: Optional[Path] = None,
|
||||||
**kw,
|
**kw,
|
||||||
) -> "Self":
|
) -> "Self":
|
||||||
"""The public constructor."""
|
"""The public constructor."""
|
||||||
return super().from_parent(parent=parent, path=path, **kw)
|
return super().from_parent(parent=parent, fspath=fspath, path=path, **kw)
|
||||||
|
|
||||||
|
|
||||||
class File(FSCollector, abc.ABC):
|
class File(FSCollector, abc.ABC):
|
||||||
|
|
|
@ -48,6 +48,7 @@ from _pytest.compat import getimfunc
|
||||||
from _pytest.compat import getlocation
|
from _pytest.compat import getlocation
|
||||||
from _pytest.compat import is_async_function
|
from _pytest.compat import is_async_function
|
||||||
from _pytest.compat import is_generator
|
from _pytest.compat import is_generator
|
||||||
|
from _pytest.compat import LEGACY_PATH
|
||||||
from _pytest.compat import NOTSET
|
from _pytest.compat import NOTSET
|
||||||
from _pytest.compat import safe_getattr
|
from _pytest.compat import safe_getattr
|
||||||
from _pytest.compat import safe_isclass
|
from _pytest.compat import safe_isclass
|
||||||
|
@ -665,6 +666,7 @@ class Package(nodes.Directory):
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
fspath: Optional[LEGACY_PATH],
|
||||||
parent: nodes.Collector,
|
parent: nodes.Collector,
|
||||||
# NOTE: following args are unused:
|
# NOTE: following args are unused:
|
||||||
config=None,
|
config=None,
|
||||||
|
@ -676,6 +678,7 @@ class Package(nodes.Directory):
|
||||||
# super().__init__(self, fspath, parent=parent)
|
# super().__init__(self, fspath, parent=parent)
|
||||||
session = parent.session
|
session = parent.session
|
||||||
super().__init__(
|
super().__init__(
|
||||||
|
fspath=fspath,
|
||||||
path=path,
|
path=path,
|
||||||
parent=parent,
|
parent=parent,
|
||||||
config=config,
|
config=config,
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
# mypy: allow-untyped-defs
|
# mypy: allow-untyped-defs
|
||||||
|
import re
|
||||||
|
|
||||||
from _pytest import deprecated
|
from _pytest import deprecated
|
||||||
|
from _pytest.compat import legacy_path
|
||||||
from _pytest.pytester import Pytester
|
from _pytest.pytester import Pytester
|
||||||
import pytest
|
import pytest
|
||||||
from pytest import PytestDeprecationWarning
|
from pytest import PytestDeprecationWarning
|
||||||
|
@ -85,6 +88,25 @@ def test_private_is_deprecated() -> None:
|
||||||
PrivateInit(10, _ispytest=True)
|
PrivateInit(10, _ispytest=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_node_ctor_fspath_argument_is_deprecated(pytester: Pytester) -> None:
|
||||||
|
mod = pytester.getmodulecol("")
|
||||||
|
|
||||||
|
class MyFile(pytest.File):
|
||||||
|
def collect(self):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
with pytest.warns(
|
||||||
|
pytest.PytestDeprecationWarning,
|
||||||
|
match=re.escape(
|
||||||
|
"The (fspath: py.path.local) argument to MyFile is deprecated."
|
||||||
|
),
|
||||||
|
):
|
||||||
|
MyFile.from_parent(
|
||||||
|
parent=mod.parent,
|
||||||
|
fspath=legacy_path("bla"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_fixture_disallow_on_marked_functions():
|
def test_fixture_disallow_on_marked_functions():
|
||||||
"""Test that applying @pytest.fixture to a marked function warns (#3364)."""
|
"""Test that applying @pytest.fixture to a marked function warns (#3364)."""
|
||||||
with pytest.warns(
|
with pytest.warns(
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# mypy: allow-untyped-defs
|
# mypy: allow-untyped-defs
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
from _pytest.compat import LEGACY_PATH
|
||||||
from _pytest.fixtures import TopRequest
|
from _pytest.fixtures import TopRequest
|
||||||
from _pytest.legacypath import LEGACY_PATH
|
|
||||||
from _pytest.legacypath import TempdirFactory
|
from _pytest.legacypath import TempdirFactory
|
||||||
from _pytest.legacypath import Testdir
|
from _pytest.legacypath import Testdir
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -16,7 +16,7 @@ def test_item_fspath(pytester: pytest.Pytester) -> None:
|
||||||
items2, hookrec = pytester.inline_genitems(item.nodeid)
|
items2, hookrec = pytester.inline_genitems(item.nodeid)
|
||||||
(item2,) = items2
|
(item2,) = items2
|
||||||
assert item2.name == item.name
|
assert item2.name == item.name
|
||||||
assert item2.fspath == item.fspath # type: ignore[attr-defined]
|
assert item2.fspath == item.fspath
|
||||||
assert item2.path == item.path
|
assert item2.path == item.path
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ from typing import Type
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from _pytest import nodes
|
from _pytest import nodes
|
||||||
|
from _pytest.compat import legacy_path
|
||||||
from _pytest.outcomes import OutcomeException
|
from _pytest.outcomes import OutcomeException
|
||||||
from _pytest.pytester import Pytester
|
from _pytest.pytester import Pytester
|
||||||
from _pytest.warning_types import PytestWarning
|
from _pytest.warning_types import PytestWarning
|
||||||
|
@ -44,9 +45,9 @@ def test_subclassing_both_item_and_collector_deprecated(
|
||||||
warnings.simplefilter("error")
|
warnings.simplefilter("error")
|
||||||
|
|
||||||
class SoWrong(nodes.Item, nodes.File):
|
class SoWrong(nodes.Item, nodes.File):
|
||||||
def __init__(self, path, parent):
|
def __init__(self, fspath, parent):
|
||||||
"""Legacy ctor with legacy call # don't wana see"""
|
"""Legacy ctor with legacy call # don't wana see"""
|
||||||
super().__init__(parent, path)
|
super().__init__(fspath, parent)
|
||||||
|
|
||||||
def collect(self):
|
def collect(self):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
@ -55,7 +56,9 @@ def test_subclassing_both_item_and_collector_deprecated(
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
with pytest.warns(PytestWarning) as rec:
|
with pytest.warns(PytestWarning) as rec:
|
||||||
SoWrong.from_parent(request.session, path=tmp_path / "broken.txt", wrong=10)
|
SoWrong.from_parent(
|
||||||
|
request.session, fspath=legacy_path(tmp_path / "broken.txt")
|
||||||
|
)
|
||||||
messages = [str(x.message) for x in rec]
|
messages = [str(x.message) for x in rec]
|
||||||
assert any(
|
assert any(
|
||||||
re.search(".*SoWrong.* not using a cooperative constructor.*", x)
|
re.search(".*SoWrong.* not using a cooperative constructor.*", x)
|
||||||
|
|
Loading…
Reference in New Issue