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

[RFC] assert: keep "where … and …" output in verbose mode #5933

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't get the "\n~" part...? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update the docstring with expl as well. 😁

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would need more updating in general then, especially for when we go with the return-string-to-skip special postprocessing approach.

"""return explanation for comparisons in failing assert expressions.

Return None for no custom explanation, otherwise return a list
Expand Down