From dfe1209d2cc136d5a7b2e6149ee931d6be39f0c4 Mon Sep 17 00:00:00 2001 From: Kalle Bronsen Date: Wed, 13 Jul 2016 11:41:27 +0200 Subject: [PATCH 01/18] De-404 links in changelog --- CHANGELOG.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2a18d2b86..51150c823 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -99,8 +99,8 @@ .. _#510: https://github.com/pytest-dev/pytest/issues/510 .. _#1506: https://github.com/pytest-dev/pytest/pull/1506 -.. _#1496: https://github.com/pytest-dev/pytest/issue/1496 -.. _#1524: https://github.com/pytest-dev/pytest/issue/1524 +.. _#1496: https://github.com/pytest-dev/pytest/issues/1496 +.. _#1524: https://github.com/pytest-dev/pytest/pull/1524 .. _@prusse-martin: https://github.com/prusse-martin .. _@astraw38: https://github.com/astraw38 From 9007e16cdf791d3e9df45cd3f5a0c26fb551fac0 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Tue, 12 Jul 2016 12:41:40 -0300 Subject: [PATCH 02/18] Document limitations for yield-tests in nose Also add nose doc to the root toctree Closes #1716 --- doc/en/contents.rst | 1 + doc/en/nose.rst | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/doc/en/contents.rst b/doc/en/contents.rst index 48c3471b5..4e94f4ade 100644 --- a/doc/en/contents.rst +++ b/doc/en/contents.rst @@ -19,6 +19,7 @@ Full pytest documentation recwarn cache plugins + nose contributing talks diff --git a/doc/en/nose.rst b/doc/en/nose.rst index 04386ea0f..fc2c4812e 100644 --- a/doc/en/nose.rst +++ b/doc/en/nose.rst @@ -24,7 +24,7 @@ Supported nose Idioms * setup and teardown at module/class/method level * SkipTest exceptions and markers * setup/teardown decorators -* yield-based tests and their setup +* ``yield``-based tests and their setup * ``__test__`` attribute on modules/classes/functions * general usage of nose utilities @@ -51,5 +51,12 @@ Unsupported idioms / known issues - nose-style doctests are not collected and executed correctly, also doctest fixtures don't work. -- no nose-configuration is recognized +- no nose-configuration is recognized. + +- ``yield``-based methods don't support ``setup`` properly because + the ``setup`` method is always called in the same class instance. + There are no plans to fix this currently because ``yield``-tests + are deprecated in pytest 3.0, with ``pytest.mark.parametrize`` + being the recommended alternative. + From 7e37497d5a1fd2ee612e39980af5ac948367ecb9 Mon Sep 17 00:00:00 2001 From: Javi Romero Date: Fri, 22 Jul 2016 12:39:06 +0200 Subject: [PATCH 03/18] Uppercase first word in docstrings. Change to an imperative form. Add name to authors. --- AUTHORS | 1 + _pytest/capture.py | 4 ++-- _pytest/junitxml.py | 4 ++-- _pytest/monkeypatch.py | 6 +++--- _pytest/python.py | 2 +- _pytest/tmpdir.py | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/AUTHORS b/AUTHORS index c35e66587..b459cef6c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -96,3 +96,4 @@ Tom Viner Trevor Bekolay Wouter van Ackooy Bernard Pratz +Javier Romero diff --git a/_pytest/capture.py b/_pytest/capture.py index 3895a714a..2763c148c 100644 --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -156,7 +156,7 @@ error_capsysfderror = "cannot use capsys and capfd at the same time" @pytest.fixture def capsys(request): - """enables capturing of writes to sys.stdout/sys.stderr and makes + """Enable capturing of writes to sys.stdout/sys.stderr and make captured output available via ``capsys.readouterr()`` method calls which return a ``(out, err)`` tuple. """ @@ -167,7 +167,7 @@ def capsys(request): @pytest.fixture def capfd(request): - """enables capturing of writes to file descriptors 1 and 2 and makes + """Enable capturing of writes to file descriptors 1 and 2 and make captured output available via ``capfd.readouterr()`` method calls which return a ``(out, err)`` tuple. """ diff --git a/_pytest/junitxml.py b/_pytest/junitxml.py index f4de1343e..4c2b9d149 100644 --- a/_pytest/junitxml.py +++ b/_pytest/junitxml.py @@ -186,8 +186,8 @@ class _NodeReporter(object): @pytest.fixture def record_xml_property(request): - """Fixture that adds extra xml properties to the tag for the calling test. - The fixture is callable with (name, value), with value being automatically + """Add extra xml properties to the tag for the calling test. + The fixture is callable with ``(name, value)``, with value being automatically xml-encoded. """ request.node.warn( diff --git a/_pytest/monkeypatch.py b/_pytest/monkeypatch.py index d4c169d37..adf3427ce 100644 --- a/_pytest/monkeypatch.py +++ b/_pytest/monkeypatch.py @@ -9,7 +9,7 @@ RE_IMPORT_ERROR_NAME = re.compile("^No module named (.*)$") def pytest_funcarg__monkeypatch(request): - """The returned ``monkeypatch`` funcarg provides these + """Return a ``monkeypatch`` funcarg providing the following helper methods to modify objects, dictionaries or os.environ:: monkeypatch.setattr(obj, name, value, raising=True) @@ -220,10 +220,10 @@ class monkeypatch: """ Undo previous changes. This call consumes the undo stack. Calling it a second time has no effect unless you do more monkeypatching after the undo call. - + There is generally no need to call `undo()`, since it is called automatically during tear-down. - + Note that the same `monkeypatch` fixture is used across a single test function invocation. If `monkeypatch` is used both by the test function itself and one of the test fixtures, diff --git a/_pytest/python.py b/_pytest/python.py index 502fdc7ef..6242fd497 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -271,7 +271,7 @@ def pytest_namespace(): @fixture(scope="session") def pytestconfig(request): - """ the pytest config object with access to command line opts.""" + """ The pytest config object with access to command line opts.""" return request.config diff --git a/_pytest/tmpdir.py b/_pytest/tmpdir.py index ebc48dbe5..9986f5628 100644 --- a/_pytest/tmpdir.py +++ b/_pytest/tmpdir.py @@ -108,7 +108,7 @@ def tmpdir_factory(request): @pytest.fixture def tmpdir(request, tmpdir_factory): - """return a temporary directory path object + """Return a temporary directory path object which is unique to each test function invocation, created as a sub directory of the base temporary directory. The returned object is a `py.path.local`_ From 1aab6e3bc2c3953b9fcd635a02d4226324bfb2eb Mon Sep 17 00:00:00 2001 From: Javi Romero Date: Fri, 22 Jul 2016 12:54:42 +0200 Subject: [PATCH 04/18] Add changes to changelog. --- CHANGELOG.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 51150c823..2e55acbbc 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -36,12 +36,14 @@ Thanks `@bagerard`_ for reporting (`#1503`_). Thanks to `@davehunt`_ and `@tomviner`_ for PR. -* Renamed the pytest ``pdb`` module (plugin) into ``debugging``. +* Renamed the pytest ``pdb`` module (plugin) into ``debugging``. * Improve of the test output for logical expression with brackets. Fixes(`#925`_). Thanks `@DRMacIver`_ for reporting. Thanks to `@RedBeardCode`_ for PR. +* Updated docstrings with a more uniform style. + * * ImportErrors in plugins now are a fatal error instead of issuing a From 018acc6bae522d0cef5b5ee3061573dba2505b23 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 23 Jul 2016 10:44:38 -0300 Subject: [PATCH 05/18] Explain why thanks yourself in the CHANGELOG --- .github/PULL_REQUEST_TEMPLATE.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index d09edce43..198780a2a 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,7 +2,10 @@ Thanks for submitting a PR, your contribution is really appreciated! Here's a quick checklist that should be present in PRs: -- [ ] Target: for bug or doc fixes, target `master`; for new features, target `features` -- [ ] Make sure to include one or more tests for your change -- [ ] Add yourself to `AUTHORS` -- [ ] Add a new entry to the `CHANGELOG` (choose any open position to avoid merge conflicts with other PRs) +- [ ] Target: for bug or doc fixes, target `master`; for new features, target `features`; +- [ ] Make sure to include one or more tests for your change; +- [ ] Add yourself to `AUTHORS`; +- [ ] Add a new entry to `CHANGELOG.rst` + * Choose any open position to avoid merge conflicts with other PRs. + * Add a link to the issue you are fixing (if any) using RST syntax. + * The pytest team likes to have people to acknowledged in the `CHANGELOG`, so please add a thank note to yourself ("Thanks @user for the PR") and a link to your GitHub profile. It may sound weird thanking yourself, but otherwise a maintainer would have to do it manually before or after merging instead of just using GitHub's merge button. This makes it easier on the maintainers to merge PRs. From 1704b7d2657bd680425da014fdfd9c0a8798628f Mon Sep 17 00:00:00 2001 From: Diego Russo Date: Sat, 23 Jul 2016 15:48:41 +0200 Subject: [PATCH 06/18] Test case for overriding autouse fixtures Test case for overriding autouse fixture with a parametrized fixture. The test covers the problem explained in the issue 1601 Adding Diego Russo to AUTHORS --- AUTHORS | 1 + testing/python/fixture.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/AUTHORS b/AUTHORS index b459cef6c..9d90a52bd 100644 --- a/AUTHORS +++ b/AUTHORS @@ -34,6 +34,7 @@ Dave Hunt David Díaz-Barquero David Mohr David Vierra +Diego Russo Edison Gustavo Muenz Eduardo Schettino Elizaveta Shashkova diff --git a/testing/python/fixture.py b/testing/python/fixture.py index 435f7947c..8b0a203bd 100644 --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -336,6 +336,38 @@ class TestFillFixtures: result = testdir.runpytest(testfile) result.stdout.fnmatch_lines(["*3 passed*"]) + def test_override_autouse_fixture_with_parametrized_fixture_conftest_conftest(self, testdir): + """Test override of the autouse fixture with parametrized one on the conftest level. + This test covers the issue explained in issue 1601 + """ + testdir.makeconftest(""" + import pytest + + @pytest.fixture(autouse=True) + def spam(): + return 'spam' + """) + subdir = testdir.mkpydir('subdir') + subdir.join("conftest.py").write(_pytest._code.Source(""" + import pytest + + @pytest.fixture(params=[1, 2, 3]) + def spam(request): + return request.param + """)) + testfile = subdir.join("test_spam.py") + testfile.write(_pytest._code.Source(""" + params = {'spam': 1} + + def test_spam(spam): + assert spam == params['spam'] + params['spam'] += 1 + """)) + result = testdir.runpytest() + result.stdout.fnmatch_lines(["*3 passed*"]) + result = testdir.runpytest(testfile) + result.stdout.fnmatch_lines(["*3 passed*"]) + def test_autouse_fixture_plugin(self, testdir): # A fixture from a plugin has no baseid set, which screwed up # the autouse fixture handling. From 6799a47c7884ded9001b08833307492b63468760 Mon Sep 17 00:00:00 2001 From: Edoardo Batini Date: Sat, 23 Jul 2016 23:43:34 +0200 Subject: [PATCH 07/18] Start FixtureLookupErrorRepr with an 'E' --- _pytest/python.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/_pytest/python.py b/_pytest/python.py index 6242fd497..cc2dd64d3 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1835,8 +1835,13 @@ class FixtureLookupErrorRepr(TerminalRepr): #tw.line("FixtureLookupError: %s" %(self.argname), red=True) for tbline in self.tblines: tw.line(tbline.rstrip()) - for line in self.errorstring.split("\n"): - tw.line(" " + line.strip(), red=True) + lines = self.errorstring.split("\n") + for line in lines: + if line == lines[0]: + prefix = 'E ' + else: + prefix = ' ' + tw.line(prefix + line.strip(), red=True) tw.line() tw.line("%s:%d" % (self.filename, self.firstlineno+1)) From e9a67e6702c5780ab1fedf4de327214937590397 Mon Sep 17 00:00:00 2001 From: Edoardo Batini Date: Sat, 23 Jul 2016 23:45:07 +0200 Subject: [PATCH 08/18] Adjust test involving FixtureLookupErrorRepr I added a starting 'E' to the expected error messages. The tests were still passing after the previous patch but I think it's better to have stricter tests. --- testing/acceptance_test.py | 2 +- testing/test_capture.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index 1b14d12a5..8b7cca205 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -376,7 +376,7 @@ class TestGeneralUsage: res = testdir.runpytest(p) res.stdout.fnmatch_lines([ "*source code not available*", - "*fixture 'invalid_fixture' not found", + "E*fixture 'invalid_fixture' not found", ]) def test_plugins_given_as_strings(self, tmpdir, monkeypatch): diff --git a/testing/test_capture.py b/testing/test_capture.py index 73660692b..ef561ab4f 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -416,9 +416,9 @@ class TestCaptureFixture: result = testdir.runpytest(p) result.stdout.fnmatch_lines([ "*ERROR*setup*test_one*", - "*capsys*capfd*same*time*", + "E*capsys*capfd*same*time*", "*ERROR*setup*test_two*", - "*capsys*capfd*same*time*", + "E*capsys*capfd*same*time*", "*2 error*"]) @pytest.mark.parametrize("method", ["sys", "fd"]) From e00199212cab25f5581221a03180310dfe2a0e5f Mon Sep 17 00:00:00 2001 From: Edoardo Batini Date: Sat, 23 Jul 2016 23:49:44 +0200 Subject: [PATCH 09/18] Add myself to the AUTHORS --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index b459cef6c..b5dc2eb1e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -35,6 +35,7 @@ David Díaz-Barquero David Mohr David Vierra Edison Gustavo Muenz +Edoardo Batini Eduardo Schettino Elizaveta Shashkova Endre Galaczi From 3c4158ac350991b7164d23840490d68ea3ebba3a Mon Sep 17 00:00:00 2001 From: Edoardo Batini Date: Sat, 23 Jul 2016 23:51:11 +0200 Subject: [PATCH 10/18] Add changelog entry for this bugfix branch --- CHANGELOG.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2e55acbbc..ca911ffaf 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -3,6 +3,9 @@ **Bug Fixes** +* Add an 'E' to the first line of error messages from FixtureLookupErrorRepr. + Fixes (`#717`_). Thanks `@blueyed`_ for reporting. + * Text documents without any doctests no longer appear as "skipped". Thanks `@graingert`_ for reporting and providing a full PR (`#1580`_). From fabe8cda2f9464412e4193a31fb6323d93ba191a Mon Sep 17 00:00:00 2001 From: Edoardo Batini Date: Sat, 23 Jul 2016 23:59:34 +0200 Subject: [PATCH 11/18] Thanking myself in CHANGELOG --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ca911ffaf..728c86ca3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,7 +4,7 @@ **Bug Fixes** * Add an 'E' to the first line of error messages from FixtureLookupErrorRepr. - Fixes (`#717`_). Thanks `@blueyed`_ for reporting. + Fixes (`#717`_). Thanks `@blueyed`_ for reporting and `@eolo999`_ for the PR. * Text documents without any doctests no longer appear as "skipped". Thanks `@graingert`_ for reporting and providing a full PR (`#1580`_). From f450e0a1db5ccc6a55479f58d6755e8ec3dfd525 Mon Sep 17 00:00:00 2001 From: Edoardo Batini Date: Sun, 24 Jul 2016 00:06:16 +0200 Subject: [PATCH 12/18] Thanks to Tom Viner for his guidance during EuroPython2016 sprint --- CHANGELOG.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 728c86ca3..8b316f5ff 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,7 +4,8 @@ **Bug Fixes** * Add an 'E' to the first line of error messages from FixtureLookupErrorRepr. - Fixes (`#717`_). Thanks `@blueyed`_ for reporting and `@eolo999`_ for the PR. + Fixes (`#717`_). Thanks `@blueyed`_ for reporting, `@eolo999`_ for the PR + and `@tomviner`_ for his guidance during EuroPython2016 sprint. * Text documents without any doctests no longer appear as "skipped". Thanks `@graingert`_ for reporting and providing a full PR (`#1580`_). From 0ae77be9f0bf48c7484062a02f42cf256cebce96 Mon Sep 17 00:00:00 2001 From: Edoardo Batini Date: Sun, 24 Jul 2016 00:46:06 +0200 Subject: [PATCH 13/18] Add new target links in CHANGELOG --- CHANGELOG.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8b316f5ff..d3d7c097e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -53,6 +53,7 @@ * ImportErrors in plugins now are a fatal error instead of issuing a pytest warning (`#1479`_). Thanks to `@The-Compiler`_ for the PR. +.. _#717: https://github.com/pytest-dev/pytest/issues/717 .. _#1580: https://github.com/pytest-dev/pytest/pull/1580 .. _#1605: https://github.com/pytest-dev/pytest/issues/1605 .. _#1597: https://github.com/pytest-dev/pytest/pull/1597 @@ -63,6 +64,8 @@ .. _#1479: https://github.com/pytest-dev/pytest/issues/1479 .. _#925: https://github.com/pytest-dev/pytest/issues/925 +.. _@eolo999: https://github.com/eolo999 +.. _@blueyed: https://github.com/blueyed .. _@graingert: https://github.com/graingert .. _@taschini: https://github.com/taschini .. _@nikratio: https://github.com/nikratio From 42adaf5a619aa1df4e549fd0c4013765415c8772 Mon Sep 17 00:00:00 2001 From: Tom Viner Date: Sun, 24 Jul 2016 14:13:43 +0200 Subject: [PATCH 14/18] Fix #1210 display msg for early calls to exit --- AUTHORS | 1 + CHANGELOG.rst | 7 ++++++- _pytest/main.py | 5 +++++ testing/test_runner.py | 12 ++++++++++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 9d90a52bd..4ce6f0aa4 100644 --- a/AUTHORS +++ b/AUTHORS @@ -59,6 +59,7 @@ Jan Balster Janne Vanhala Jason R. Coombs John Towler +Jon Sonesen Joshua Bronson Jurko Gospodnetić Katarzyna Jachim diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2e55acbbc..dd73fce5c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -44,7 +44,9 @@ * Updated docstrings with a more uniform style. -* +* Add stderr write for ``pytest.exit(msg)`` during startup. Previously the message was never shown. + Thanks `@BeyondEvil`_ for reporting `#1210`_. Thanks to `@JonathonSonesen`_ and + `@tomviner`_ for PR. * ImportErrors in plugins now are a fatal error instead of issuing a pytest warning (`#1479`_). Thanks to `@The-Compiler`_ for the PR. @@ -58,6 +60,7 @@ .. _#1503: https://github.com/pytest-dev/pytest/issues/1503 .. _#1479: https://github.com/pytest-dev/pytest/issues/1479 .. _#925: https://github.com/pytest-dev/pytest/issues/925 +.. _#1210: https://github.com/pytest-dev/pytest/issues/1210 .. _@graingert: https://github.com/graingert .. _@taschini: https://github.com/taschini @@ -67,6 +70,8 @@ .. _@bagerard: https://github.com/bagerard .. _@davehunt: https://github.com/davehunt .. _@DRMacIver: https://github.com/DRMacIver +.. _@BeyondEvil: https://github.com/BeyondEvil +.. _@JonathonSonesen: https://github.com/JonathonSonesen 2.9.2 diff --git a/_pytest/main.py b/_pytest/main.py index df99687ad..7376c170f 100644 --- a/_pytest/main.py +++ b/_pytest/main.py @@ -92,6 +92,11 @@ def wrap_session(config, doit): raise except KeyboardInterrupt: excinfo = _pytest._code.ExceptionInfo() + if initstate < 2 and isinstance( + excinfo.value, pytest.exit.Exception): + excinfo = _pytest._code.ExceptionInfo() + sys.stderr.write('{0}: {1}\n'.format( + type(excinfo.value).__name__, excinfo.value.msg)) config.hook.pytest_keyboard_interrupt(excinfo=excinfo) session.exitstatus = EXIT_INTERRUPTED except: diff --git a/testing/test_runner.py b/testing/test_runner.py index 377801132..0fb15ebfa 100644 --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -457,6 +457,18 @@ def test_pytest_fail(): s = excinfo.exconly(tryshort=True) assert s.startswith("Failed") +def test_pytest_exit_msg(testdir): + testdir.makeconftest(""" + import pytest + + def pytest_configure(config): + pytest.exit('oh noes') + """) + result = testdir.runpytest() + result.stderr.fnmatch_lines([ + "Exit: oh noes", + ]) + def test_pytest_fail_notrace(testdir): testdir.makepyfile(""" import pytest From e9d729bd46c10248d2a16eb8bd2f944bae7ecb82 Mon Sep 17 00:00:00 2001 From: Edoardo Batini Date: Mon, 25 Jul 2016 10:11:37 +0200 Subject: [PATCH 15/18] drop parenthesis around GH issue number --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d3d7c097e..e861df450 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,7 +4,7 @@ **Bug Fixes** * Add an 'E' to the first line of error messages from FixtureLookupErrorRepr. - Fixes (`#717`_). Thanks `@blueyed`_ for reporting, `@eolo999`_ for the PR + Fixes `#717`_. Thanks `@blueyed`_ for reporting, `@eolo999`_ for the PR and `@tomviner`_ for his guidance during EuroPython2016 sprint. * Text documents without any doctests no longer appear as "skipped". From a309a571d9439b6330a0f0fa10e38ee43d061b12 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 25 Jul 2016 08:16:32 +0200 Subject: [PATCH 16/18] Cleanups for #1763 --- CHANGELOG.rst | 2 +- _pytest/main.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index dd73fce5c..5cdb63470 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -21,7 +21,7 @@ e.g. with ``request.getfuncargvalue``. BACKWARD INCOMPAT: Previously these params were simply never defined. So a fixture decorated like ``@pytest.fixture(params=[0, 1, 2])`` only ran once. Now a failure is raised. Fixes (`#460`_). Thanks to - `@nikratio`_ for bug report, `@RedBeardCode`_ and `@tomviner`_ for PR. + `@nikratio`_ for bug report, `@RedBeardCode`_ and `@tomviner`_ for the PR. * Create correct diff for strings ending with newlines. Fixes (`#1553`_). Thanks `@Vogtinator`_ for reporting. Thanks to `@RedBeardCode`_ and diff --git a/_pytest/main.py b/_pytest/main.py index 7376c170f..31b52c503 100644 --- a/_pytest/main.py +++ b/_pytest/main.py @@ -94,9 +94,8 @@ def wrap_session(config, doit): excinfo = _pytest._code.ExceptionInfo() if initstate < 2 and isinstance( excinfo.value, pytest.exit.Exception): - excinfo = _pytest._code.ExceptionInfo() sys.stderr.write('{0}: {1}\n'.format( - type(excinfo.value).__name__, excinfo.value.msg)) + excinfo.typename, excinfo.value.msg)) config.hook.pytest_keyboard_interrupt(excinfo=excinfo) session.exitstatus = EXIT_INTERRUPTED except: From f7ad173fee28dd2c04e87f6eae214d6ca35153b2 Mon Sep 17 00:00:00 2001 From: Dmitry Dygalo Date: Sat, 23 Jul 2016 17:37:58 +0200 Subject: [PATCH 17/18] Fixed collection of classes with custom ``__new__`` method --- AUTHORS | 1 + CHANGELOG.rst | 5 +++++ _pytest/python.py | 15 +++++++++++---- testing/python/collect.py | 12 ++++++++++++ 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/AUTHORS b/AUTHORS index 4ce6f0aa4..7ef2df84a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -35,6 +35,7 @@ David Díaz-Barquero David Mohr David Vierra Diego Russo +Dmitry Dygalo Edison Gustavo Muenz Eduardo Schettino Elizaveta Shashkova diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5cdb63470..c99947943 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -51,6 +51,10 @@ * ImportErrors in plugins now are a fatal error instead of issuing a pytest warning (`#1479`_). Thanks to `@The-Compiler`_ for the PR. +* Fixed collection of classes with custom ``__new__`` method. + Fixes `#1579`_. Thanks to `@Stranger6667`_ for the PR. + +.. _#1579: https://github.com/pytest-dev/pytest/issues/1579 .. _#1580: https://github.com/pytest-dev/pytest/pull/1580 .. _#1605: https://github.com/pytest-dev/pytest/issues/1605 .. _#1597: https://github.com/pytest-dev/pytest/pull/1597 @@ -72,6 +76,7 @@ .. _@DRMacIver: https://github.com/DRMacIver .. _@BeyondEvil: https://github.com/BeyondEvil .. _@JonathonSonesen: https://github.com/JonathonSonesen +.. _@Stranger6667: https://github.com/Stranger6667 2.9.2 diff --git a/_pytest/python.py b/_pytest/python.py index 6242fd497..812adf4b4 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -662,6 +662,10 @@ class Class(PyCollector): self.warn("C1", "cannot collect test class %r because it has a " "__init__ constructor" % self.obj.__name__) return [] + elif hasnew(self.obj): + self.warn("C1", "cannot collect test class %r because it has a " + "__new__ constructor" % self.obj.__name__) + return [] return [self._getcustomclass("Instance")(name="()", parent=self)] def setup(self): @@ -679,8 +683,7 @@ class Class(PyCollector): class Instance(PyCollector): def _getobj(self): - obj = self.parent.obj() - return obj + return self.parent.obj() def collect(self): self.session._fixturemanager.parsefactories(self) @@ -793,10 +796,14 @@ class Generator(FunctionMixin, PyCollector): def hasinit(obj): init = getattr(obj, '__init__', None) if init: - if init != object.__init__: - return True + return init != object.__init__ +def hasnew(obj): + new = getattr(obj, '__new__', None) + if new: + return new != object.__new__ + def fillfixtures(function): """ fill missing funcargs for a test function. """ diff --git a/testing/python/collect.py b/testing/python/collect.py index 22433da77..59760d8d1 100644 --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -109,6 +109,18 @@ class TestClass: colitems = modcol.collect() assert len(colitems) == 0 + def test_issue1579_namedtuple(self, testdir): + testdir.makepyfile(""" + import collections + + TestCase = collections.namedtuple('TestCase', ['a']) + """) + result = testdir.runpytest('-rw') + result.stdout.fnmatch_lines( + "*cannot collect test class 'TestCase' " + "because it has a __new__ constructor*" + ) + class TestGenerator: def test_generative_functions(self, testdir): From d72afe7e08033c5e6268ec77f68e894fb1b6bab1 Mon Sep 17 00:00:00 2001 From: Dmitry Dygalo Date: Mon, 25 Jul 2016 10:54:02 +0200 Subject: [PATCH 18/18] Fixed scope override inside metafunc.parametrize. Fixes #634 --- CHANGELOG.rst | 4 ++++ _pytest/python.py | 10 ++++++++-- testing/python/metafunc.py | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c99947943..164fe18b6 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -54,6 +54,10 @@ * Fixed collection of classes with custom ``__new__`` method. Fixes `#1579`_. Thanks to `@Stranger6667`_ for the PR. +* Fixed scope overriding inside metafunc.parametrize (`#634`_). + Thanks to `@Stranger6667`_ for the PR. + +.. _#634: https://github.com/pytest-dev/pytest/issues/634 .. _#1579: https://github.com/pytest-dev/pytest/issues/1579 .. _#1580: https://github.com/pytest-dev/pytest/pull/1580 .. _#1605: https://github.com/pytest-dev/pytest/issues/1605 diff --git a/_pytest/python.py b/_pytest/python.py index 812adf4b4..693d7c8c5 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1005,9 +1005,15 @@ class Metafunc(FuncargnamesCompatAttr): newmarks = newkeywords.setdefault(0, {}) newmarks[newmark.markname] = newmark - if scope is None: - scope = "function" + if self._arg2fixturedefs: + # Takes the most narrow scope from used fixtures + fixtures_scopes = [fixturedef[0].scope for fixturedef in self._arg2fixturedefs.values()] + for scope in reversed(scopes): + if scope in fixtures_scopes: + break + else: + scope = 'function' scopenum = scopes.index(scope) valtypes = {} for arg in argnames: diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index 13c709579..d6e45384d 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -819,6 +819,43 @@ class TestMetafuncFunctional: reprec = testdir.inline_run() reprec.assertoutcome(passed=5) + def test_parametrize_issue634(self, testdir): + testdir.makepyfile(''' + import pytest + + @pytest.fixture(scope='module') + def foo(request): + print('preparing foo-%d' % request.param) + return 'foo-%d' % request.param + + + def test_one(foo): + pass + + + def test_two(foo): + pass + + + test_two.test_with = (2, 3) + + + def pytest_generate_tests(metafunc): + params = (1, 2, 3, 4) + if not 'foo' in metafunc.fixturenames: + return + + test_with = getattr(metafunc.function, 'test_with', None) + if test_with: + params = test_with + metafunc.parametrize('foo', params, indirect=True) + + ''') + result = testdir.runpytest("-s") + output = result.stdout.str() + assert output.count('preparing foo-2') == 1 + assert output.count('preparing foo-3') == 1 + def test_parametrize_issue323(self, testdir): testdir.makepyfile(""" import pytest