Skip to content

Show repr for callables used in an assert directly #11525

Closed
@The-Compiler

Description

@The-Compiler

With something like

import pytest

@pytest.fixture
def fixt():
    return 42

def test_something():  # missing "fixt" argument
    print(fixt)
    assert fixt == 42

(which is a common beginners mistake), pytest prints:

======================================= test session starts ========================================
collected 1 item

tmp31nzhe4b.py F                                                                             [100%]

============================================= FAILURES =============================================
__________________________________________ test_something __________________________________________

    def test_something():  # missing "fixt" argument
        print(fixt)
>       assert fixt == 42
E       assert fixt == 42

/tmp/ipykernel_77860/2395276065.py:9: AssertionError
--------------------------------------- Captured stdout call ---------------------------------------
<function fixt at 0x7fd7745c4160>
===================================== short test summary info ======================================
FAILED tmp31nzhe4b.py::test_something - assert fixt == 42
======================================== 1 failed in 0.03s =========================================

notably, without anything making it clear that fixt is a function, and not the value the user actually expected. Only when we print(fixt) it becomes clear that this is a function object and what the mistake was.

This is due to:

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

which was originally introduced in 65edf87.

The rationale for it can be found in the related issue:

and it boils down to:

I think in some cases it can result in too verbose output, especially when using builtins where you don't really want to have extra information on "len", "callable" etc.

and

Another reason for this heuristic occurred to me: Many commonly used global names like classes and modules are more nicely displayed by their name rather than their repr.

I believe this is useful in cases like assert len(values) == 2 where we really don't need to drill down into what len is. However, it hides vital information in the case that one side of the == is a global callable directly, rather than it being used as a part of a bigger expression.

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: reportingrelated to terminal output and user-facing messages and errors

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions