Skip to content

Commit b5a6e30

Browse files
authored
Merge pull request #9499 from pytest-dev/backport-9494-to-7.0.x
[7.0.x] python: add back `instance` accessor to all python nodes, not just Function
2 parents 0c5fc61 + d0ae12c commit b5a6e30

File tree

2 files changed

+26
-18
lines changed

2 files changed

+26
-18
lines changed

src/_pytest/python.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,16 @@ def cls(self):
278278
node = self.getparent(Class)
279279
return node.obj if node is not None else None
280280

281+
@property
282+
def instance(self):
283+
"""Python instance object the function is bound to.
284+
285+
Returns None if not a test method, e.g. for a standalone test function,
286+
a staticmethod, a class or a module.
287+
"""
288+
node = self.getparent(Function)
289+
return getattr(node.obj, "__self__", None) if node is not None else None
290+
281291
@property
282292
def obj(self):
283293
"""Underlying Python object."""
@@ -1689,15 +1699,6 @@ def function(self):
16891699
"""Underlying python 'function' object."""
16901700
return getimfunc(self.obj)
16911701

1692-
@property
1693-
def instance(self):
1694-
"""Python instance object the function is bound to.
1695-
1696-
Returns None if not a test method, e.g. for a standalone test function
1697-
or a staticmethod.
1698-
"""
1699-
return getattr(self.obj, "__self__", None)
1700-
17011702
def _getobj(self):
17021703
assert self.parent is not None
17031704
if isinstance(self.parent, Class):

testing/test_collection.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def test_fail(): assert 0
6464

6565
assert pytester.collect_by_name(modcol, "doesnotexist") is None
6666

67-
def test_getparent(self, pytester: Pytester) -> None:
67+
def test_getparent_and_accessors(self, pytester: Pytester) -> None:
6868
modcol = pytester.getmodulecol(
6969
"""
7070
class TestClass:
@@ -77,14 +77,21 @@ def test_foo(self):
7777
fn = pytester.collect_by_name(cls, "test_foo")
7878
assert isinstance(fn, pytest.Function)
7979

80-
module_parent = fn.getparent(pytest.Module)
81-
assert module_parent is modcol
82-
83-
function_parent = fn.getparent(pytest.Function)
84-
assert function_parent is fn
85-
86-
class_parent = fn.getparent(pytest.Class)
87-
assert class_parent is cls
80+
assert fn.getparent(pytest.Module) is modcol
81+
assert modcol.module is not None
82+
assert modcol.cls is None
83+
assert modcol.instance is None
84+
85+
assert fn.getparent(pytest.Class) is cls
86+
assert cls.module is not None
87+
assert cls.cls is not None
88+
assert cls.instance is None
89+
90+
assert fn.getparent(pytest.Function) is fn
91+
assert fn.module is not None
92+
assert fn.cls is not None
93+
assert fn.instance is not None
94+
assert fn.function is not None
8895

8996
def test_getcustomfile_roundtrip(self, pytester: Pytester) -> None:
9097
hello = pytester.makefile(".xxx", hello="world")

0 commit comments

Comments
 (0)