Open alexmojaki opened 6 years ago
Thanks for the report @alexmojaki!
This also appears to be relevant for doctests (https://github.com/Frozenball/pytest-sugar/issues/134). It was bisected to https://github.com/pytest-dev/pytest/commit/fbc45be83f279f936121355649728f7aeec6e6a6 (https://github.com/Frozenball/pytest-sugar/issues/134#issuecomment-406067245) - /cc @will133.
This is due to assertion rewriting, with --assert=plain
pytest also reports line 5.
Probably, bug is here: https://github.com/pytest-dev/pytest/blob/1df593f97890245a8eaaa89444a3ba7bada2a3b0/src/_pytest/assertion/rewrite.py#L891
Rewrite ignores multiline assert statements and uses assert.lineno - first assert line num (reporting do nothing wrong). Assert statement comes in one piece and there is no way for reporter to determine correct line for now. May be we can detect correct substatement line and attach to Assert object for future usage (by reporter a.k.a. error printer).
Another effect of what seems to be the same bug: lambda
objects used in an assert always use the line of the assert
. As a result, functions from the inspect
module may return wrong results when used on such lambda
.
I don't know whether it's used internally by pytest, but it may be used by the user to log some information. (That's how I stumbled on it.)
For instance, with the following code:
import inspect
def print_and_call(f):
print(inspect.getsource(f))
return f()
def test():
assert print_and_call(
lambda: True
)
pytest -s test.py
, the whole test()
function is printed.pytest -s --assert=plain test.py
, only the lambda: True
line is printed (as expected).
In the below example, the normal Python traceback correctly points to line 5, where the actual division by zero happens. pytest points to line 4.
Theoretically this certainly seems like a serious issue, but for the practical question of how often this is a problem, don't count me as a datapoint. I only noticed this problem while playing with some dark magic code that uses the line numbers of frames. The above example is completely contrived.