Skip to content

Commit

Permalink
[WIP/RFC] assert: keep "where … and …" output in verbose mode
Browse files Browse the repository at this point in the history
  • Loading branch information
blueyed committed Oct 9, 2019
1 parent 3fada8c commit 1543a16
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 8 deletions.
9 changes: 6 additions & 3 deletions src/_pytest/assertion/__init__.py
Expand Up @@ -110,8 +110,8 @@ def pytest_runtest_setup(item):
comparison for the test.
"""

def callbinrepr(op, left, right):
# type: (str, object, object) -> Optional[str]
def callbinrepr(op, left, right, expl):
# type: (str, object, object, str) -> Optional[str]
"""Call the pytest_assertrepr_compare hook and prepare the result
This uses the first result from the hook and then ensures the
Expand All @@ -127,10 +127,13 @@ def callbinrepr(op, left, right):
pretty printing.
"""
hook_result = item.ihook.pytest_assertrepr_compare(
config=item.config, op=op, left=left, right=right
config=item.config, op=op, left=left, right=right, expl=expl
)
for new_expl in hook_result:
if new_expl:
if isinstance(new_expl, str):
return new_expl

new_expl = truncate.truncate_if_required(new_expl, item)
new_expl = [line.replace("\n", "\\n") for line in new_expl]
res = "\n~".join(new_expl)
Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/assertion/rewrite.py
Expand Up @@ -392,7 +392,7 @@ def _call_reprcompare(ops, results, expls, each_obj):
if done:
break
if util._reprcompare is not None:
custom = util._reprcompare(ops[i], each_obj[i], each_obj[i + 1])
custom = util._reprcompare(ops[i], each_obj[i], each_obj[i + 1], expl)
if custom is not None:
return custom
return expl
Expand Down
8 changes: 5 additions & 3 deletions src/_pytest/assertion/util.py
Expand Up @@ -14,7 +14,9 @@
# interpretation code and assertion rewriter to detect this plugin was
# loaded and in turn call the hooks defined here as part of the
# DebugInterpreter.
_reprcompare = None # type: Optional[Callable[[str, object, object], Optional[str]]]
_reprcompare = (
None
) # type: Optional[Callable[[str, object, object, str], Optional[str]]]

# Works similarly as _reprcompare attribute. Is populated with the hook call
# when pytest_runtest_setup is called.
Expand Down Expand Up @@ -121,7 +123,7 @@ def isiterable(obj):
return False


def assertrepr_compare(config, op, left, right):
def assertrepr_compare(config, op, left, right, expl):
"""Return specialised explanations for some operators/operands"""
maxsize = (80 - 15 - len(op) - 2) // 2 # 15 chars indentation, 1 space around op
left_repr = saferepr(left, maxsize=maxsize)
Expand All @@ -146,7 +148,7 @@ def assertrepr_compare(config, op, left, right):
type_fn = (isdatacls, isattrs)
explanation = _compare_eq_cls(left, right, verbose, type_fn)
elif verbose > 0:
explanation = _compare_eq_verbose(left, right)
return expl + "\n~" + "\n~".join(_compare_eq_verbose(left, right))
if isiterable(left) and isiterable(right):
expl = _compare_eq_iterable(left, right, verbose)
if explanation is not None:
Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/hookspec.py
Expand Up @@ -472,7 +472,7 @@ def pytest_unconfigure(config):
# -------------------------------------------------------------------------


def pytest_assertrepr_compare(config, op, left, right):
def pytest_assertrepr_compare(config, op, left, right, expl):
"""return explanation for comparisons in failing assert expressions.
Return None for no custom explanation, otherwise return a list
Expand Down

0 comments on commit 1543a16

Please sign in to comment.