Skip to content

Commit f8167db

Browse files
committed
refactor: move get_real_func to fixtures.py
1 parent 9ac53d9 commit f8167db

File tree

6 files changed

+42
-48
lines changed

6 files changed

+42
-48
lines changed

src/_pytest/_code/code.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@
4545
from _pytest._io import TerminalWriter
4646
from _pytest._io.saferepr import safeformat
4747
from _pytest._io.saferepr import saferepr
48-
from _pytest.compat import get_real_func
4948
from _pytest.deprecated import check_ispytest
49+
from _pytest.fixtures import get_real_func
5050
from _pytest.pathlib import absolutepath
5151
from _pytest.pathlib import bestrelpath
5252

src/_pytest/compat.py

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@
44
from __future__ import annotations
55

66
import enum
7-
import functools
87
import inspect
98
from inspect import Parameter
109
from inspect import signature
1110
import os
12-
from pathlib import Path
1311
import sys
1412
from typing import Any
1513
from typing import Callable
@@ -65,20 +63,6 @@ def is_async_function(func: object) -> bool:
6563
return iscoroutinefunction(func) or inspect.isasyncgenfunction(func)
6664

6765

68-
def getlocation(function, curdir: str | os.PathLike[str] | None = None) -> str:
69-
function = get_real_func(function)
70-
fn = Path(inspect.getfile(function))
71-
lineno = function.__code__.co_firstlineno
72-
if curdir is not None:
73-
try:
74-
relfn = fn.relative_to(curdir)
75-
except ValueError:
76-
pass
77-
else:
78-
return "%s:%d" % (relfn, lineno + 1)
79-
return "%s:%d" % (fn, lineno + 1)
80-
81-
8266
def num_mock_patch_args(function) -> int:
8367
"""Return number of arguments used up by mock arguments (if any)."""
8468
patchings = getattr(function, "patchings", None)
@@ -209,31 +193,6 @@ def ascii_escaped(val: bytes | str) -> str:
209193
return ret.translate(_non_printable_ascii_translate_table)
210194

211195

212-
def get_real_func(obj):
213-
"""Get the real function object of the (possibly) wrapped object by
214-
:func:`functools.wraps`, or :func:`functools.partial`, or :func:`pytest.fixture`."""
215-
from _pytest.fixtures import FixtureFunctionDefinition
216-
217-
start_obj = obj
218-
for _ in range(100):
219-
if isinstance(obj, FixtureFunctionDefinition):
220-
obj = obj._get_wrapped_function()
221-
break
222-
new_obj = getattr(obj, "__wrapped__", None)
223-
if new_obj is None:
224-
break
225-
obj = new_obj
226-
else:
227-
from _pytest._io.saferepr import saferepr
228-
229-
raise ValueError(
230-
f"could not find real function of {saferepr(start_obj)}\nstopped at {saferepr(obj)}"
231-
)
232-
if isinstance(obj, functools.partial):
233-
obj = obj.func
234-
return obj
235-
236-
237196
def getimfunc(func):
238197
try:
239198
return func.__func__

src/_pytest/fixtures.py

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,7 @@
4343
from _pytest._code.code import TerminalRepr
4444
from _pytest._io import TerminalWriter
4545
from _pytest.compat import assert_never
46-
from _pytest.compat import get_real_func
47-
from _pytest.compat import getfuncargnames
4846
from _pytest.compat import getimfunc
49-
from _pytest.compat import getlocation
5047
from _pytest.compat import is_generator
5148
from _pytest.compat import NOTSET
5249
from _pytest.compat import NotSetType
@@ -58,6 +55,7 @@
5855
from _pytest.deprecated import check_ispytest
5956
from _pytest.deprecated import MARKED_FIXTURE
6057
from _pytest.deprecated import YIELD_FIXTURE
58+
from _pytest.fixtures import getfuncargnames
6159
from _pytest.main import Session
6260
from _pytest.mark import Mark
6361
from _pytest.mark import ParameterSet
@@ -1914,3 +1912,40 @@ def _showfixtures_main(config: Config, session: Session) -> None:
19141912
def write_docstring(tw: TerminalWriter, doc: str, indent: str = " ") -> None:
19151913
for line in doc.split("\n"):
19161914
tw.line(indent + line)
1915+
1916+
1917+
def get_real_func(obj):
1918+
"""Get the real function object of the (possibly) wrapped object by
1919+
:func:`functools.wraps`, or :func:`functools.partial`, or :func:`pytest.fixture`."""
1920+
start_obj = obj
1921+
for _ in range(100):
1922+
if isinstance(obj, FixtureFunctionDefinition):
1923+
obj = obj._get_wrapped_function()
1924+
break
1925+
new_obj = getattr(obj, "__wrapped__", None)
1926+
if new_obj is None:
1927+
break
1928+
obj = new_obj
1929+
else:
1930+
from _pytest._io.saferepr import saferepr
1931+
1932+
raise ValueError(
1933+
f"could not find real function of {saferepr(start_obj)}\nstopped at {saferepr(obj)}"
1934+
)
1935+
if isinstance(obj, functools.partial):
1936+
obj = obj.func
1937+
return obj
1938+
1939+
1940+
def getlocation(function, curdir: str | os.PathLike[str] | None = None) -> str:
1941+
function = get_real_func(function)
1942+
fn = Path(inspect.getfile(function))
1943+
lineno = function.__code__.co_firstlineno
1944+
if curdir is not None:
1945+
try:
1946+
relfn = fn.relative_to(curdir)
1947+
except ValueError:
1948+
pass
1949+
else:
1950+
return "%s:%d" % (relfn, lineno + 1)
1951+
return "%s:%d" % (fn, lineno + 1)

src/_pytest/python.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
from _pytest._io.saferepr import saferepr
4141
from _pytest.compat import ascii_escaped
4242
from _pytest.compat import get_default_arg_names
43-
from _pytest.compat import get_real_func
4443
from _pytest.compat import getimfunc
4544
from _pytest.compat import is_async_function
4645
from _pytest.compat import is_generator
@@ -55,6 +54,7 @@
5554
from _pytest.fixtures import FixtureDef
5655
from _pytest.fixtures import FixtureRequest
5756
from _pytest.fixtures import FuncFixtureInfo
57+
from _pytest.fixtures import get_real_func
5858
from _pytest.fixtures import get_scope_node
5959
from _pytest.main import Session
6060
from _pytest.mark import MARK_GEN

testing/code/test_source.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ def test_comment_in_statement() -> None:
464464

465465
def test_source_with_decorator() -> None:
466466
"""Test behavior with Source / Code().source with regard to decorators."""
467-
from _pytest.compat import get_real_func
467+
from _pytest.fixtures import get_real_func
468468

469469
@pytest.mark.foo
470470
def deco_mark():

testing/test_compat.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
from typing import TYPE_CHECKING
1010

1111
from _pytest.compat import assert_never
12-
from _pytest.compat import get_real_func
1312
from _pytest.compat import is_generator
1413
from _pytest.compat import safe_getattr
1514
from _pytest.compat import safe_isclass
15+
from _pytest.fixtures import get_real_func
1616
from _pytest.outcomes import OutcomeException
1717
from _pytest.pytester import Pytester
1818
import pytest

0 commit comments

Comments
 (0)