Skip to content

Commit 87b7274

Browse files
committed
refactor: removed PytestWrapper class
1 parent 4ad37f5 commit 87b7274

File tree

3 files changed

+15
-31
lines changed

3 files changed

+15
-31
lines changed

src/_pytest/compat.py

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
from __future__ import annotations
55

6-
import dataclasses
76
import enum
87
import functools
98
import inspect
@@ -210,30 +209,15 @@ def ascii_escaped(val: bytes | str) -> str:
210209
return ret.translate(_non_printable_ascii_translate_table)
211210

212211

213-
# TODO: remove and replace with FixtureFunctionDefinition
214-
@dataclasses.dataclass
215-
class _PytestWrapper:
216-
"""Dummy wrapper around a function object for internal use only.
217-
218-
Used to correctly unwrap the underlying function object when we are
219-
creating fixtures, because we wrap the function object ourselves with a
220-
decorator to issue warnings when the fixture function is called directly.
221-
"""
222-
223-
obj: Any
224-
225-
226212
def get_real_func(obj):
227213
"""Get the real function object of the (possibly) wrapped object by
228-
functools.wraps or functools.partial."""
214+
functools.wraps or functools.partial or pytest.fixture"""
215+
from _pytest.fixtures import FixtureFunctionDefinition
216+
229217
start_obj = obj
230-
for i in range(100):
231-
# __pytest_wrapped__ is set by @pytest.fixture when wrapping the fixture function
232-
# to trigger a warning if it gets called directly instead of by pytest: we don't
233-
# want to unwrap further than this otherwise we lose useful wrappings like @mock.patch (#3774)
234-
new_obj = getattr(obj, "__pytest_wrapped__", None)
235-
if isinstance(new_obj, _PytestWrapper):
236-
obj = new_obj.obj
218+
for _ in range(100):
219+
if isinstance(obj, FixtureFunctionDefinition):
220+
obj = obj.get_real_func()
237221
break
238222
new_obj = getattr(obj, "__wrapped__", None)
239223
if new_obj is None:

src/_pytest/fixtures.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
from _pytest._code.code import FormattedExcinfo
4343
from _pytest._code.code import TerminalRepr
4444
from _pytest._io import TerminalWriter
45-
from _pytest.compat import _PytestWrapper
4645
from _pytest.compat import assert_never
4746
from _pytest.compat import get_real_func
4847
from _pytest.compat import getfuncargnames
@@ -1204,7 +1203,6 @@ def __init__(
12041203
# Using isinstance on every object in code might execute code that is not intended to be executed.
12051204
# Like lazy loaded classes.
12061205
self._pytestfixturefunction = fixture_function_marker
1207-
self.__pytest_wrapped__ = _PytestWrapper(function)
12081206
self.fixture_function_marker = fixture_function_marker
12091207
self.fixture_function = function
12101208
self.instance = instance

testing/test_compat.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from typing import TYPE_CHECKING
88
from typing import Union
99

10-
from _pytest.compat import _PytestWrapper
1110
from _pytest.compat import assert_never
1211
from _pytest.compat import get_real_func
1312
from _pytest.compat import is_generator
@@ -52,8 +51,8 @@ def __getattr__(self, attr):
5251
with pytest.raises(
5352
ValueError,
5453
match=(
55-
"could not find real function of <Evil left=800>\n"
56-
"stopped at <Evil left=800>"
54+
"could not find real function of <Evil left=900>\n"
55+
"stopped at <Evil left=900>"
5756
),
5857
):
5958
get_real_func(evil)
@@ -78,10 +77,13 @@ def func():
7877
wrapped_func2 = decorator(decorator(wrapped_func))
7978
assert get_real_func(wrapped_func2) is func
8079

81-
# special case for __pytest_wrapped__ attribute: used to obtain the function up until the point
82-
# a function was wrapped by pytest itself
83-
wrapped_func2.__pytest_wrapped__ = _PytestWrapper(wrapped_func)
84-
assert get_real_func(wrapped_func2) is wrapped_func
80+
# obtain the function up until the point a function was wrapped by pytest itself
81+
@pytest.fixture
82+
def wrapped_func3():
83+
pass
84+
85+
wrapped_func4 = decorator(wrapped_func3)
86+
assert get_real_func(wrapped_func4) is wrapped_func3.get_real_func()
8587

8688

8789
def test_get_real_func_partial() -> None:

0 commit comments

Comments
 (0)