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

Fix off-by-one error with lineno in mark collection error #5003

Merged
merged 1 commit into from
Mar 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/5003.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix line offset with mark collection error (off by one).
4 changes: 3 additions & 1 deletion src/_pytest/_code/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,9 @@ def compile_(source, filename=None, mode="exec", flags=0, dont_inherit=0):

def getfslineno(obj):
""" Return source location (path, lineno) for the given object.
If the source cannot be determined return ("", -1)
If the source cannot be determined return ("", -1).

The line number is 0-based.
"""
from .code import Code

Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/mark/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def get_empty_parameterset_mark(config, argnames, func):
f_name = func.__name__
_, lineno = getfslineno(func)
raise Collector.CollectError(
"Empty parameter set in '%s' at line %d" % (f_name, lineno)
"Empty parameter set in '%s' at line %d" % (f_name, lineno + 1)
)
else:
raise LookupError(requested_mark)
Expand Down
35 changes: 25 additions & 10 deletions testing/test_mark.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import six

import pytest
from _pytest.main import EXIT_INTERRUPTED
from _pytest.mark import EMPTY_PARAMETERSET_OPTION
from _pytest.mark import MarkGenerator as Mark
from _pytest.nodes import Collector
Expand Down Expand Up @@ -859,20 +860,34 @@ def test_parameterset_for_fail_at_collect(testdir):

config = testdir.parseconfig()
from _pytest.mark import pytest_configure, get_empty_parameterset_mark
from _pytest.compat import getfslineno

pytest_configure(config)

test_func = all
func_name = test_func.__name__
_, func_lineno = getfslineno(test_func)
expected_errmsg = r"Empty parameter set in '%s' at line %d" % (
func_name,
func_lineno,
)
with pytest.raises(
Collector.CollectError,
match=r"Empty parameter set in 'pytest_configure' at line \d\d+",
):
get_empty_parameterset_mark(config, ["a"], pytest_configure)

p1 = testdir.makepyfile(
"""
import pytest

with pytest.raises(Collector.CollectError, match=expected_errmsg):
get_empty_parameterset_mark(config, ["a"], test_func)
@pytest.mark.parametrize("empty", [])
def test():
pass
"""
)
result = testdir.runpytest(str(p1))
result.stdout.fnmatch_lines(
[
"collected 0 items / 1 errors",
"* ERROR collecting test_parameterset_for_fail_at_collect.py *",
"Empty parameter set in 'test' at line 3",
"*= 1 error in *",
]
)
assert result.ret == EXIT_INTERRUPTED


def test_parameterset_for_parametrize_bad_markname(testdir):
Expand Down