Node: enable self-type for _create

This commit is contained in:
Ronny Pfannschmidt 2024-06-18 16:53:50 +02:00
parent 56fc42ab9f
commit befa0c5e40
1 changed files with 23 additions and 22 deletions

View File

@ -19,6 +19,7 @@ from typing import TypeVar
import warnings
import pluggy
from typing_extensions import Self
import _pytest._code
from _pytest._code import getfslineno
@ -53,8 +54,6 @@ SEP = "/"
tracebackcutdir = Path(_pytest.__file__).parent
def _imply_path(
node_type: type[Node],
path: Path | None,
@ -103,26 +102,6 @@ class NodeMeta(abc.ABCMeta):
).format(name=f"{cls.__module__}.{cls.__name__}")
fail(msg, pytrace=False)
def _create(cls: type[_T], *k: Any, **kw: Any) -> _T:
try:
return super().__call__(*k, **kw) # type: ignore[no-any-return,misc]
except TypeError as e:
sig = signature(getattr(cls, "__init__"))
known_kw = {k: v for k, v in kw.items() if k in sig.parameters}
from .warning_types import PytestDeprecationWarning
warnings.warn(
PytestDeprecationWarning(
f"{cls} is not using a cooperative constructor and only takes {set(known_kw)}.\n"
f"Exception: {e}\n"
"See https://docs.pytest.org/en/stable/deprecations.html"
"#constructors-of-custom-pytest-node-subclasses-should-take-kwargs "
"for more details."
)
)
return super().__call__(*k, **known_kw) # type: ignore[no-any-return,misc]
class Node(abc.ABC, metaclass=NodeMeta):
r"""Base class of :class:`Collector` and :class:`Item`, the components of
@ -223,6 +202,28 @@ class Node(abc.ABC, metaclass=NodeMeta):
assert parent is not None
return f"{parent.nodeid}::{name}"
@classmethod
def _create(cls, *k: object, **kw: object) -> Self:
callit = super(type(cls), NodeMeta).__call__ # type: ignore[misc]
try:
return cast(Self, callit(cls, *k, **kw))
except TypeError as e:
sig = signature(getattr(cls, "__init__"))
known_kw = {k: v for k, v in kw.items() if k in sig.parameters}
from .warning_types import PytestDeprecationWarning
warnings.warn(
PytestDeprecationWarning(
f"{cls} is not using a cooperative constructor and only takes {set(known_kw)}.\n"
f"Exception: {e}\n"
"See https://docs.pytest.org/en/stable/deprecations.html"
"#constructors-of-custom-pytest-node-subclasses-should-take-kwargs "
"for more details."
)
)
return cast(Self, callit(cls, *k, **known_kw))
@classmethod
def from_parent(cls, parent: Node, **kw: Any) -> Self:
"""Public constructor for Nodes.