From d441fa66fea052d04364acb6fc67c3b3cc0217c0 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Fri, 15 Mar 2019 02:47:06 +0100 Subject: [PATCH 1/9] Fix line offsets with `ScopeMismatch` errors Fixes https://github.com/pytest-dev/pytest/issues/4928. --- changelog/4928.bugfix.rst | 1 + src/_pytest/fixtures.py | 2 +- testing/python/fixture.py | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 changelog/4928.bugfix.rst diff --git a/changelog/4928.bugfix.rst b/changelog/4928.bugfix.rst new file mode 100644 index 00000000000..8959efacba2 --- /dev/null +++ b/changelog/4928.bugfix.rst @@ -0,0 +1 @@ +Fix line offsets with ``ScopeMismatch`` errors. diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index b2ad9aae397..5dc803d66b6 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -612,7 +612,7 @@ def _factorytraceback(self): fs, lineno = getfslineno(factory) p = self._pyfuncitem.session.fspath.bestrelpath(fs) args = _format_args(factory) - lines.append("%s:%d: def %s%s" % (p, lineno, factory.__name__, args)) + lines.append("%s:%d: def %s%s" % (p, lineno + 1, factory.__name__, args)) return lines def _getscopeitem(self, scope): diff --git a/testing/python/fixture.py b/testing/python/fixture.py index 3d557cec85b..53df1990b24 100644 --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -992,8 +992,8 @@ def test_add(arg2): result.stdout.fnmatch_lines( [ "*ScopeMismatch*involved factories*", - "* def arg2*", - "* def arg1*", + "test_receives_funcargs_scope_mismatch.py:6: def arg2(arg1)", + "test_receives_funcargs_scope_mismatch.py:2: def arg1()", "*1 error*", ] ) From 1e3d5a0412a2e9550fc9a5a6de3e44323471832e Mon Sep 17 00:00:00 2001 From: henrykironde Date: Sun, 17 Mar 2019 20:36:10 -0400 Subject: [PATCH 2/9] Add example for k flag Includes an example of multiple expressions --- src/_pytest/mark/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/_pytest/mark/__init__.py b/src/_pytest/mark/__init__.py index bc4c467f918..e7f08e163f6 100644 --- a/src/_pytest/mark/__init__.py +++ b/src/_pytest/mark/__init__.py @@ -52,6 +52,7 @@ def pytest_addoption(parser): "other' matches all test functions and classes whose name " "contains 'test_method' or 'test_other', while -k 'not test_method' " "matches those that don't contain 'test_method' in their names. " + "-k 'not test_method and not test_other' will eliminate the matches. " "Additionally keywords are matched to classes and functions " "containing extra names in their 'extra_keyword_matches' set, " "as well as functions which have names assigned directly to them.", From 2ade3d5c89b93ea59ff287c05cbe67672b471cfe Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Wed, 20 Mar 2019 18:37:34 +0100 Subject: [PATCH 3/9] ci: rename "trial" tox factor to "twisted" Ref: https://github.com/pytest-dev/pytest/pull/4848#issuecomment-467909204 --- .travis.yml | 4 ++-- azure-pipelines.yml | 10 +++++----- tox.ini | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 750f93f81d4..183cd6156bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -68,7 +68,7 @@ jobs: # Specialized factors for py37. # Coverage for: # - test_sys_breakpoint_interception (via pexpect). - - env: TOXENV=py37-pexpect,py37-trial PYTEST_COVERAGE=1 + - env: TOXENV=py37-pexpect,py37-twisted PYTEST_COVERAGE=1 - env: TOXENV=py37-pluggymaster-xdist - env: TOXENV=py37-freeze @@ -80,7 +80,7 @@ jobs: - stage: baseline # Coverage for: # - _pytest.unittest._handle_skip (via pexpect). - env: TOXENV=py27-pexpect,py27-trial PYTEST_COVERAGE=1 + env: TOXENV=py27-pexpect,py27-twisted PYTEST_COVERAGE=1 python: '2.7' # Use py36 here for faster baseline. - env: TOXENV=py36-xdist diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 712106c94e2..38d893ad414 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -30,9 +30,9 @@ jobs: # - numpy # - pytester's LsofFdLeakChecker (being skipped) PYTEST_COVERAGE: '1' - py27-trial: + py27-twisted: python.version: '2.7' - tox.env: 'py27-trial' + tox.env: 'py27-twisted' python.needs_vc: True py27-pluggymaster-xdist: python.version: '2.7' @@ -40,7 +40,7 @@ jobs: # Coverage for: # - except-IOError in _attempt_to_close_capture_file for py2. # Also seen with py27-nobyte (using xdist), and py27-xdist. - # But no exception with py27-pexpect,py27-trial,py27-numpy. + # But no exception with py27-pexpect,py27-twisted,py27-numpy. PYTEST_COVERAGE: '1' pypy: python.version: 'pypy' @@ -76,9 +76,9 @@ jobs: py37-linting/docs/doctesting: python.version: '3.7' tox.env: 'linting,docs,doctesting' - py37-trial/numpy: + py37-twisted/numpy: python.version: '3.7' - tox.env: 'py37-trial,py37-numpy' + tox.env: 'py37-twisted,py37-numpy' py37-pluggymaster-xdist: python.version: '3.7' tox.env: 'py37-pluggymaster-xdist' diff --git a/tox.ini b/tox.ini index 97cac6f6bde..180f7755cf7 100644 --- a/tox.ini +++ b/tox.ini @@ -13,7 +13,7 @@ envlist = py38 pypy pypy3 - {py27,py37}-{pexpect,xdist,trial,numpy,pluggymaster} + {py27,py37}-{pexpect,xdist,twisted,numpy,pluggymaster} py27-nobyte-xdist doctesting py37-freeze @@ -67,7 +67,7 @@ basepython = python3 deps = pre-commit>=1.11.0 commands = pre-commit run --all-files --show-diff-on-failure -[testenv:py27-trial] +[testenv:py27-twisted] deps = {[testenv]deps} twisted @@ -75,9 +75,9 @@ deps = commands = {env:_PYTEST_TOX_COVERAGE_RUN:} pytest {posargs:testing/test_unittest.py} -[testenv:py37-trial] -deps = {[testenv:py27-trial]deps} -commands = {[testenv:py27-trial]commands} +[testenv:py37-twisted] +deps = {[testenv:py27-twisted]deps} +commands = {[testenv:py27-twisted]commands} [testenv:docs] basepython = python3 From 543779fc43a5f5c847e08bf2789c306d0dcf01a7 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Wed, 20 Mar 2019 18:41:48 +0100 Subject: [PATCH 4/9] tox: generic twisted factor --- tox.ini | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/tox.ini b/tox.ini index 180f7755cf7..352bdc51408 100644 --- a/tox.ini +++ b/tox.ini @@ -26,7 +26,7 @@ commands = coverage: coverage report passenv = USER USERNAME COVERAGE_* TRAVIS PYTEST_ADDOPTS setenv = - _PYTEST_TOX_DEFAULT_POSARGS={env:_PYTEST_TOX_POSARGS_LSOF:} {env:_PYTEST_TOX_POSARGS_PEXPECT:} {env:_PYTEST_TOX_POSARGS_XDIST:} + _PYTEST_TOX_DEFAULT_POSARGS={env:_PYTEST_TOX_POSARGS_LSOF:} {env:_PYTEST_TOX_POSARGS_PEXPECT:} {env:_PYTEST_TOX_POSARGS_TWISTED:} {env:_PYTEST_TOX_POSARGS_XDIST:} # Configuration to run with coverage similar to Travis/Appveyor, e.g. # "tox -e py37-coverage". @@ -42,12 +42,16 @@ setenv = pexpect: _PYTEST_TOX_PLATFORM=linux|darwin pexpect: _PYTEST_TOX_POSARGS_PEXPECT=testing/test_pdb.py testing/test_terminal.py testing/test_unittest.py + twisted: _PYTEST_TOX_POSARGS_TWISTED=testing/test_unittest.py + xdist: _PYTEST_TOX_POSARGS_XDIST=-n auto extras = testing deps = numpy: numpy pexpect: pexpect pluggymaster: git+https://github.com/pytest-dev/pluggy.git@master + twisted: twisted + twisted: unittest2 xdist: pytest-xdist>=1.13 {env:_PYTEST_TOX_EXTRA_DEP:} platform = {env:_PYTEST_TOX_PLATFORM:.*} @@ -67,18 +71,6 @@ basepython = python3 deps = pre-commit>=1.11.0 commands = pre-commit run --all-files --show-diff-on-failure -[testenv:py27-twisted] -deps = - {[testenv]deps} - twisted - unittest2 -commands = - {env:_PYTEST_TOX_COVERAGE_RUN:} pytest {posargs:testing/test_unittest.py} - -[testenv:py37-twisted] -deps = {[testenv:py27-twisted]deps} -commands = {[testenv:py27-twisted]commands} - [testenv:docs] basepython = python3 skipsdist = True From dcbdcc729ba36b7ea89fc900bfd67f6ead3d585a Mon Sep 17 00:00:00 2001 From: Brian Skinn Date: Thu, 21 Mar 2019 15:14:28 -0400 Subject: [PATCH 5/9] Fix pytestmark syntax in reference.rst pytest 4.3.1 throws an error if `pytestmark` is set to a tuple of marks; it appears to insist on a list. With `pytestmark = [pytest.mark.api, pytest.mark.good]`: ``` ============================== test session starts ============================== platform win32 -- Python 3.6.3, pytest-4.3.1, py-1.8.0, pluggy-0.9.0 rootdir: C:\Temp\git\sphobjinv, inifile: tox.ini plugins: timeout-1.3.3 collected 48 items / 41 deselected / 7 selected tests\test_api_good.py ....... [100%] ==================== 7 passed, 41 deselected in 0.15 seconds ==================== ``` With `pytestmark = (pytest.mark.api, pytest.mark.good)`: ``` ==================================== ERRORS ===================================== ____________________ ERROR collecting tests/test_api_good.py ____________________ env\lib\site-packages\_pytest\runner.py:226: in from_call result = func() env\lib\site-packages\_pytest\runner.py:289: in call = CallInfo.from_call(lambda: list(collector.collect()), "collect") env\lib\site-packages\_pytest\python.py:435: in collect self._inject_setup_module_fixture() env\lib\site-packages\_pytest\python.py:447: in _inject_setup_module_fixture setup_module = _get_non_fixture_func(self.obj, "setUpModule") env\lib\site-packages\_pytest\python.py:255: in obj self.own_markers.extend(get_unpacked_marks(self.obj)) env\lib\site-packages\_pytest\mark\structures.py:244: in get_unpacked_marks return normalize_mark_list(mark_list) env\lib\site-packages\_pytest\mark\structures.py:259: in normalize_mark_list raise TypeError("got {!r} instead of Mark".format(mark)) E TypeError: got (MarkDecorator(mark=Mark(name='api', args=(), kwargs={})), MarkDecorator(mark=Mark(name='good', args=(), kwargs={}))) instead of Mark !!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!! ==================== 19 deselected, 1 error in 0.27 seconds ===================== ``` --- doc/en/reference.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/en/reference.rst b/doc/en/reference.rst index bd89d024dce..94889b91363 100644 --- a/doc/en/reference.rst +++ b/doc/en/reference.rst @@ -883,7 +883,7 @@ pytest_mark **Tutorial**: :ref:`scoped-marking` Can be declared at the **global** level in *test modules* to apply one or more :ref:`marks ` to all -test functions and methods. Can be either a single mark or a sequence of marks. +test functions and methods. Can be either a single mark or a list of marks. .. code-block:: python @@ -896,7 +896,7 @@ test functions and methods. Can be either a single mark or a sequence of marks. import pytest - pytestmark = (pytest.mark.integration, pytest.mark.slow) + pytestmark = [pytest.mark.integration, pytest.mark.slow] PYTEST_DONT_REWRITE (module docstring) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 0642da01450840a66ba0c43d6e86011c44e9d863 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Fri, 22 Mar 2019 17:46:16 +0100 Subject: [PATCH 6/9] .coveragerc: use "src" only from current dir This avoids including generated test files with "src" in their path. --- .coveragerc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.coveragerc b/.coveragerc index b5cfb9e7bc4..cbc6c5c5084 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,6 +1,6 @@ [run] include = - */src/* + src/* testing/* */lib/python*/site-packages/_pytest/* */lib/python*/site-packages/pytest.py From d0f3f26fffccd16e349518f9a5f83dcce4e37d12 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 23 Mar 2019 23:14:39 +0100 Subject: [PATCH 7/9] test_collect_capturing: cover captured stderr --- testing/test_capture.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/testing/test_capture.py b/testing/test_capture.py index 5ed806fa4df..14eae7efaaf 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -134,12 +134,22 @@ def test_unicode(): def test_collect_capturing(testdir): p = testdir.makepyfile( """ + import sys + print("collect %s failure" % 13) + sys.stderr.write("collect %s_stderr failure" % 13) import xyz42123 """ ) result = testdir.runpytest(p) - result.stdout.fnmatch_lines(["*Captured stdout*", "*collect 13 failure*"]) + result.stdout.fnmatch_lines( + [ + "*Captured stdout*", + "collect 13 failure", + "*Captured stderr*", + "collect 13_stderr failure", + ] + ) class TestPerTestCapturing(object): From 3127ec737b107466654680ad785863b7c044d0da Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sun, 24 Mar 2019 11:04:05 +0100 Subject: [PATCH 8/9] Fix pytest's own tests with `-W error::ResourceWarning` --- testing/python/fixture.py | 1 + testing/test_session.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/testing/python/fixture.py b/testing/python/fixture.py index 53df1990b24..64f9a97c19a 100644 --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -1103,6 +1103,7 @@ def __init__(self, request): values = reprec.getfailedcollections() assert len(values) == 1 + @pytest.mark.filterwarnings("ignore::pytest.PytestDeprecationWarning") def test_request_can_be_overridden(self, testdir): testdir.makepyfile( """ diff --git a/testing/test_session.py b/testing/test_session.py index 6b185f76b19..6f01bd3bfc3 100644 --- a/testing/test_session.py +++ b/testing/test_session.py @@ -116,7 +116,8 @@ def __repr__(self): class TestBrokenClass(object): def test_explicit_bad_repr(self): t = BrokenRepr1() - pytest.raises(Exception, 'repr(t)') + with pytest.raises(Exception, match="I'm a broken repr"): + repr(t) def test_implicit_bad_repr1(self): t = BrokenRepr1() From 0ea18892657ec3adc61f0c3e02f7cc8c13b0f35c Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sun, 24 Mar 2019 11:17:55 +0100 Subject: [PATCH 9/9] test_as_errors: use subprocess with `-W` Ref: https://github.com/pytest-dev/pytest/pull/4981 --- testing/test_warnings.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/testing/test_warnings.py b/testing/test_warnings.py index 1b4231edc5b..929ae8d607f 100644 --- a/testing/test_warnings.py +++ b/testing/test_warnings.py @@ -95,10 +95,12 @@ def test_as_errors(testdir, pyfile_with_warnings, method): testdir.makeini( """ [pytest] - filterwarnings= error + filterwarnings=error """ ) - result = testdir.runpytest(*args) + # Use a subprocess, since changing logging level affects other threads + # (xdist). + result = testdir.runpytest_subprocess(*args) result.stdout.fnmatch_lines( [ "E UserWarning: user warning",