File tree Expand file tree Collapse file tree 3 files changed +15
-31
lines changed Expand file tree Collapse file tree 3 files changed +15
-31
lines changed Original file line number Diff line number Diff line change 33
44from __future__ import annotations
55
6- import dataclasses
76import enum
87import functools
98import 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-
226212def 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 :
Original file line number Diff line number Diff line change 4242from _pytest ._code .code import FormattedExcinfo
4343from _pytest ._code .code import TerminalRepr
4444from _pytest ._io import TerminalWriter
45- from _pytest .compat import _PytestWrapper
4645from _pytest .compat import assert_never
4746from _pytest .compat import get_real_func
4847from _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
Original file line number Diff line number Diff line change 77from typing import TYPE_CHECKING
88from typing import Union
99
10- from _pytest .compat import _PytestWrapper
1110from _pytest .compat import assert_never
1211from _pytest .compat import get_real_func
1312from _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
8789def test_get_real_func_partial () -> None :
You can’t perform that action at this time.
0 commit comments