Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

typing: Improve FixtureDefinition and FixtureDef #12999

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
41c7c2c
feat: use repr for pytest fixtures
Glyphack Jun 18, 2024
cee9044
(fixture) create a new class to represent fixtures
Glyphack Jun 19, 2024
004f29f
fix: update code to use new fixture definitions
Glyphack Jun 20, 2024
224595a
Update AUTHORS
Glyphack Jun 20, 2024
8666dfb
chore: add changelog entry
Glyphack Jun 20, 2024
b724030
add test case for asserting missing fixture
Glyphack Jun 20, 2024
4552e06
refactor: removed PytestWrapper class
Glyphack Jun 20, 2024
1efc230
chore: update changelog
Glyphack Jun 20, 2024
b6f87a3
refactor: remove _pytestfixturefunction attribute
Glyphack Jun 20, 2024
bc69c19
refactor: remove unused code
Glyphack Jun 20, 2024
da5e8e9
ci: set no cover for test function
Glyphack Jun 20, 2024
ec7f7b1
docs: fix docstring
Glyphack Jun 20, 2024
f61c23c
refactor: replace attribute check with type check
Glyphack Jun 20, 2024
144befb
chore: update changelog
Glyphack Jun 20, 2024
e556218
test: add test for _get_wrapped_function
Glyphack Jun 20, 2024
a48b2a0
refactor: remove unused code
Glyphack Jun 20, 2024
c7d8339
refactor: replace type with isinstance
Glyphack Jun 20, 2024
6ba2370
docs: update docstring
Glyphack Jun 20, 2024
3bc5ad1
refactor: use instance check to print repr
Glyphack Jun 20, 2024
04a0cde
docs: ignore FixtureFunctionDefinition from docs
Glyphack Jun 20, 2024
9822c94
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 4, 2024
786aec5
Update changelog/11525.improvement.rst
Glyphack Jul 4, 2024
afe72f6
Update src/_pytest/fixtures.py
Glyphack Jul 4, 2024
3b66f72
Update src/_pytest/fixtures.py
Glyphack Jul 4, 2024
149cc30
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 4, 2024
eb3943c
Update src/_pytest/compat.py
Glyphack Jul 4, 2024
2891be5
fix: update fixture repr in text
Glyphack Jul 30, 2024
1734722
fix: check TypeError raised
Glyphack Jul 30, 2024
d749473
test: remove redundant test
Glyphack Oct 23, 2024
fa2f2b5
Fix tests
Glyphack Oct 23, 2024
1b5b4c7
Handle scenarios where fixture is renamed in decorator
Glyphack Oct 23, 2024
6ee850a
Add follow ups as todo comments
Glyphack Oct 27, 2024
131e306
Remove get_real_func loop
Glyphack Oct 27, 2024
f062ff6
Use _get_wrapped_function to unwrap fixtures
Glyphack Nov 23, 2024
7f1b8d3
Merge branch 'main' into reprs-assert-callable
Glyphack Nov 25, 2024
0c01079
Carry around ParamSpec and return value in FixtureFunctionDefinition
nicoddemus Nov 26, 2024
e18d519
Make FixtureDef a Generic to carry the ParamSpec of the fixture function
nicoddemus Nov 26, 2024
47c82fa
Fix import
nicoddemus Nov 26, 2024
8aa9998
Remove old FixtureFunction alias
nicoddemus Nov 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ Serhii Mozghovyi
Seth Junot
Shantanu Jain
Sharad Nair
Shaygan Hooshyari
Shubham Adep
Simon Blanchard
Simon Gomizelj
Expand Down
3 changes: 3 additions & 0 deletions changelog/11525.improvement.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
The fixtures are now represented as fixture in test output.

-- by :user:`the-compiler` and :user:`glyphack`
1 change: 1 addition & 0 deletions doc/en/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
("py:class", "_pytest._code.code.TerminalRepr"),
("py:class", "TerminalRepr"),
("py:class", "_pytest.fixtures.FixtureFunctionMarker"),
("py:class", "_pytest.fixtures.FixtureFunctionDefinition"),
("py:class", "_pytest.logging.LogCaptureHandler"),
("py:class", "_pytest.mark.structures.ParameterSet"),
# Intentionally undocumented/private
Expand Down
3 changes: 2 additions & 1 deletion src/_pytest/assertion/rewrite.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from _pytest._version import version
from _pytest.assertion import util
from _pytest.config import Config
from _pytest.fixtures import FixtureFunctionDefinition
from _pytest.main import Session
from _pytest.pathlib import absolutepath
from _pytest.pathlib import fnmatch_ex
Expand Down Expand Up @@ -472,7 +473,7 @@ def _format_assertmsg(obj: object) -> str:

def _should_repr_global_name(obj: object) -> bool:
if callable(obj):
return False
return isinstance(obj, FixtureFunctionDefinition)

try:
return not hasattr(obj, "__name__")
Expand Down
48 changes: 2 additions & 46 deletions src/_pytest/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

from __future__ import annotations

import dataclasses
import enum
import functools
import inspect
Expand Down Expand Up @@ -205,59 +204,16 @@ def ascii_escaped(val: bytes | str) -> str:
return ret.translate(_non_printable_ascii_translate_table)


@dataclasses.dataclass
class _PytestWrapper:
"""Dummy wrapper around a function object for internal use only.

Used to correctly unwrap the underlying function object when we are
creating fixtures, because we wrap the function object ourselves with a
decorator to issue warnings when the fixture function is called directly.
"""

obj: Any


def get_real_func(obj):
"""Get the real function object of the (possibly) wrapped object by
functools.wraps or functools.partial."""
start_obj = obj
for i in range(100):
# __pytest_wrapped__ is set by @pytest.fixture when wrapping the fixture function
# to trigger a warning if it gets called directly instead of by pytest: we don't
# want to unwrap further than this otherwise we lose useful wrappings like @mock.patch (#3774)
new_obj = getattr(obj, "__pytest_wrapped__", None)
if isinstance(new_obj, _PytestWrapper):
obj = new_obj.obj
break
new_obj = getattr(obj, "__wrapped__", None)
if new_obj is None:
break
obj = new_obj
else:
from _pytest._io.saferepr import saferepr
:func:`functools.wraps`, or :func:`functools.partial`."""
obj = inspect.unwrap(obj)

raise ValueError(
f"could not find real function of {saferepr(start_obj)}\nstopped at {saferepr(obj)}"
)
if isinstance(obj, functools.partial):
obj = obj.func
return obj


def get_real_method(obj, holder):
"""Attempt to obtain the real function object that might be wrapping
``obj``, while at the same time returning a bound method to ``holder`` if
the original object was a bound method."""
try:
is_method = hasattr(obj, "__func__")
obj = get_real_func(obj)
except Exception: # pragma: no cover
return obj
if is_method and hasattr(obj, "__get__") and callable(obj.__get__):
obj = obj.__get__(holder)
return obj


def getimfunc(func):
try:
return func.__func__
Expand Down
Loading
Loading