From 2fcf21a6c7c3b77f7284fdc9bd11b06bed257c59 Mon Sep 17 00:00:00 2001 From: James Cooke Date: Fri, 20 Sep 2019 18:36:25 +0100 Subject: [PATCH 01/18] Fix logging doc: change x.level to x.levelno --- doc/en/logging.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/en/logging.rst b/doc/en/logging.rst index c32205f13..e6f91cdf7 100644 --- a/doc/en/logging.rst +++ b/doc/en/logging.rst @@ -161,7 +161,7 @@ the records for the ``setup`` and ``call`` stages during teardown like so: yield window for when in ("setup", "call"): messages = [ - x.message for x in caplog.get_records(when) if x.level == logging.WARNING + x.message for x in caplog.get_records(when) if x.levelno == logging.WARNING ] if messages: pytest.fail( From de8fdab7a97b958ed5e85729114e8bb6689e05fe Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 21 Sep 2019 14:40:24 -0300 Subject: [PATCH 02/18] Change report-coverage.sh in attempt to fix Azure Recently sometimes Azure has failed with: ++ curl -s https://codecov.io/bash bash: /dev/fd/63: No such file or directory This attempts to fix this by modifying report-coverage.sh slightly. --- scripts/report-coverage.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/report-coverage.sh b/scripts/report-coverage.sh index 755783d2a..362dab091 100755 --- a/scripts/report-coverage.sh +++ b/scripts/report-coverage.sh @@ -13,4 +13,5 @@ fi python -m coverage combine python -m coverage xml python -m coverage report -m -bash <(curl -s https://codecov.io/bash) -Z -X gcov -X coveragepy -X search -X xcode -X gcovout -X fix -f coverage.xml +curl -S -L --retry 3 -s https://codecov.io/bash -o codecov-upload.sh +bash codecov-upload.sh -Z -X gcov -X coveragepy -X search -X xcode -X gcovout -X fix -f coverage.xml From ea0c7e43b6f31500ad20c9c9c986544b1bd060a1 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Mon, 23 Sep 2019 02:26:53 +0200 Subject: [PATCH 03/18] Remove unneeded codecov options (implied with "-f") --- scripts/report-coverage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/report-coverage.sh b/scripts/report-coverage.sh index 362dab091..500d217f0 100755 --- a/scripts/report-coverage.sh +++ b/scripts/report-coverage.sh @@ -14,4 +14,4 @@ python -m coverage combine python -m coverage xml python -m coverage report -m curl -S -L --retry 3 -s https://codecov.io/bash -o codecov-upload.sh -bash codecov-upload.sh -Z -X gcov -X coveragepy -X search -X xcode -X gcovout -X fix -f coverage.xml +bash codecov-upload.sh -Z -X fix -f coverage.xml From 04c01fb606cdd3a51c04d945fc92c673905d6ad0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= Date: Mon, 23 Sep 2019 16:23:14 +0200 Subject: [PATCH 04/18] test_argcomplete do not call python directly #5872 Use sys.executable to detect which python we should actually be testing. --- testing/test_parseopt.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/testing/test_parseopt.py b/testing/test_parseopt.py index dd7bc8753..5350974d7 100644 --- a/testing/test_parseopt.py +++ b/testing/test_parseopt.py @@ -298,7 +298,11 @@ def test_argcomplete(testdir, monkeypatch): # redirect output from argcomplete to stdin and stderr is not trivial # http://stackoverflow.com/q/12589419/1307905 # so we use bash - fp.write('COMP_WORDBREAKS="$COMP_WORDBREAKS" python -m pytest 8>&1 9>&2') + fp.write( + 'COMP_WORDBREAKS="$COMP_WORDBREAKS" {} -m pytest 8>&1 9>&2'.format( + sys.executable + ) + ) # alternative would be exteneded Testdir.{run(),_run(),popen()} to be able # to handle a keyword argument env that replaces os.environ in popen or # extends the copy, advantage: could not forget to restore From 19c9e536044b969bf7c5377e7b0a5dff55a6accf Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 23 Sep 2019 08:56:09 -0700 Subject: [PATCH 05/18] Make sure to quote `sys.executable` as we're running a shell --- testing/test_parseopt.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testing/test_parseopt.py b/testing/test_parseopt.py index 5350974d7..d39065b82 100644 --- a/testing/test_parseopt.py +++ b/testing/test_parseopt.py @@ -1,6 +1,7 @@ import argparse import distutils.spawn import os +import shlex import sys import py @@ -300,7 +301,7 @@ def test_argcomplete(testdir, monkeypatch): # so we use bash fp.write( 'COMP_WORDBREAKS="$COMP_WORDBREAKS" {} -m pytest 8>&1 9>&2'.format( - sys.executable + shlex.quote(sys.executable) ) ) # alternative would be exteneded Testdir.{run(),_run(),popen()} to be able From 7731e456151337a2830736115396d023c8188884 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Mon, 23 Sep 2019 20:57:43 +0200 Subject: [PATCH 06/18] ci: codecov: use 6 retries with curl This should result in retries of 1+2+4+8+16+32 = 63s. Ref: https://github.com/pytest-dev/pytest/pull/5869#issuecomment-534235437 --- scripts/report-coverage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/report-coverage.sh b/scripts/report-coverage.sh index 500d217f0..7fdeda464 100755 --- a/scripts/report-coverage.sh +++ b/scripts/report-coverage.sh @@ -13,5 +13,5 @@ fi python -m coverage combine python -m coverage xml python -m coverage report -m -curl -S -L --retry 3 -s https://codecov.io/bash -o codecov-upload.sh +curl -S -L --retry 6 -s https://codecov.io/bash -o codecov-upload.sh bash codecov-upload.sh -Z -X fix -f coverage.xml From 7bdfba3578455b58589e5834fea3feaf932018bd Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 28 Sep 2019 11:52:09 -0300 Subject: [PATCH 07/18] Fix --setup-only and --setup-show for custom pytest items Fix #5884 --- changelog/5884.bugfix.rst | 1 + src/_pytest/runner.py | 4 ++-- testing/conftest.py | 27 +++++++++++++++++++++++++++ testing/python/setup_only.py | 6 +++--- testing/python/setup_plan.py | 6 +++--- 5 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 changelog/5884.bugfix.rst diff --git a/changelog/5884.bugfix.rst b/changelog/5884.bugfix.rst new file mode 100644 index 000000000..42d207ce7 --- /dev/null +++ b/changelog/5884.bugfix.rst @@ -0,0 +1 @@ +Fix ``--setup-only`` and ``--setup-show`` for custom pytest items. diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 7d8b74a80..fce4c1e3f 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -107,8 +107,8 @@ def show_test_item(item): tw = item.config.get_terminal_writer() tw.line() tw.write(" " * 8) - tw.write(item._nodeid) - used_fixtures = sorted(item._fixtureinfo.name2fixturedefs.keys()) + tw.write(item.nodeid) + used_fixtures = sorted(getattr(item, "fixturenames", [])) if used_fixtures: tw.write(" (fixtures used: {})".format(", ".join(used_fixtures))) diff --git a/testing/conftest.py b/testing/conftest.py index d7f94ce45..a03efb0cf 100644 --- a/testing/conftest.py +++ b/testing/conftest.py @@ -88,3 +88,30 @@ def tw_mock(): fullwidth = 80 return TWMock() + + +@pytest.fixture +def dummy_yaml_custom_test(testdir): + """Writes a conftest file that collects and executes a dummy yaml test. + + Taken from the docs, but stripped down to the bare minimum, useful for + tests which needs custom items collected. + """ + testdir.makeconftest( + """ + import pytest + + def pytest_collect_file(parent, path): + if path.ext == ".yaml" and path.basename.startswith("test"): + return YamlFile(path, parent) + + class YamlFile(pytest.File): + def collect(self): + yield YamlItem(self.fspath.basename, self) + + class YamlItem(pytest.Item): + def runtest(self): + pass + """ + ) + testdir.makefile(".yaml", test1="") diff --git a/testing/python/setup_only.py b/testing/python/setup_only.py index 4ae24b15a..7c871a9ee 100644 --- a/testing/python/setup_only.py +++ b/testing/python/setup_only.py @@ -6,8 +6,8 @@ def mode(request): return request.param -def test_show_only_active_fixtures(testdir, mode): - p = testdir.makepyfile( +def test_show_only_active_fixtures(testdir, mode, dummy_yaml_custom_test): + testdir.makepyfile( ''' import pytest @pytest.fixture @@ -21,7 +21,7 @@ def test_show_only_active_fixtures(testdir, mode): ''' ) - result = testdir.runpytest(mode, p) + result = testdir.runpytest(mode) assert result.ret == 0 result.stdout.fnmatch_lines( diff --git a/testing/python/setup_plan.py b/testing/python/setup_plan.py index 0321939a8..e323ba240 100644 --- a/testing/python/setup_plan.py +++ b/testing/python/setup_plan.py @@ -1,6 +1,6 @@ -def test_show_fixtures_and_test(testdir): +def test_show_fixtures_and_test(testdir, dummy_yaml_custom_test): """ Verifies that fixtures are not executed. """ - p = testdir.makepyfile( + testdir.makepyfile( """ import pytest @pytest.fixture @@ -11,7 +11,7 @@ def test_show_fixtures_and_test(testdir): """ ) - result = testdir.runpytest("--setup-plan", p) + result = testdir.runpytest("--setup-plan") assert result.ret == 0 result.stdout.fnmatch_lines( From 065773aa97a02731e5eec05e29204b50850d9248 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 28 Sep 2019 10:20:54 -0400 Subject: [PATCH 08/18] Use 'python3' instead of 'python3.6' on tox This allows us to use python3.7+ to use tox --- tox.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tox.ini b/tox.ini index 15360826f..e95b011b6 100644 --- a/tox.ini +++ b/tox.ini @@ -77,7 +77,7 @@ commands = [testenv:regen] changedir = doc/en skipsdist = True -basepython = python3.6 +basepython = python3 deps = sphinx PyYAML @@ -103,7 +103,7 @@ commands = [testenv:release] decription = do a release, required posarg of the version number -basepython = python3.6 +basepython = python3 usedevelop = True passenv = * deps = @@ -116,7 +116,7 @@ commands = python scripts/release.py {posargs} [testenv:publish_gh_release_notes] description = create GitHub release after deployment -basepython = python3.6 +basepython = python3 usedevelop = True passenv = GH_RELEASE_NOTES_TOKEN TRAVIS_TAG TRAVIS_REPO_SLUG deps = From 068ef90b92a9e9205af31cb3d82e7d2a433ff969 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 28 Sep 2019 21:18:37 -0400 Subject: [PATCH 09/18] Preparing release version 5.2.0 --- CHANGELOG.rst | 39 +++++++++++++++++++++++++++++++ changelog/1682.deprecation.rst | 2 -- changelog/1682.feature.rst | 3 --- changelog/5056.trivial.rst | 1 - changelog/5764.feature.rst | 1 - changelog/5806.bugfix.rst | 1 - changelog/5884.bugfix.rst | 1 - doc/en/announce/index.rst | 1 + doc/en/announce/release-5.2.0.rst | 36 ++++++++++++++++++++++++++++ doc/en/example/parametrize.rst | 4 ++-- doc/en/example/reportingdemo.rst | 4 ++-- doc/en/example/simple.rst | 2 +- doc/en/getting-started.rst | 2 +- 13 files changed, 82 insertions(+), 15 deletions(-) delete mode 100644 changelog/1682.deprecation.rst delete mode 100644 changelog/1682.feature.rst delete mode 100644 changelog/5056.trivial.rst delete mode 100644 changelog/5764.feature.rst delete mode 100644 changelog/5806.bugfix.rst delete mode 100644 changelog/5884.bugfix.rst create mode 100644 doc/en/announce/release-5.2.0.rst diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5d2fa4b38..55fba65eb 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -18,6 +18,45 @@ with advance notice in the **Deprecations** section of releases. .. towncrier release notes start +pytest 5.2.0 (2019-09-28) +========================= + +Deprecations +------------ + +- `#1682 `_: Passing arguments to pytest.fixture() as positional arguments is deprecated - pass them + as a keyword argument instead. + + + +Features +-------- + +- `#1682 `_: The ``scope`` parameter of ``@pytest.fixture`` can now be a callable that receives + the fixture name and the ``config`` object as keyword-only parameters. + See `the docs `__ for more information. + + +- `#5764 `_: New behavior of the ``--pastebin`` option: failures to connect to the pastebin server are reported, without failing the pytest run + + + +Bug Fixes +--------- + +- `#5806 `_: Fix "lexer" being used when uploading to bpaste.net from ``--pastebin`` to "text". + + +- `#5884 `_: Fix ``--setup-only`` and ``--setup-show`` for custom pytest items. + + + +Trivial/Internal Changes +------------------------ + +- `#5056 `_: The HelpFormatter uses ``py.io.get_terminal_width`` for better width detection. + + pytest 5.1.3 (2019-09-18) ========================= diff --git a/changelog/1682.deprecation.rst b/changelog/1682.deprecation.rst deleted file mode 100644 index 741164eb6..000000000 --- a/changelog/1682.deprecation.rst +++ /dev/null @@ -1,2 +0,0 @@ -Passing arguments to pytest.fixture() as positional arguments is deprecated - pass them -as a keyword argument instead. diff --git a/changelog/1682.feature.rst b/changelog/1682.feature.rst deleted file mode 100644 index 392de6363..000000000 --- a/changelog/1682.feature.rst +++ /dev/null @@ -1,3 +0,0 @@ -The ``scope`` parameter of ``@pytest.fixture`` can now be a callable that receives -the fixture name and the ``config`` object as keyword-only parameters. -See `the docs `__ for more information. diff --git a/changelog/5056.trivial.rst b/changelog/5056.trivial.rst deleted file mode 100644 index 75e01a88b..000000000 --- a/changelog/5056.trivial.rst +++ /dev/null @@ -1 +0,0 @@ -The HelpFormatter uses ``py.io.get_terminal_width`` for better width detection. diff --git a/changelog/5764.feature.rst b/changelog/5764.feature.rst deleted file mode 100644 index 3ac77b8fe..000000000 --- a/changelog/5764.feature.rst +++ /dev/null @@ -1 +0,0 @@ -New behavior of the ``--pastebin`` option: failures to connect to the pastebin server are reported, without failing the pytest run diff --git a/changelog/5806.bugfix.rst b/changelog/5806.bugfix.rst deleted file mode 100644 index ec887768d..000000000 --- a/changelog/5806.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fix "lexer" being used when uploading to bpaste.net from ``--pastebin`` to "text". diff --git a/changelog/5884.bugfix.rst b/changelog/5884.bugfix.rst deleted file mode 100644 index 42d207ce7..000000000 --- a/changelog/5884.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fix ``--setup-only`` and ``--setup-show`` for custom pytest items. diff --git a/doc/en/announce/index.rst b/doc/en/announce/index.rst index a601b247e..5fe3cc78c 100644 --- a/doc/en/announce/index.rst +++ b/doc/en/announce/index.rst @@ -6,6 +6,7 @@ Release announcements :maxdepth: 2 + release-5.2.0 release-5.1.3 release-5.1.2 release-5.1.1 diff --git a/doc/en/announce/release-5.2.0.rst b/doc/en/announce/release-5.2.0.rst new file mode 100644 index 000000000..f61d70222 --- /dev/null +++ b/doc/en/announce/release-5.2.0.rst @@ -0,0 +1,36 @@ +pytest-5.2.0 +======================================= + +The pytest team is proud to announce the 5.2.0 release! + +pytest is a mature Python testing tool with more than a 2000 tests +against itself, passing on many different interpreters and platforms. + +This release contains a number of bugs fixes and improvements, so users are encouraged +to take a look at the CHANGELOG: + + https://docs.pytest.org/en/latest/changelog.html + +For complete documentation, please visit: + + https://docs.pytest.org/en/latest/ + +As usual, you can upgrade from pypi via: + + pip install -U pytest + +Thanks to all who contributed to this release, among them: + +* Andrzej Klajnert +* Anthony Sottile +* Bruno Oliveira +* Daniel Hahler +* James Cooke +* Michael Goerz +* Ran Benita +* Tomáš Chvátal +* aklajnert + + +Happy testing, +The Pytest Development Team diff --git a/doc/en/example/parametrize.rst b/doc/en/example/parametrize.rst index 640106ccd..0b94e425c 100644 --- a/doc/en/example/parametrize.rst +++ b/doc/en/example/parametrize.rst @@ -475,10 +475,10 @@ Running it results in some skips if we don't have all the python interpreters in .. code-block:: pytest . $ pytest -rs -q multipython.py - ssssssssssss...ssssssssssss [100%] + ssssssssssssssssssssssss... [100%] ========================= short test summary info ========================== SKIPPED [12] $REGENDOC_TMPDIR/CWD/multipython.py:30: 'python3.5' not found - SKIPPED [12] $REGENDOC_TMPDIR/CWD/multipython.py:30: 'python3.7' not found + SKIPPED [12] $REGENDOC_TMPDIR/CWD/multipython.py:30: 'python3.6' not found 3 passed, 24 skipped in 0.12s Indirect parametrization of optional implementations/imports diff --git a/doc/en/example/reportingdemo.rst b/doc/en/example/reportingdemo.rst index 1c06782f6..eb978c5ea 100644 --- a/doc/en/example/reportingdemo.rst +++ b/doc/en/example/reportingdemo.rst @@ -436,7 +436,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: items = [1, 2, 3] print("items is {!r}".format(items)) > a, b = items.pop() - E TypeError: 'int' object is not iterable + E TypeError: cannot unpack non-iterable int object failure_demo.py:181: TypeError --------------------------- Captured stdout call --------------------------- @@ -516,7 +516,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: def test_z2_type_error(self): items = 3 > a, b = items - E TypeError: 'int' object is not iterable + E TypeError: cannot unpack non-iterable int object failure_demo.py:222: TypeError ______________________ TestMoreErrors.test_startswith ______________________ diff --git a/doc/en/example/simple.rst b/doc/en/example/simple.rst index 71ac77f7b..a7cd06d31 100644 --- a/doc/en/example/simple.rst +++ b/doc/en/example/simple.rst @@ -445,7 +445,7 @@ Now we can profile which test functions execute the slowest: ========================= slowest 3 test durations ========================= 0.30s call test_some_are_slow.py::test_funcslow2 - 0.21s call test_some_are_slow.py::test_funcslow1 + 0.20s call test_some_are_slow.py::test_funcslow1 0.10s call test_some_are_slow.py::test_funcfast ============================ 3 passed in 0.12s ============================= diff --git a/doc/en/getting-started.rst b/doc/en/getting-started.rst index 2bdd68ea3..97347f126 100644 --- a/doc/en/getting-started.rst +++ b/doc/en/getting-started.rst @@ -28,7 +28,7 @@ Install ``pytest`` .. code-block:: bash $ pytest --version - This is pytest version 5.x.y, imported from $PYTHON_PREFIX/lib/python3.6/site-packages/pytest.py + This is pytest version 5.x.y, imported from $PYTHON_PREFIX/lib/python3.7/site-packages/pytest.py .. _`simpletest`: From 07792c7113f71a25df56492f6199568bd704bb34 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 28 Sep 2019 18:19:53 -0700 Subject: [PATCH 10/18] Fix attribute docs in _pytest.pytester --- src/_pytest/pytester.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index 94058f70c..0f3460741 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -351,15 +351,14 @@ class RunResult: Attributes: - :ret: the return value - :outlines: list of lines captured from stdout - :errlines: list of lines captures from stderr - :stdout: :py:class:`LineMatcher` of stdout, use ``stdout.str()`` to + :ivar ret: the return value + :ivar outlines: list of lines captured from stdout + :ivar errlines: list of lines captured from stderr + :ivar stdout: :py:class:`LineMatcher` of stdout, use ``stdout.str()`` to reconstruct stdout or the commonly used ``stdout.fnmatch_lines()`` method - :stderr: :py:class:`LineMatcher` of stderr - :duration: duration in seconds - + :ivar stderr: :py:class:`LineMatcher` of stderr + :ivar duration: duration in seconds """ def __init__(self, ret, outlines, errlines, duration): @@ -454,9 +453,9 @@ class Testdir: Attributes: - :tmpdir: The :py:class:`py.path.local` instance of the temporary directory. + :ivar tmpdir: The :py:class:`py.path.local` instance of the temporary directory. - :plugins: A list of plugins to use with :py:meth:`parseconfig` and + :ivar plugins: A list of plugins to use with :py:meth:`parseconfig` and :py:meth:`runpytest`. Initially this is an empty list but plugins can be added to the list. The type of items to add to the list depends on the method using them so refer to them for details. From acfd0fd9d677b1d300b227be6734ccced0594824 Mon Sep 17 00:00:00 2001 From: tadashigaki Date: Tue, 1 Oct 2019 02:44:07 +0900 Subject: [PATCH 11/18] Update doc: pytest section in setup.cfg --- doc/en/customize.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/en/customize.rst b/doc/en/customize.rst index 3471463a3..891922373 100644 --- a/doc/en/customize.rst +++ b/doc/en/customize.rst @@ -134,10 +134,13 @@ progress output, you can write it into a configuration file: .. code-block:: ini # content of pytest.ini or tox.ini - # setup.cfg files should use [tool:pytest] section instead [pytest] addopts = -ra -q + # content of setup.cfg + [tool:pytest] + addopts = -ra -q + Alternatively, you can set a ``PYTEST_ADDOPTS`` environment variable to add command line options while the environment is in use: From b490f5f97915ebe63666e1a51816f81c43d16267 Mon Sep 17 00:00:00 2001 From: "Kevin J. Foley" Date: Tue, 1 Oct 2019 10:17:26 -0400 Subject: [PATCH 12/18] Fix doc typo --- doc/en/reference.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/en/reference.rst b/doc/en/reference.rst index b6df27f9c..9c3a4c731 100644 --- a/doc/en/reference.rst +++ b/doc/en/reference.rst @@ -1003,7 +1003,7 @@ passed multiple times. The expected format is ``name=value``. For example:: [pytest] addopts = --maxfail=2 -rf # exit after 2 failures, report fail info - issuing ``pytest test_hello.py`` actually means:: + issuing ``pytest test_hello.py`` actually means: .. code-block:: bash From a79acf279a80bbbac0a05d8fadf62649753c668a Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Tue, 1 Oct 2019 20:40:13 +0200 Subject: [PATCH 13/18] Fix warnings with attrs 19.2 and fix object assertions attrs 19.2 deprecated cmp in favor of the dataclass-ish eq/order duo. This causes deprecation warnings that in turn break some of the cool new deep object comparisons. Since we at attrs expected this to be a problem, it shipped with helpers to write backward and forward compatible code. This PR uses that and avoids changed to minimal versions. --- src/_pytest/assertion/util.py | 15 ++++++++++++++- src/_pytest/compat.py | 7 +++++++ src/_pytest/mark/structures.py | 3 ++- testing/test_assertion.py | 3 ++- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/_pytest/assertion/util.py b/src/_pytest/assertion/util.py index 11c7bdf6f..21ec72803 100644 --- a/src/_pytest/assertion/util.py +++ b/src/_pytest/assertion/util.py @@ -8,6 +8,7 @@ from typing import Optional import _pytest._code from _pytest import outcomes from _pytest._io.saferepr import saferepr +from _pytest.compat import attrs_has_eq # The _reprcompare attribute on the util module is used by the new assertion # interpretation code and assertion rewriter to detect this plugin was @@ -112,6 +113,18 @@ def isattrs(obj): return getattr(obj, "__attrs_attrs__", None) is not None +if attrs_has_eq: + + def attrsfieldhaseq(a): + return a.eq + + +else: + + def attrsfieldhaseq(a): + return a.cmp + + def isiterable(obj): try: iter(obj) @@ -375,7 +388,7 @@ def _compare_eq_cls(left, right, verbose, type_fns): fields_to_check = [field for field, info in all_fields.items() if info.compare] elif isattrs(left): all_fields = left.__attrs_attrs__ - fields_to_check = [field.name for field in all_fields if field.cmp] + fields_to_check = [field.name for field in all_fields if attrsfieldhaseq(field)] same = [] diff = [] diff --git a/src/_pytest/compat.py b/src/_pytest/compat.py index 3d1531e77..575e85b9a 100644 --- a/src/_pytest/compat.py +++ b/src/_pytest/compat.py @@ -354,3 +354,10 @@ if sys.version_info < (3, 5, 2): # pragma: no cover def overload(f): # noqa: F811 return f + + +attrs_has_eq = getattr(attr, "__version_info__", (0, 0)) >= (19, 2) +if attrs_has_eq: + attrs_no_eq = {"eq": False} +else: + attrs_no_eq = {"cmp": False} diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index f8cf55b4c..19333453f 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -8,6 +8,7 @@ from typing import Set import attr from ..compat import ascii_escaped +from ..compat import attrs_no_eq from ..compat import getfslineno from ..compat import NOTSET from _pytest.outcomes import fail @@ -367,7 +368,7 @@ class NodeKeywords(MutableMapping): return "".format(self.node) -@attr.s(cmp=False, hash=False) +@attr.s(hash=False, **attrs_no_eq) # type: ignore class NodeMarkers: """ internal structure for storing marks belonging to a node diff --git a/testing/test_assertion.py b/testing/test_assertion.py index bf23e3202..83370fb43 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -9,6 +9,7 @@ import pytest from _pytest import outcomes from _pytest.assertion import truncate from _pytest.assertion import util +from _pytest.compat import attrs_no_eq def mock_config(): @@ -687,7 +688,7 @@ class TestAssert_reprcompare_attrsclass: @attr.s class SimpleDataObject: field_a = attr.ib() - field_b = attr.ib(cmp=False) + field_b = attr.ib(**attrs_no_eq) left = SimpleDataObject(1, "b") right = SimpleDataObject(1, "b") From 9637b3e376d6e94c10af5c7132f97fd3cb308125 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 3 Oct 2019 09:01:08 -0700 Subject: [PATCH 14/18] Fix dynamic scoping changelog link --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 55fba65eb..504b0f517 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -34,7 +34,7 @@ Features - `#1682 `_: The ``scope`` parameter of ``@pytest.fixture`` can now be a callable that receives the fixture name and the ``config`` object as keyword-only parameters. - See `the docs `__ for more information. + See `the docs `__ for more information. - `#5764 `_: New behavior of the ``--pastebin`` option: failures to connect to the pastebin server are reported, without failing the pytest run From c58b0fb4acefefc81a12ab92ad3f37384218ee78 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 5 Oct 2019 18:16:35 -0700 Subject: [PATCH 15/18] Use ATTRS_EQ_FIELD for attrs 19.2 compat --- src/_pytest/assertion/util.py | 18 ++++-------------- src/_pytest/compat.py | 7 +++---- src/_pytest/mark/structures.py | 5 +++-- testing/test_assertion.py | 4 ++-- 4 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/_pytest/assertion/util.py b/src/_pytest/assertion/util.py index 21ec72803..c2a4e446f 100644 --- a/src/_pytest/assertion/util.py +++ b/src/_pytest/assertion/util.py @@ -8,7 +8,7 @@ from typing import Optional import _pytest._code from _pytest import outcomes from _pytest._io.saferepr import saferepr -from _pytest.compat import attrs_has_eq +from _pytest.compat import ATTRS_EQ_FIELD # The _reprcompare attribute on the util module is used by the new assertion # interpretation code and assertion rewriter to detect this plugin was @@ -113,18 +113,6 @@ def isattrs(obj): return getattr(obj, "__attrs_attrs__", None) is not None -if attrs_has_eq: - - def attrsfieldhaseq(a): - return a.eq - - -else: - - def attrsfieldhaseq(a): - return a.cmp - - def isiterable(obj): try: iter(obj) @@ -388,7 +376,9 @@ def _compare_eq_cls(left, right, verbose, type_fns): fields_to_check = [field for field, info in all_fields.items() if info.compare] elif isattrs(left): all_fields = left.__attrs_attrs__ - fields_to_check = [field.name for field in all_fields if attrsfieldhaseq(field)] + fields_to_check = [ + field.name for field in all_fields if getattr(field, ATTRS_EQ_FIELD) + ] same = [] diff = [] diff --git a/src/_pytest/compat.py b/src/_pytest/compat.py index 575e85b9a..3898fb252 100644 --- a/src/_pytest/compat.py +++ b/src/_pytest/compat.py @@ -356,8 +356,7 @@ if sys.version_info < (3, 5, 2): # pragma: no cover return f -attrs_has_eq = getattr(attr, "__version_info__", (0, 0)) >= (19, 2) -if attrs_has_eq: - attrs_no_eq = {"eq": False} +if getattr(attr, "__version_info__", ()) >= (19, 2): + ATTRS_EQ_FIELD = "eq" else: - attrs_no_eq = {"cmp": False} + ATTRS_EQ_FIELD = "cmp" diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index 19333453f..2cab96d67 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -8,7 +8,7 @@ from typing import Set import attr from ..compat import ascii_escaped -from ..compat import attrs_no_eq +from ..compat import ATTRS_EQ_FIELD from ..compat import getfslineno from ..compat import NOTSET from _pytest.outcomes import fail @@ -368,7 +368,8 @@ class NodeKeywords(MutableMapping): return "".format(self.node) -@attr.s(hash=False, **attrs_no_eq) # type: ignore +# mypy cannot find this overload, remove when on attrs>=19.2 +@attr.s(hash=False, **{ATTRS_EQ_FIELD: False}) # type: ignore class NodeMarkers: """ internal structure for storing marks belonging to a node diff --git a/testing/test_assertion.py b/testing/test_assertion.py index 83370fb43..8fce5e279 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -9,7 +9,7 @@ import pytest from _pytest import outcomes from _pytest.assertion import truncate from _pytest.assertion import util -from _pytest.compat import attrs_no_eq +from _pytest.compat import ATTRS_EQ_FIELD def mock_config(): @@ -688,7 +688,7 @@ class TestAssert_reprcompare_attrsclass: @attr.s class SimpleDataObject: field_a = attr.ib() - field_b = attr.ib(**attrs_no_eq) + field_b = attr.ib(**{ATTRS_EQ_FIELD: False}) left = SimpleDataObject(1, "b") right = SimpleDataObject(1, "b") From 1c5efffd904e0068a3e7b4090d94bbe589be66bf Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sun, 6 Oct 2019 07:58:23 -0400 Subject: [PATCH 16/18] Add changelog entry for #5902 --- changelog/5902.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/5902.bugfix.rst diff --git a/changelog/5902.bugfix.rst b/changelog/5902.bugfix.rst new file mode 100644 index 000000000..dccb49757 --- /dev/null +++ b/changelog/5902.bugfix.rst @@ -0,0 +1 @@ +Fix warnings about deprecated ``cmp`` attribute in ``attrs>=19.2``. \ No newline at end of file From 12cc729f6b50abbd3708dfc64e76ff454852b805 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sun, 6 Oct 2019 08:00:49 -0400 Subject: [PATCH 17/18] Preparing release version 5.2.1 --- CHANGELOG.rst | 9 +++++++++ changelog/5902.bugfix.rst | 1 - doc/en/announce/index.rst | 1 + doc/en/announce/release-5.2.1.rst | 23 +++++++++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) delete mode 100644 changelog/5902.bugfix.rst create mode 100644 doc/en/announce/release-5.2.1.rst diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 504b0f517..c03fa631e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -18,6 +18,15 @@ with advance notice in the **Deprecations** section of releases. .. towncrier release notes start +pytest 5.2.1 (2019-10-06) +========================= + +Bug Fixes +--------- + +- `#5902 `_: Fix warnings about deprecated ``cmp`` attribute in ``attrs>=19.2``. + + pytest 5.2.0 (2019-09-28) ========================= diff --git a/changelog/5902.bugfix.rst b/changelog/5902.bugfix.rst deleted file mode 100644 index dccb49757..000000000 --- a/changelog/5902.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fix warnings about deprecated ``cmp`` attribute in ``attrs>=19.2``. \ No newline at end of file diff --git a/doc/en/announce/index.rst b/doc/en/announce/index.rst index 5fe3cc78c..d5e684198 100644 --- a/doc/en/announce/index.rst +++ b/doc/en/announce/index.rst @@ -6,6 +6,7 @@ Release announcements :maxdepth: 2 + release-5.2.1 release-5.2.0 release-5.1.3 release-5.1.2 diff --git a/doc/en/announce/release-5.2.1.rst b/doc/en/announce/release-5.2.1.rst new file mode 100644 index 000000000..312cfd778 --- /dev/null +++ b/doc/en/announce/release-5.2.1.rst @@ -0,0 +1,23 @@ +pytest-5.2.1 +======================================= + +pytest 5.2.1 has just been released to PyPI. + +This is a bug-fix release, being a drop-in replacement. To upgrade:: + + pip install --upgrade pytest + +The full changelog is available at https://docs.pytest.org/en/latest/changelog.html. + +Thanks to all who contributed to this release, among them: + +* Anthony Sottile +* Bruno Oliveira +* Florian Bruhin +* Hynek Schlawack +* Kevin J. Foley +* tadashigaki + + +Happy testing, +The pytest Development Team From b0fd8742da28c2df2bd20cab9d67b432ce542951 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sun, 6 Oct 2019 16:00:54 +0200 Subject: [PATCH 18/18] ci: test oldest supported attrs --- .travis.yml | 3 ++- setup.py | 2 +- tox.ini | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5de40f3a4..c713a19a1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,8 +49,9 @@ jobs: # - pytester's LsofFdLeakChecker # - TestArgComplete (linux only) # - numpy + # - old attrs # Empty PYTEST_ADDOPTS to run this non-verbose. - - env: TOXENV=py37-lsof-numpy-twisted-xdist PYTEST_COVERAGE=1 PYTEST_ADDOPTS= + - env: TOXENV=py37-lsof-oldattrs-numpy-twisted-xdist PYTEST_COVERAGE=1 PYTEST_ADDOPTS= # Specialized factors for py37. # Coverage for: diff --git a/setup.py b/setup.py index adbafb557..dcf63f6fd 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ from setuptools import setup INSTALL_REQUIRES = [ "py>=1.5.0", "packaging", - "attrs>=17.4.0", + "attrs>=17.4.0", # should match oldattrs tox env. "more-itertools>=4.0.0", "atomicwrites>=1.0", 'pathlib2>=2.2.0;python_version<"3.6"', diff --git a/tox.ini b/tox.ini index e95b011b6..e1b611f58 100644 --- a/tox.ini +++ b/tox.ini @@ -41,6 +41,8 @@ setenv = xdist: _PYTEST_TOX_POSARGS_XDIST=-n auto extras = testing deps = + oldattrs: attrs==17.4.0 + oldattrs: hypothesis<=4.38.1 numpy: numpy pexpect: pexpect pluggymaster: git+https://github.com/pytest-dev/pluggy.git@master