assertion: save/restore hooks on item (#6646)
This commit is contained in:
parent
1480aa31a7
commit
aa0328782f
|
@ -0,0 +1 @@
|
||||||
|
Assertion rewriting hooks are (re)stored for the current item, which fixes them being still used after e.g. pytester's :func:`testdir.runpytest <_pytest.pytester.Testdir.runpytest>` etc.
|
|
@ -8,6 +8,7 @@ from _pytest.assertion import rewrite
|
||||||
from _pytest.assertion import truncate
|
from _pytest.assertion import truncate
|
||||||
from _pytest.assertion import util
|
from _pytest.assertion import util
|
||||||
from _pytest.compat import TYPE_CHECKING
|
from _pytest.compat import TYPE_CHECKING
|
||||||
|
from _pytest.config import hookimpl
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from _pytest.main import Session
|
from _pytest.main import Session
|
||||||
|
@ -105,7 +106,8 @@ def pytest_collection(session: "Session") -> None:
|
||||||
assertstate.hook.set_session(session)
|
assertstate.hook.set_session(session)
|
||||||
|
|
||||||
|
|
||||||
def pytest_runtest_setup(item):
|
@hookimpl(tryfirst=True, hookwrapper=True)
|
||||||
|
def pytest_runtest_protocol(item):
|
||||||
"""Setup the pytest_assertrepr_compare and pytest_assertion_pass hooks
|
"""Setup the pytest_assertrepr_compare and pytest_assertion_pass hooks
|
||||||
|
|
||||||
The newinterpret and rewrite modules will use util._reprcompare if
|
The newinterpret and rewrite modules will use util._reprcompare if
|
||||||
|
@ -143,6 +145,7 @@ def pytest_runtest_setup(item):
|
||||||
return res
|
return res
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
saved_assert_hooks = util._reprcompare, util._assertion_pass
|
||||||
util._reprcompare = callbinrepr
|
util._reprcompare = callbinrepr
|
||||||
|
|
||||||
if item.ihook.pytest_assertion_pass.get_hookimpls():
|
if item.ihook.pytest_assertion_pass.get_hookimpls():
|
||||||
|
@ -154,10 +157,9 @@ def pytest_runtest_setup(item):
|
||||||
|
|
||||||
util._assertion_pass = call_assertion_pass_hook
|
util._assertion_pass = call_assertion_pass_hook
|
||||||
|
|
||||||
|
yield
|
||||||
|
|
||||||
def pytest_runtest_teardown(item):
|
util._reprcompare, util._assertion_pass = saved_assert_hooks
|
||||||
util._reprcompare = None
|
|
||||||
util._assertion_pass = None
|
|
||||||
|
|
||||||
|
|
||||||
def pytest_sessionfinish(session):
|
def pytest_sessionfinish(session):
|
||||||
|
|
|
@ -27,7 +27,6 @@ from pluggy import HookspecMarker
|
||||||
from pluggy import PluginManager
|
from pluggy import PluginManager
|
||||||
|
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
import _pytest.assertion
|
|
||||||
import _pytest.deprecated
|
import _pytest.deprecated
|
||||||
import _pytest.hookspec # the extension point definitions
|
import _pytest.hookspec # the extension point definitions
|
||||||
from .exceptions import PrintHelp
|
from .exceptions import PrintHelp
|
||||||
|
@ -260,6 +259,8 @@ class PytestPluginManager(PluginManager):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
import _pytest.assertion
|
||||||
|
|
||||||
super().__init__("pytest")
|
super().__init__("pytest")
|
||||||
# The objects are module objects, only used generically.
|
# The objects are module objects, only used generically.
|
||||||
self._conftest_plugins = set() # type: Set[object]
|
self._conftest_plugins = set() # type: Set[object]
|
||||||
|
@ -891,6 +892,8 @@ class Config:
|
||||||
ns, unknown_args = self._parser.parse_known_and_unknown_args(args)
|
ns, unknown_args = self._parser.parse_known_and_unknown_args(args)
|
||||||
mode = getattr(ns, "assertmode", "plain")
|
mode = getattr(ns, "assertmode", "plain")
|
||||||
if mode == "rewrite":
|
if mode == "rewrite":
|
||||||
|
import _pytest.assertion
|
||||||
|
|
||||||
try:
|
try:
|
||||||
hook = _pytest.assertion.install_importhook(self)
|
hook = _pytest.assertion.install_importhook(self)
|
||||||
except SystemError:
|
except SystemError:
|
||||||
|
|
|
@ -72,10 +72,19 @@ class TestImportHookInstallation:
|
||||||
result = testdir.runpytest_subprocess()
|
result = testdir.runpytest_subprocess()
|
||||||
result.stdout.fnmatch_lines(
|
result.stdout.fnmatch_lines(
|
||||||
[
|
[
|
||||||
"E * AssertionError: ([[][]], [[][]], [[]<TestReport *>[]])*",
|
"> r.assertoutcome(passed=1)",
|
||||||
"E * assert"
|
"E AssertionError: ([[][]], [[][]], [[]<TestReport *>[]])*",
|
||||||
" {'failed': 1, 'passed': 0, 'skipped': 0} =="
|
"E assert {'failed': 1,... 'skipped': 0} == {'failed': 0,... 'skipped': 0}",
|
||||||
" {'failed': 0, 'passed': 1, 'skipped': 0}",
|
"E Omitting 1 identical items, use -vv to show",
|
||||||
|
"E Differing items:",
|
||||||
|
"E Use -v to get the full diff",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
# XXX: unstable output.
|
||||||
|
result.stdout.fnmatch_lines_random(
|
||||||
|
[
|
||||||
|
"E {'failed': 1} != {'failed': 0}",
|
||||||
|
"E {'passed': 0} != {'passed': 1}",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue