diff --git a/py/_code/_assertionnew.py b/py/_code/_assertionnew.py index a80ae898c..192eecfce 100644 --- a/py/_code/_assertionnew.py +++ b/py/_code/_assertionnew.py @@ -108,10 +108,16 @@ unary_map = { class DebugInterpreter(ast.NodeVisitor): - """Interpret AST nodes to gleam useful debugging information.""" + """Interpret AST nodes to gleam useful debugging information. + + The _pytesthook attribute is used to detect if the py.test + pytest_assertion plugin is loaded and if so call it's hooks. + """ def __init__(self, frame): self.frame = frame + self._pytesthook = getattr(py.builtin.builtins.AssertionError, + "_pytesthook") def generic_visit(self, node): # Fallback when we don't have a special implementation. @@ -177,13 +183,14 @@ class DebugInterpreter(ast.NodeVisitor): if not result: break left_explanation, left_result = next_explanation, next_result - hook_result = py.test.config.hook.pytest_assert_compare( - op=op_symbol, left=left_result, right=next_result) - if hook_result: - for new_expl in hook_result: - if new_expl: - explanation = '\n~'.join(new_expl) - break + if self._pytesthook: + hook_result = self._pytesthook.pytest_assert_compare( + op=op_symbol, left=left_result, right=next_result) + if hook_result: + for new_expl in hook_result: + if new_expl: + explanation = '\n~'.join(new_expl) + break return explanation, result def visit_BoolOp(self, boolop): diff --git a/py/_plugin/pytest_assertion.py b/py/_plugin/pytest_assertion.py index 8f2aa5b22..2816671ab 100644 --- a/py/_plugin/pytest_assertion.py +++ b/py/_plugin/pytest_assertion.py @@ -8,10 +8,15 @@ def pytest_addoption(parser): help="disable python assert expression reinterpretation."), def pytest_configure(config): + # The _pytesthook attribute on the AssertionError is used by + # py._code._assertionnew to detect this plugin was loaded and in + # turn call the hooks defined here as part of the + # DebugInterpreter. if not config.getvalue("noassert") and not config.getvalue("nomagic"): warn_about_missing_assertion() config._oldassertion = py.builtin.builtins.AssertionError py.builtin.builtins.AssertionError = py.code._AssertionError + py.builtin.builtins.AssertionError._pytesthook = config.hook def pytest_unconfigure(config): if hasattr(config, '_oldassertion'):