expand marker test debugging and restore maker discovery when obj is passed trough

This commit is contained in:
Ronny Pfannschmidt 2024-06-22 12:21:00 +02:00
parent cbd9e8996f
commit ec2bcc51ee
3 changed files with 26 additions and 9 deletions

View File

@ -107,7 +107,7 @@ class NodeMeta(abc.ABCMeta):
def _create(cls: type[_T], *k: Any, **kw: Any) -> _T:
try:
return super().__call__(*k, **kw) # type: ignore[no-any-return,misc]
except TypeError:
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
@ -115,6 +115,7 @@ class NodeMeta(abc.ABCMeta):
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."

View File

@ -255,6 +255,10 @@ class PyobjMixin(nodes.Node):
as its intended to always mix in before a node
its position in the mro is unaffected"""
def __init__(self, *k: Any, obj: Any | None = None, **kw: Any) -> None:
super().__init__(*k, **kw)
self._assign_obj_with_markers(obj)
_ALLOW_MARKERS = True
@property
@ -279,19 +283,23 @@ class PyobjMixin(nodes.Node):
# Overridden by Function.
return None
def _assign_obj_with_markers(self, obj: Any | None) -> None:
self._obj = obj
# XXX evil hack
# used to avoid Function marker duplication
if self._ALLOW_MARKERS and obj is not None:
self.own_markers.extend(get_unpacked_marks(self.obj))
# This assumes that `obj` is called before there is a chance
# to add custom keys to `self.keywords`, so no fear of overriding.
self.keywords.update((mark.name, mark) for mark in self.own_markers)
@property
def obj(self) -> Any:
"""Underlying Python object."""
obj = getattr(self, "_obj", None)
if obj is None:
self._obj = obj = self._getobj()
# XXX evil hack
# used to avoid Function marker duplication
if self._ALLOW_MARKERS:
self.own_markers.extend(get_unpacked_marks(self.obj))
# This assumes that `obj` is called before there is a chance
# to add custom keys to `self.keywords`, so no fear of overriding.
self.keywords.update((mark.name, mark) for mark in self.own_markers)
obj = self._getobj()
self._assign_obj_with_markers(obj)
return obj
@obj.setter

View File

@ -582,6 +582,14 @@ class TestFunctional:
has_own, has_inherited = items
has_own_marker = has_own.get_closest_marker("c")
has_inherited_marker = has_inherited.get_closest_marker("c")
for item in items:
print(item)
for node in item.iter_parents():
print(" ", node)
for marker in node.own_markers:
print(" ", marker)
assert has_own_marker is not None
assert has_inherited_marker is not None
assert has_own_marker.kwargs == {"location": "function"}