From 69bab4ab0466af77b96d388db845de9d5ac78b7a Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Wed, 22 Jun 2016 09:52:48 +0200 Subject: [PATCH 01/31] added check for already existing option names to OptionGroup.addoption() --- AUTHORS | 1 + CHANGELOG.rst | 6 ++++++ _pytest/config.py | 4 ++++ testing/test_parseopt.py | 7 +++++++ 4 files changed, 18 insertions(+) diff --git a/AUTHORS b/AUTHORS index 1035a3552..ac8caf905 100644 --- a/AUTHORS +++ b/AUTHORS @@ -106,3 +106,4 @@ Tom Viner Trevor Bekolay Wouter van Ackooy Bernard Pratz +Stefan Zimmermann diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e9592daff..d95d66384 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -127,6 +127,11 @@ * +* ``OptionGroup.addoption()`` now checks if option names were already + added before, to make it easier to track down issues like `#1618`_. + Before, you only got exceptions later from ``argparse`` library, + giving no clue about the actual reason for double-added options. + .. _@milliams: https://github.com/milliams .. _@csaftoiu: https://github.com/csaftoiu .. _@flub: https://github.com/flub @@ -161,6 +166,7 @@ .. _#1628: https://github.com/pytest-dev/pytest/pull/1628 .. _#1629: https://github.com/pytest-dev/pytest/issues/1629 .. _#1633: https://github.com/pytest-dev/pytest/pull/1633 +.. _#1618: https://github.com/pytest-dev/pytest/issues/1618 **Bug Fixes** diff --git a/_pytest/config.py b/_pytest/config.py index 9a308df2b..a17587d9e 100644 --- a/_pytest/config.py +++ b/_pytest/config.py @@ -686,6 +686,10 @@ class OptionGroup: results in help showing '--two-words' only, but --twowords gets accepted **and** the automatic destination is in args.twowords """ + conflict = set(optnames).intersection( + name for opt in self.options for name in opt.names()) + if conflict: + raise ValueError("option names %s already added" % conflict) option = Argument(*optnames, **attrs) self._addoption_instance(option, shortupper=False) diff --git a/testing/test_parseopt.py b/testing/test_parseopt.py index 4b8667718..afec1114c 100644 --- a/testing/test_parseopt.py +++ b/testing/test_parseopt.py @@ -77,6 +77,13 @@ class TestParser: assert len(group.options) == 1 assert isinstance(group.options[0], parseopt.Argument) + def test_group_addoption_conflict(self): + group = parseopt.OptionGroup("hello again") + group.addoption("--option1", "--option-1", action="store_true") + with pytest.raises(ValueError) as err: + group.addoption("--option1", "--option-one", action="store_true") + assert str(set(["--option1"])) in str(err.value) + def test_group_shortopt_lowercase(self, parser): group = parser.getgroup("hello") pytest.raises(ValueError, """ From dc55551213a7e55fb7de7ff1d59ea9ba124f6514 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 24 Jun 2016 12:08:57 +0200 Subject: [PATCH 02/31] Start proposal for parametrize with fixtures --- doc/en/parametrize_with_fixtures.rst | 58 ++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 doc/en/parametrize_with_fixtures.rst diff --git a/doc/en/parametrize_with_fixtures.rst b/doc/en/parametrize_with_fixtures.rst new file mode 100644 index 000000000..06cfea5e3 --- /dev/null +++ b/doc/en/parametrize_with_fixtures.rst @@ -0,0 +1,58 @@ +========================= +Parametrize with fixtures +========================= + +Problem +------- + +As a user I have functional tests that I would like to run against various +scenarios. + +In this particular example we want to generate a new project based on a +cookiecutter template. We want to test default values but also data that +emulates user input. + +- use default values +- emulate user input + - specify 'author' + - specify 'project_slug' + - specify 'author' and 'project_slug' + +This is how a functional test could look like: + +.. code-block:: python + + import pytest + + @pytest.fixture + def default_context(): + return {'extra_context': {}} + + + @pytest.fixture(params=[ + {'author': 'alice'}, + {'project_slug': 'helloworld'}, + {'author': 'bob', 'project_slug': 'foobar'}, + ]) + def extra_context(request): + return {'extra_context': request.param} + + + @pytest.fixture(params=['default', 'extra']) + def context(request): + if request.param == 'default': + return request.getfuncargvalue('default_context') + else: + return request.getfuncargvalue('extra_context') + + + def test_generate_project(cookies, context): + """Call the cookiecutter API to generate a new project from a + template. + """ + result = cookies.bake(extra_context=context) + + assert result.exit_code == 0 + assert result.exception is None + assert result.project.isdir() + From d81f23009bda9e31bd8ccc4c8300fcbaad56fe5c Mon Sep 17 00:00:00 2001 From: Omar Kohl Date: Sun, 10 Apr 2016 19:57:45 +0200 Subject: [PATCH 03/31] Raise CollectError if pytest.skip() is called during collection pytest.skip() must not be used at module level because it can easily be misunderstood and used as a decorator instead of pytest.mark.skip, causing the whole module to be skipped instead of just the test being decorated. This is unexpected for users used to the @unittest.skip decorator and therefore it is best to bail out with a clean error when it happens. The pytest equivalent of @unittest.skip is @pytest.mark.skip . Adapt existing tests that were actually relying on this behaviour and add a test that explicitly test that collection fails. fix #607 --- _pytest/python.py | 6 ++++ testing/test_junitxml.py | 59 +++++++++++++++++++++++++++------------ testing/test_resultlog.py | 9 ------ testing/test_runner.py | 12 -------- testing/test_session.py | 8 +----- testing/test_skipping.py | 22 +++++++++++---- testing/test_terminal.py | 3 +- 7 files changed, 66 insertions(+), 53 deletions(-) diff --git a/_pytest/python.py b/_pytest/python.py index 1f65eee59..0520ecef0 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -656,6 +656,12 @@ class Module(pytest.File, PyCollector): "Make sure your test modules/packages have valid Python names." % (self.fspath, exc or exc_class) ) + except _pytest.runner.Skipped: + raise self.CollectError( + "Using @pytest.skip outside a test (e.g. as a test function " + "decorator) is not allowed. Use @pytest.mark.skip or " + "@pytest.mark.skipif instead." + ) #print "imported test module", mod self.config.pluginmanager.consider_module(mod) return mod diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index fde003e31..8291ea148 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- from xml.dom import minidom -from _pytest.main import EXIT_NOTESTSCOLLECTED import py import sys import os @@ -158,6 +157,47 @@ class TestPython: snode = tnode.find_first_by_tag("skipped") snode.assert_attr(type="pytest.skip", message="hello23", ) + def test_mark_skip_contains_name_reason(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.mark.skip(reason="hello24") + def test_skip(): + assert True + """) + result, dom = runandparse(testdir) + assert result.ret == 0 + node = dom.find_first_by_tag("testsuite") + node.assert_attr(skips=1) + tnode = node.find_first_by_tag("testcase") + tnode.assert_attr( + file="test_mark_skip_contains_name_reason.py", + line="1", + classname="test_mark_skip_contains_name_reason", + name="test_skip") + snode = tnode.find_first_by_tag("skipped") + snode.assert_attr(type="pytest.skip", message="hello24", ) + + def test_mark_skipif_contains_name_reason(self, testdir): + testdir.makepyfile(""" + import pytest + GLOBAL_CONDITION = True + @pytest.mark.skipif(GLOBAL_CONDITION, reason="hello25") + def test_skip(): + assert True + """) + result, dom = runandparse(testdir) + assert result.ret == 0 + node = dom.find_first_by_tag("testsuite") + node.assert_attr(skips=1) + tnode = node.find_first_by_tag("testcase") + tnode.assert_attr( + file="test_mark_skipif_contains_name_reason.py", + line="2", + classname="test_mark_skipif_contains_name_reason", + name="test_skip") + snode = tnode.find_first_by_tag("skipped") + snode.assert_attr(type="pytest.skip", message="hello25", ) + def test_classname_instance(self, testdir): testdir.makepyfile(""" class TestClass: @@ -351,23 +391,6 @@ class TestPython: fnode.assert_attr(message="collection failure") assert "SyntaxError" in fnode.toxml() - def test_collect_skipped(self, testdir): - testdir.makepyfile("import pytest; pytest.skip('xyz')") - result, dom = runandparse(testdir) - assert result.ret == EXIT_NOTESTSCOLLECTED - node = dom.find_first_by_tag("testsuite") - node.assert_attr(skips=1, tests=1) - tnode = node.find_first_by_tag("testcase") - tnode.assert_attr( - file="test_collect_skipped.py", - name="test_collect_skipped") - - # pytest doesn't give us a line here. - assert tnode["line"] is None - - fnode = tnode.find_first_by_tag("skipped") - fnode.assert_attr(message="collection skipped") - def test_unicode(self, testdir): value = 'hx\xc4\x85\xc4\x87\n' testdir.makepyfile(""" diff --git a/testing/test_resultlog.py b/testing/test_resultlog.py index 373d19213..e2d4fc263 100644 --- a/testing/test_resultlog.py +++ b/testing/test_resultlog.py @@ -83,19 +83,10 @@ class TestWithFunctionIntegration: def test_collection_report(self, testdir): ok = testdir.makepyfile(test_collection_ok="") - skip = testdir.makepyfile(test_collection_skip= - "import pytest ; pytest.skip('hello')") fail = testdir.makepyfile(test_collection_fail="XXX") lines = self.getresultlog(testdir, ok) assert not lines - lines = self.getresultlog(testdir, skip) - assert len(lines) == 2 - assert lines[0].startswith("S ") - assert lines[0].endswith("test_collection_skip.py") - assert lines[1].startswith(" ") - assert lines[1].endswith("test_collection_skip.py:1: Skipped: hello") - lines = self.getresultlog(testdir, fail) assert lines assert lines[0].startswith("F ") diff --git a/testing/test_runner.py b/testing/test_runner.py index 377801132..7db809b24 100644 --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -365,18 +365,6 @@ class TestSessionReports: assert res[0].name == "test_func1" assert res[1].name == "TestClass" - def test_skip_at_module_scope(self, testdir): - col = testdir.getmodulecol(""" - import pytest - pytest.skip("hello") - def test_func(): - pass - """) - rep = main.collect_one_node(col) - assert not rep.failed - assert not rep.passed - assert rep.skipped - reporttypes = [ runner.BaseReport, diff --git a/testing/test_session.py b/testing/test_session.py index 8c9386a12..e3b9f0fcc 100644 --- a/testing/test_session.py +++ b/testing/test_session.py @@ -174,10 +174,6 @@ class TestNewSession(SessionTests): class TestY(TestX): pass """, - test_two=""" - import pytest - pytest.skip('xxx') - """, test_three="xxxdsadsadsadsa", __init__="" ) @@ -189,11 +185,9 @@ class TestNewSession(SessionTests): started = reprec.getcalls("pytest_collectstart") finished = reprec.getreports("pytest_collectreport") assert len(started) == len(finished) - assert len(started) == 8 # XXX extra TopCollector + assert len(started) == 7 # XXX extra TopCollector colfail = [x for x in finished if x.failed] - colskipped = [x for x in finished if x.skipped] assert len(colfail) == 1 - assert len(colskipped) == 1 def test_minus_x_import_error(self, testdir): testdir.makepyfile(__init__="") diff --git a/testing/test_skipping.py b/testing/test_skipping.py index 2bfb6a8dc..f8e85d446 100644 --- a/testing/test_skipping.py +++ b/testing/test_skipping.py @@ -682,10 +682,6 @@ def test_skipped_reasons_functional(testdir): def test_method(self): doskip() """, - test_two = """ - from conftest import doskip - doskip() - """, conftest = """ import pytest def doskip(): @@ -694,7 +690,7 @@ def test_skipped_reasons_functional(testdir): ) result = testdir.runpytest('--report=skipped') result.stdout.fnmatch_lines([ - "*SKIP*3*conftest.py:3: test", + "*SKIP*2*conftest.py:3: test", ]) assert result.ret == 0 @@ -941,3 +937,19 @@ def test_xfail_item(testdir): assert not failed xfailed = [r for r in skipped if hasattr(r, 'wasxfail')] assert xfailed + + +def test_module_level_skip_error(testdir): + """ + Verify that using pytest.skip at module level causes a collection error + """ + testdir.makepyfile(""" + import pytest + @pytest.skip + def test_func(): + assert True + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines( + "*Using @pytest.skip outside a test * is not allowed*" + ) diff --git a/testing/test_terminal.py b/testing/test_terminal.py index 909450f55..589881c23 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -223,8 +223,7 @@ class TestCollectonly: """) result = testdir.runpytest("--collect-only", "-rs") result.stdout.fnmatch_lines([ - "SKIP*hello*", - "*1 skip*", + "*ERROR collecting*", ]) def test_collectonly_failed_module(self, testdir): From b3615ac29db523ae4071b7cd4b8ad35696f43b54 Mon Sep 17 00:00:00 2001 From: Omar Kohl Date: Tue, 19 Apr 2016 20:37:54 +0200 Subject: [PATCH 04/31] Update CHANGELOG with #607 and add version 3.0.0.dev1 --- CHANGELOG.rst | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d95d66384..7488694ad 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,24 @@ +3.0.0.dev1 +========== + +**Changes** + +* + +* + +* + +* Fix (`#607`_): pytest.skip() is no longer allowed at module level to + prevent misleading use as test function decorator. When used at a module + level an error will be raised during collection. + Thanks `@omarkohl`_ for the complete PR (`#1519`_). + +* + +.. _#607: https://github.com/pytest-dev/pytest/issues/607 +.. _#1519: https://github.com/pytest-dev/pytest/pull/1519 + 2.10.0.dev1 =========== From 84f0dcecf8c6001d6fe3785378160722ceb74ff3 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Sat, 25 Jun 2016 10:10:57 +0200 Subject: [PATCH 05/31] Add issues section to proposal doc --- doc/en/parametrize_with_fixtures.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/en/parametrize_with_fixtures.rst b/doc/en/parametrize_with_fixtures.rst index 06cfea5e3..e18887a64 100644 --- a/doc/en/parametrize_with_fixtures.rst +++ b/doc/en/parametrize_with_fixtures.rst @@ -56,3 +56,21 @@ This is how a functional test could look like: assert result.exception is None assert result.project.isdir() + +Issues +------ + +* By using ``request.getfuncargvalue()`` we rely on actual fixture function + execution to know what fixtures are involved, due to it's dynamic nature +* More importantly, ``request.getfuncargvalue()`` cannot be combined with + parametrized fixtures, such as ``extra_context`` +* This is very inconvenient if you wish to extend an existing test suite by + certain parameters for fixtures that are already used by tests + +pytest version 3.0 and higher reports an error if you try to run above code:: + + Failed: The requested fixture has no parameter defined for the current + test. + + Requested fixture 'extra_context' + From c6a711c2fce7259fb2b36a247771843bbf7c626d Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Sat, 25 Jun 2016 10:50:14 +0200 Subject: [PATCH 06/31] Add proposed solution using a module function --- doc/en/parametrize_with_fixtures.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/doc/en/parametrize_with_fixtures.rst b/doc/en/parametrize_with_fixtures.rst index e18887a64..4b6f21c03 100644 --- a/doc/en/parametrize_with_fixtures.rst +++ b/doc/en/parametrize_with_fixtures.rst @@ -74,3 +74,19 @@ pytest version 3.0 and higher reports an error if you try to run above code:: Requested fixture 'extra_context' + +Proposed solution +----------------- + +A new function that can be used in modules can be used to dynamically define +fixtures from existing ones. + +.. code-block:: python + + pytest.define_combined_fixture( + name='context', + fixtures=['default_context', 'extra_context'], + ) + +The new fixture ``context`` inherits the scope from the used fixtures. + From 4f8b8c8d312f659ab3c453df31ee05c5c2645728 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Sat, 25 Jun 2016 10:55:08 +0200 Subject: [PATCH 07/31] Add alternative approach that uses wrappers --- doc/en/parametrize_with_fixtures.rst | 48 ++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/doc/en/parametrize_with_fixtures.rst b/doc/en/parametrize_with_fixtures.rst index 4b6f21c03..3964d9d7d 100644 --- a/doc/en/parametrize_with_fixtures.rst +++ b/doc/en/parametrize_with_fixtures.rst @@ -90,3 +90,51 @@ fixtures from existing ones. The new fixture ``context`` inherits the scope from the used fixtures. +Alternative approach +-------------------- + +A new helper function named ``fixture_request`` tells pytest to yield all +parameters of a fixture. + +.. code-block:: python + + @pytest.fixture(params=[ + pytest.fixture_request('default_context'), + pytest.fixture_request('extra_context'), + ]) + def context(request): + """Returns all values for ``default_context``, one-by-one before it + does the same for ``extra_context``. + + request.param: + - {} + - {'author': 'alice'} + - {'project_slug': 'helloworld'} + - {'author': 'bob', 'project_slug': 'foobar'} + """ + return request.param + +.. note:: + + How should the scoping work in that case? Ideally it uses invocation scope + and relies on its params + +The same helper can be used in combination with ``pytest.mark.parametrize``. + +.. code-block:: python + + + @pytest.mark.parametrize( + 'context, expected_response_code', + [ + (pytest.fixture_request('default_context'), 0), + (pytest.fixture_request('extra_context'), 0), + ], + ) + def test_generate_project(cookies, context, exit_code): + """Call the cookiecutter API to generate a new project from a + template. + """ + result = cookies.bake(extra_context=context) + + assert result.exit_code == exit_code From 693859210a24d3ba58b5ab93e91d0eb53e9eb872 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Sat, 25 Jun 2016 11:00:54 +0200 Subject: [PATCH 08/31] Add yielded values to function example --- doc/en/parametrize_with_fixtures.rst | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/en/parametrize_with_fixtures.rst b/doc/en/parametrize_with_fixtures.rst index 3964d9d7d..762f1d8a4 100644 --- a/doc/en/parametrize_with_fixtures.rst +++ b/doc/en/parametrize_with_fixtures.rst @@ -88,7 +88,13 @@ fixtures from existing ones. fixtures=['default_context', 'extra_context'], ) -The new fixture ``context`` inherits the scope from the used fixtures. +The new fixture ``context`` inherits the scope from the used fixtures and yield +the following values. + +- ``{}`` +- ``{'author': 'alice'}`` +- ``{'project_slug': 'helloworld'}`` +- ``{'author': 'bob', 'project_slug': 'foobar'}`` Alternative approach -------------------- From 526c564576d641ffdef12654fca6d63dc8f66ebc Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Sat, 25 Jun 2016 11:06:17 +0200 Subject: [PATCH 09/31] Fix rst bullet point lists --- doc/en/parametrize_with_fixtures.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/en/parametrize_with_fixtures.rst b/doc/en/parametrize_with_fixtures.rst index 762f1d8a4..d65e5eb15 100644 --- a/doc/en/parametrize_with_fixtures.rst +++ b/doc/en/parametrize_with_fixtures.rst @@ -13,9 +13,13 @@ cookiecutter template. We want to test default values but also data that emulates user input. - use default values + - emulate user input + - specify 'author' + - specify 'project_slug' + - specify 'author' and 'project_slug' This is how a functional test could look like: @@ -92,8 +96,11 @@ The new fixture ``context`` inherits the scope from the used fixtures and yield the following values. - ``{}`` + - ``{'author': 'alice'}`` + - ``{'project_slug': 'helloworld'}`` + - ``{'author': 'bob', 'project_slug': 'foobar'}`` Alternative approach From 5860c609aeafa2fc2cf6b449fa83903c87fbc6af Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Sat, 25 Jun 2016 11:09:46 +0200 Subject: [PATCH 10/31] Remove note on scoping --- doc/en/parametrize_with_fixtures.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/doc/en/parametrize_with_fixtures.rst b/doc/en/parametrize_with_fixtures.rst index d65e5eb15..ab3ffecf0 100644 --- a/doc/en/parametrize_with_fixtures.rst +++ b/doc/en/parametrize_with_fixtures.rst @@ -127,11 +127,6 @@ parameters of a fixture. """ return request.param -.. note:: - - How should the scoping work in that case? Ideally it uses invocation scope - and relies on its params - The same helper can be used in combination with ``pytest.mark.parametrize``. .. code-block:: python From 891e1677b68b2fccffb36110e544dd97467e3a1d Mon Sep 17 00:00:00 2001 From: Oliver Bestwalter Date: Sat, 25 Jun 2016 12:27:05 +0200 Subject: [PATCH 11/31] Remove all py.test-X* entry points. The versioned, suffixed entry points are not documented and a leftover from a pre-virtualenv world. They also are broken for wheels. --- setup.py | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/setup.py b/setup.py index 6966fe1f2..bcc1f1766 100644 --- a/setup.py +++ b/setup.py @@ -69,7 +69,8 @@ def main(): platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], author='Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna Laugher, Florian Bruhin and others', author_email='holger at merlinux.eu', - entry_points=make_entry_points(), + entry_points={'console_scripts': + ['pytest=pytest:main', 'py.test=pytest:main']}, classifiers=classifiers, cmdclass={'test': PyTest}, # the following should be enabled for release @@ -81,29 +82,6 @@ def main(): ) -def cmdline_entrypoints(versioninfo, platform, basename): - target = 'pytest:main' - if platform.startswith('java'): - points = {'py.test-jython': target} - else: - if basename.startswith('pypy'): - points = {'py.test-%s' % basename: target} - else: # cpython - points = {'py.test-%s.%s' % versioninfo[:2] : target} - points['py.test'] = target - points['pytest'] = target - return points - - -def make_entry_points(): - basename = os.path.basename(sys.executable) - points = cmdline_entrypoints(sys.version_info, sys.platform, basename) - keys = list(points.keys()) - keys.sort() - l = ['%s = %s' % (x, points[x]) for x in keys] - return {'console_scripts': l} - - class PyTest(Command): user_options = [] def initialize_options(self): From acfdd85dffa8ddbf61ad4ad987980dd265a8c5e9 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Sat, 25 Jun 2016 14:42:19 +0200 Subject: [PATCH 12/31] Move document to proposals subfolder --- doc/en/{ => proposals}/parametrize_with_fixtures.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename doc/en/{ => proposals}/parametrize_with_fixtures.rst (100%) diff --git a/doc/en/parametrize_with_fixtures.rst b/doc/en/proposals/parametrize_with_fixtures.rst similarity index 100% rename from doc/en/parametrize_with_fixtures.rst rename to doc/en/proposals/parametrize_with_fixtures.rst From eb98a8eefbe959dace13c809e03715bf0c2f4914 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Sat, 25 Jun 2016 14:52:57 +0200 Subject: [PATCH 13/31] Change version in issues section to pytest 3.0 only --- doc/en/proposals/parametrize_with_fixtures.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/en/proposals/parametrize_with_fixtures.rst b/doc/en/proposals/parametrize_with_fixtures.rst index ab3ffecf0..e8c31d0d8 100644 --- a/doc/en/proposals/parametrize_with_fixtures.rst +++ b/doc/en/proposals/parametrize_with_fixtures.rst @@ -71,7 +71,7 @@ Issues * This is very inconvenient if you wish to extend an existing test suite by certain parameters for fixtures that are already used by tests -pytest version 3.0 and higher reports an error if you try to run above code:: +pytest version 3.0 reports an error if you try to run above code:: Failed: The requested fixture has no parameter defined for the current test. From 1b6bc4d606a98d88b332a5e380af64ac92c2d610 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Sat, 25 Jun 2016 14:58:18 +0200 Subject: [PATCH 14/31] Add feature proposal to changelog --- CHANGELOG.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d95d66384..01c214ca6 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -106,6 +106,9 @@ Thanks `@Vogtinator`_ for reporting. Thanks to `@RedBeardCode`_ and `@tomviner`_ for PR. +* Add proposal to docs for a new feature that enables users to combine multiple + fixtures into one. Thanks to `@hpk42`_ and `@hackebrot`_. + * .. _#1580: https://github.com/pytest-dev/pytest/pull/1580 From 95b83958f49d2a247e0fdb322bcc54de47b89e67 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Sat, 25 Jun 2016 11:10:23 +0200 Subject: [PATCH 15/31] add xfailing test for issue #568 --- testing/test_mark.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/testing/test_mark.py b/testing/test_mark.py index 9b3e15b37..cf7dc6f16 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -418,6 +418,32 @@ class TestFunctional: items, rec = testdir.inline_genitems(p) self.assert_markers(items, test_foo=('a', 'b'), test_bar=('a',)) + + @pytest.mark.issue568 + @pytest.mark.xfail(reason="markers smear, needs fixing") + def test_mark_decorator_subclass_does_not_propagate_to_base2(self, testdir): + p = testdir.makepyfile(""" + import pytest + + class TestBase: + def test_foo(self): + pass + + @pytest.mark.b + class TestSub(TestBase): + pass + + + class TestOtherSub(TestBase): + pass + + """) + items, rec = testdir.inline_genitems(p) + base_item, sub_item, sub_item_other = items + assert not hasattr(base_item.obj, 'b') + assert not hasattr(sub_item_other.obj, 'b') + + def test_mark_decorator_baseclasses_merged(self, testdir): p = testdir.makepyfile(""" import pytest From 72450408ed55bf4ed852a4df25b68ee41fca6433 Mon Sep 17 00:00:00 2001 From: Oliver Bestwalter Date: Sat, 25 Jun 2016 16:00:49 +0200 Subject: [PATCH 16/31] add changes in CHANGELOG.rst --- CHANGELOG.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b5b6ec81d..804707f27 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -47,6 +47,11 @@ `#1629`_. Thanks `@obestwalter`_ and `@davehunt`_ for the complete PR (`#1633`_) +* Remove all py.test-X* entry points. The versioned, suffixed entry points + were never documented and a leftover from a pre-virtualenv era. They were + also broken for wheels, so removing these entry points also removes a + potential source of confusion. + **Changes** * Fixtures marked with ``@pytest.fixture`` can now use ``yield`` statements exactly like From 3a9e9fdf82f39e0dc9b6e60578ac2d22a93c7520 Mon Sep 17 00:00:00 2001 From: Oliver Bestwalter Date: Sat, 25 Jun 2016 16:04:23 +0200 Subject: [PATCH 17/31] rephrase changes in CHANGELOG.rst --- CHANGELOG.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 804707f27..3ab4c2228 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -48,9 +48,9 @@ (`#1633`_) * Remove all py.test-X* entry points. The versioned, suffixed entry points - were never documented and a leftover from a pre-virtualenv era. They were - also broken for wheels, so removing these entry points also removes a - potential source of confusion. + were never documented and a leftover from a pre-virtualenv era. These entry + points also created broken entry points in wheels, so removing them also + removes a source of confusion for users. **Changes** From 856e6cab75eb9926e6d6866e40cca821c99fd6a7 Mon Sep 17 00:00:00 2001 From: Ted Xiao Date: Sat, 25 Jun 2016 22:12:42 +0800 Subject: [PATCH 18/31] add --override-ini option to overrides ini values Signed-off-by: Ted Xiao --- AUTHORS | 1 + CHANGELOG.rst | 6 +++ _pytest/config.py | 32 +++++++++++---- _pytest/helpconfig.py | 4 ++ testing/test_config.py | 89 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 124 insertions(+), 8 deletions(-) diff --git a/AUTHORS b/AUTHORS index 48d9e26d6..fd543b145 100644 --- a/AUTHORS +++ b/AUTHORS @@ -100,6 +100,7 @@ Samuele Pedroni Steffen Allner Stephan Obermann Tareq Alayan +Ted Xiao Simon Gomizelj Stefano Taschini Stefan Farmbauer diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9ec08b03c..faaa65374 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -79,6 +79,10 @@ finalizer and has access to the fixture's result cache. Thanks `@d6e`_, `@sallner`_ +* New cli flag ``--override-ini`` or ``-o`` that overrides values from the ini file. + Example '-o xfail_strict=True'. A complete ini-options can be viewed + by py.test --help. Thanks `@blueyed`_ and `@fengxx`_ for the PR + **Changes** @@ -155,6 +159,8 @@ .. _@nikratio: https://github.com/nikratio .. _@RedBeardCode: https://github.com/RedBeardCode .. _@Vogtinator: https://github.com/Vogtinator +.. _@blueyed: https://github.com/blueyed +.. _@fengxx: https://github.com/fengxx * Fix `#1421`_: Exit tests if a collection error occurs and add ``--continue-on-collection-errors`` option to restore previous behaviour. diff --git a/_pytest/config.py b/_pytest/config.py index 3a8ce1c78..72613d41f 100644 --- a/_pytest/config.py +++ b/_pytest/config.py @@ -1003,14 +1003,16 @@ class Config(object): description, type, default = self._parser._inidict[name] except KeyError: raise ValueError("unknown configuration value: %r" %(name,)) - try: - value = self.inicfg[name] - except KeyError: - if default is not None: - return default - if type is None: - return '' - return [] + value = self._get_override_ini_value(name) + if value is None: + try: + value = self.inicfg[name] + except KeyError: + if default is not None: + return default + if type is None: + return '' + return [] if type == "pathlist": dp = py.path.local(self.inicfg.config.path).dirpath() l = [] @@ -1041,6 +1043,20 @@ class Config(object): l.append(relroot) return l + def _get_override_ini_value(self, name): + value = None + # override_ini is a list of list, to support both -o foo1=bar1 foo2=bar2 and + # and -o foo1=bar1 -o foo2=bar2 options + # always use the last item if multiple value set for same ini-name, + # e.g. -o foo=bar1 -o foo=bar2 will set foo to bar2 + if self.getoption("override_ini", None): + for ini_config_list in self.option.override_ini: + for ini_config in ini_config_list: + (key, user_ini_value) = ini_config.split("=", 1) + if key == name: + value = user_ini_value + return value + def getoption(self, name, default=notset, skip=False): """ return command line option value. diff --git a/_pytest/helpconfig.py b/_pytest/helpconfig.py index 15b0ada77..ae8daea9c 100644 --- a/_pytest/helpconfig.py +++ b/_pytest/helpconfig.py @@ -20,6 +20,10 @@ def pytest_addoption(parser): group.addoption('--debug', action="store_true", dest="debug", default=False, help="store internal tracing debug information in 'pytestdebug.log'.") + # support for "--overwrite-ini ININAME=INIVALUE" to override values from the ini file + # Example '-o xfail_strict=True'. + group._addoption('-o', '--override-ini', nargs='*', dest="override_ini", action="append", + help="overrides ini values which do not have a separate command-line flag") @pytest.hookimpl(hookwrapper=True) diff --git a/testing/test_config.py b/testing/test_config.py index 2d9ae6e0e..db007c2d1 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -583,3 +583,92 @@ class TestRootdir: inifile = tmpdir.ensure("pytest.ini") rootdir, inifile, inicfg = determine_setup(inifile, [tmpdir]) assert rootdir == tmpdir + +class TestOverrideIniArgs: + """ test --override-ini """ + @pytest.mark.parametrize("name", "setup.cfg tox.ini pytest.ini".split()) + def test_override_ini_names(self, testdir, name): + testdir.tmpdir.join(name).write(py.std.textwrap.dedent(""" + [pytest] + custom = 1.0 + """)) + testdir.makeconftest(""" + def pytest_addoption(parser): + parser.addini("custom", "") + """) + testdir.makepyfile(""" + def test_pass(pytestconfig): + ini_val = pytestconfig.getini("custom") + print('\\ncustom_option:%s\\n' % ini_val) + """) + + result = testdir.runpytest("--override-ini", "custom=2.0", "-s") + assert result.ret == 0 + result.stdout.fnmatch_lines([ + "custom_option:2.0" + ]) + + result = testdir.runpytest("--override-ini", "custom=2.0", + "--override-ini=custom=3.0", "-s") + assert result.ret == 0 + result.stdout.fnmatch_lines([ + "custom_option:3.0" + ]) + + + def test_override_ini_pathlist(self, testdir): + testdir.makeconftest(""" + def pytest_addoption(parser): + parser.addini("paths", "my new ini value", type="pathlist") + """) + testdir.makeini(""" + [pytest] + paths=blah.py + """) + testdir.makepyfile(""" + import py.path + def test_pathlist(pytestconfig): + config_paths = pytestconfig.getini("paths") + print(config_paths) + for cpf in config_paths: + print('\\nuser_path:%s' % cpf.basename) + """) + result = testdir.runpytest("--override-ini", 'paths=foo/bar1.py foo/bar2.py', "-s") + result.stdout.fnmatch_lines([ + "user_path:bar1.py", + "user_path:bar2.py" + ]) + + def test_override_multiple_and_default(self, testdir): + testdir.makeconftest(""" + def pytest_addoption(parser): + parser.addini("custom_option_1", "", default="o1") + parser.addini("custom_option_2", "", default="o2") + parser.addini("custom_option_3", "", default=False, type="bool") + parser.addini("custom_option_4", "", default=True, type="bool") + + """) + testdir.makeini(""" + [pytest] + custom_option_1=custom_option_1 + custom_option_2=custom_option_2 + """) + testdir.makepyfile(""" + def test_multiple_options(pytestconfig): + prefix="custom_option" + for x in range(1,5): + ini_value=pytestconfig.getini("%s_%d" % (prefix, x)) + print('\\nini%d:%s' % (x, ini_value)) + """) + result = testdir.runpytest("--override-ini", + 'custom_option_1=fulldir=/tmp/user1', + 'custom_option_2=url=/tmp/user2?a=b&d=e', + "-o", 'custom_option_3=True', + "-o", 'custom_option_4=no', + "-s") + result.stdout.fnmatch_lines([ + "ini1:fulldir=/tmp/user1", + "ini2:url=/tmp/user2?a=b&d=e", + "ini3:True", + "ini4:False" + ]) \ No newline at end of file From c17027e5767bda8ac8237be4deea03a7fd898415 Mon Sep 17 00:00:00 2001 From: Vasily Kuznetsov Date: Sat, 25 Jun 2016 18:45:47 +0200 Subject: [PATCH 19/31] Warn about asserts on tuples (fixes #1562) --- _pytest/assertion/rewrite.py | 20 +++++++++++++++----- testing/test_assertion.py | 8 ++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/_pytest/assertion/rewrite.py b/_pytest/assertion/rewrite.py index fd4f66cd0..921d17a10 100644 --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -125,7 +125,7 @@ class AssertionRewritingHook(object): co = _read_pyc(fn_pypath, pyc, state.trace) if co is None: state.trace("rewriting %r" % (fn,)) - source_stat, co = _rewrite_test(state, fn_pypath) + source_stat, co = _rewrite_test(self.config, fn_pypath) if co is None: # Probably a SyntaxError in the test. return None @@ -252,8 +252,9 @@ N = "\n".encode("utf-8") cookie_re = re.compile(r"^[ \t\f]*#.*coding[:=][ \t]*[-\w.]+") BOM_UTF8 = '\xef\xbb\xbf' -def _rewrite_test(state, fn): +def _rewrite_test(config, fn): """Try to read and rewrite *fn* and return the code object.""" + state = config._assertstate try: stat = fn.stat() source = fn.read("rb") @@ -298,7 +299,7 @@ def _rewrite_test(state, fn): # Let this pop up again in the real import. state.trace("failed to parse: %r" % (fn,)) return None, None - rewrite_asserts(tree) + rewrite_asserts(tree, fn, config) try: co = compile(tree, fn.strpath, "exec") except SyntaxError: @@ -354,9 +355,9 @@ def _read_pyc(source, pyc, trace=lambda x: None): return co -def rewrite_asserts(mod): +def rewrite_asserts(mod, module_path=None, config=None): """Rewrite the assert statements in mod.""" - AssertionRewriter().run(mod) + AssertionRewriter(module_path, config).run(mod) def _saferepr(obj): @@ -543,6 +544,11 @@ class AssertionRewriter(ast.NodeVisitor): """ + def __init__(self, module_path, config): + super(AssertionRewriter, self).__init__() + self.module_path = module_path + self.config = config + def run(self, mod): """Find all assert statements in *mod* and rewrite them.""" if not mod.body: @@ -683,6 +689,10 @@ class AssertionRewriter(ast.NodeVisitor): the expression is false. """ + if isinstance(assert_.test, ast.Tuple) and self.config is not None: + fslocation = (self.module_path, assert_.lineno) + self.config.warn('R1', 'assertion is always true, perhaps ' + 'remove parentheses?', fslocation=fslocation) self.statements = [] self.variables = [] self.variable_counter = itertools.count() diff --git a/testing/test_assertion.py b/testing/test_assertion.py index dfa1b9420..4694bb261 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -640,3 +640,11 @@ def test_diff_newline_at_end(monkeypatch, testdir): * + asdf * ? + """) + +def test_assert_tuple_warning(testdir): + testdir.makepyfile(""" + def test_tuple(): + assert(False, 'you shall not pass') + """) + result = testdir.runpytest('-rw') + result.stdout.fnmatch_lines('WR1*:2 assertion is always true*') From 0db4ae15a95f76b9f71848140318a4a6613e39d9 Mon Sep 17 00:00:00 2001 From: Vasily Kuznetsov Date: Sat, 25 Jun 2016 19:34:55 +0200 Subject: [PATCH 20/31] Update changelog --- CHANGELOG.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index faaa65374..a5338fc9c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -79,6 +79,10 @@ finalizer and has access to the fixture's result cache. Thanks `@d6e`_, `@sallner`_ +* Issue a warning for asserts whose test is a tuple literal. Such asserts will + never fail because tuples are always truthy and are usually a mistake + (see `#1562`_). Thanks `@kvas-it`_, for the PR. + * New cli flag ``--override-ini`` or ``-o`` that overrides values from the ini file. Example '-o xfail_strict=True'. A complete ini-options can be viewed by py.test --help. Thanks `@blueyed`_ and `@fengxx`_ for the PR @@ -207,6 +211,7 @@ .. _#1619: https://github.com/pytest-dev/pytest/issues/1619 .. _#372: https://github.com/pytest-dev/pytest/issues/372 .. _#1544: https://github.com/pytest-dev/pytest/issues/1544 +.. _#1562: https://github.com/pytest-dev/pytest/issues/1562 .. _#1616: https://github.com/pytest-dev/pytest/pull/1616 .. _#1628: https://github.com/pytest-dev/pytest/pull/1628 .. _#1629: https://github.com/pytest-dev/pytest/issues/1629 From 6d4cee21598f35100b46c5d892a8b3af99ec8087 Mon Sep 17 00:00:00 2001 From: Vasily Kuznetsov Date: Sun, 26 Jun 2016 02:21:51 +0200 Subject: [PATCH 21/31] Add a test for indirect use of tuple in the assert that should not cause a warning --- testing/test_assertion.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/testing/test_assertion.py b/testing/test_assertion.py index 4694bb261..60b1fb02b 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -648,3 +648,13 @@ def test_assert_tuple_warning(testdir): """) result = testdir.runpytest('-rw') result.stdout.fnmatch_lines('WR1*:2 assertion is always true*') + +def test_assert_indirect_tuple_no_warning(testdir): + testdir.makepyfile(""" + def test_tuple(): + tpl = ('foo', 'bar') + assert tpl + """) + result = testdir.runpytest('-rw') + output = '\n'.join(result.stdout.lines) + assert 'WR1' not in output From 0e2ebc96ff0606a59cc24868f527b4094cc1e2a6 Mon Sep 17 00:00:00 2001 From: RedBeardCode Date: Sat, 25 Jun 2016 11:27:10 +0200 Subject: [PATCH 22/31] Remove deprecated cmd options Fixes #1657 --- CHANGELOG.rst | 15 +++- _pytest/assertion/__init__.py | 13 --- _pytest/config.py | 2 +- _pytest/genscript.py | 132 ------------------------------ _pytest/standalonetemplate.py | 89 -------------------- _pytest/terminal.py | 14 ---- doc/en/assert.rst | 3 + doc/en/getting-started.rst | 38 +-------- doc/en/goodpractices.rst | 34 -------- doc/en/plugins.rst | 1 - doc/en/test/plugin/genscript.rst | 28 ------- doc/en/test/plugin/helpconfig.rst | 2 - doc/en/test/plugin/links.rst | 2 - doc/en/test/plugin/terminal.rst | 2 - testing/test_assertion.py | 14 +--- testing/test_config.py | 2 +- testing/test_genscript.py | 51 ------------ testing/test_skipping.py | 6 +- testing/test_terminal.py | 9 -- 19 files changed, 26 insertions(+), 431 deletions(-) delete mode 100755 _pytest/genscript.py delete mode 100755 _pytest/standalonetemplate.py delete mode 100644 doc/en/test/plugin/genscript.rst delete mode 100644 testing/test_genscript.py diff --git a/CHANGELOG.rst b/CHANGELOG.rst index faaa65374..86e0d2b7e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -16,8 +16,22 @@ * +**Incompatible changes** + +* Removing the following deprecated commandline options + + * genscript + * no-assert + * nomagic + * report + + Thanks to `@RedBeardCode`_ for the PR(`#1664`_) + + .. _#607: https://github.com/pytest-dev/pytest/issues/607 .. _#1519: https://github.com/pytest-dev/pytest/pull/1519 +.. _#1664: https://github.com/pytest-dev/pytest/pull/1664 + 2.10.0.dev1 =========== @@ -146,7 +160,6 @@ * Add proposal to docs for a new feature that enables users to combine multiple fixtures into one. Thanks to `@hpk42`_ and `@hackebrot`_. -* .. _#1580: https://github.com/pytest-dev/pytest/pull/1580 .. _#1605: https://github.com/pytest-dev/pytest/issues/1605 diff --git a/_pytest/assertion/__init__.py b/_pytest/assertion/__init__.py index 099d5f0b4..4f28c8da7 100644 --- a/_pytest/assertion/__init__.py +++ b/_pytest/assertion/__init__.py @@ -25,15 +25,6 @@ def pytest_addoption(parser): 'rewrite' (the default) rewrites assert statements in test modules on import to provide assert expression information. """) - group.addoption('--no-assert', - action="store_true", - default=False, - dest="noassert", - help="DEPRECATED equivalent to --assert=plain") - group.addoption('--nomagic', '--no-magic', - action="store_true", - default=False, - help="DEPRECATED equivalent to --assert=plain") class AssertionState: @@ -48,10 +39,6 @@ class AssertionState: def pytest_load_initial_conftests(early_config, parser, args): ns, ns_unknown_args = parser.parse_known_and_unknown_args(args) mode = ns.assertmode - no_assert = ns.noassert - no_magic = ns.nomagic - if no_assert or no_magic: - mode = "plain" if mode == "rewrite": try: import ast # noqa diff --git a/_pytest/config.py b/_pytest/config.py index 72613d41f..8ed77c61d 100644 --- a/_pytest/config.py +++ b/_pytest/config.py @@ -64,7 +64,7 @@ _preinit = [] default_plugins = ( "mark main terminal runner python pdb unittest capture skipping " - "tmpdir monkeypatch recwarn pastebin helpconfig nose assertion genscript " + "tmpdir monkeypatch recwarn pastebin helpconfig nose assertion " "junitxml resultlog doctest cacheprovider setuponly setupplan").split() builtin_plugins = set(default_plugins) diff --git a/_pytest/genscript.py b/_pytest/genscript.py deleted file mode 100755 index 62139add9..000000000 --- a/_pytest/genscript.py +++ /dev/null @@ -1,132 +0,0 @@ -""" (deprecated) generate a single-file self-contained version of pytest """ -import os -import sys -import pkgutil - -import py -import _pytest - - - -def find_toplevel(name): - for syspath in sys.path: - base = py.path.local(syspath) - lib = base/name - if lib.check(dir=1): - return lib - mod = base.join("%s.py" % name) - if mod.check(file=1): - return mod - raise LookupError(name) - -def pkgname(toplevel, rootpath, path): - parts = path.parts()[len(rootpath.parts()):] - return '.'.join([toplevel] + [x.purebasename for x in parts]) - -def pkg_to_mapping(name): - toplevel = find_toplevel(name) - name2src = {} - if toplevel.check(file=1): # module - name2src[toplevel.purebasename] = toplevel.read() - else: # package - for pyfile in toplevel.visit('*.py'): - pkg = pkgname(name, toplevel, pyfile) - name2src[pkg] = pyfile.read() - # with wheels py source code might be not be installed - # and the resulting genscript is useless, just bail out. - assert name2src, "no source code found for %r at %r" %(name, toplevel) - return name2src - -def compress_mapping(mapping): - import base64, pickle, zlib - data = pickle.dumps(mapping, 2) - data = zlib.compress(data, 9) - data = base64.encodestring(data) - data = data.decode('ascii') - return data - - -def compress_packages(names): - mapping = {} - for name in names: - mapping.update(pkg_to_mapping(name)) - return compress_mapping(mapping) - -def generate_script(entry, packages): - data = compress_packages(packages) - tmpl = py.path.local(__file__).dirpath().join('standalonetemplate.py') - exe = tmpl.read() - exe = exe.replace('@SOURCES@', data) - exe = exe.replace('@ENTRY@', entry) - return exe - - -def pytest_addoption(parser): - group = parser.getgroup("debugconfig") - group.addoption("--genscript", action="store", default=None, - dest="genscript", metavar="path", - help="create standalone pytest script at given target path.") - -def pytest_cmdline_main(config): - import _pytest.config - genscript = config.getvalue("genscript") - if genscript: - tw = _pytest.config.create_terminal_writer(config) - tw.line("WARNING: usage of genscript is deprecated.", - red=True) - deps = ['py', '_pytest', 'pytest'] # pluggy is vendored - if sys.version_info < (2,7): - deps.append("argparse") - tw.line("generated script will run on python2.6-python3.3++") - else: - tw.line("WARNING: generated script will not run on python2.6 " - "due to 'argparse' dependency. Use python2.6 " - "to generate a python2.6 compatible script", red=True) - script = generate_script( - 'import pytest; raise SystemExit(pytest.cmdline.main())', - deps, - ) - genscript = py.path.local(genscript) - genscript.write(script) - tw.line("generated pytest standalone script: %s" % genscript, - bold=True) - return 0 - - -def pytest_namespace(): - return {'freeze_includes': freeze_includes} - - -def freeze_includes(): - """ - Returns a list of module names used by pytest that should be - included by cx_freeze. - """ - result = list(_iter_all_modules(py)) - result += list(_iter_all_modules(_pytest)) - return result - - -def _iter_all_modules(package, prefix=''): - """ - Iterates over the names of all modules that can be found in the given - package, recursively. - - Example: - _iter_all_modules(_pytest) -> - ['_pytest.assertion.newinterpret', - '_pytest.capture', - '_pytest.core', - ... - ] - """ - if type(package) is not str: - path, prefix = package.__path__[0], package.__name__ + '.' - else: - path = package - for _, name, is_package in pkgutil.iter_modules([path]): - if is_package: - for m in _iter_all_modules(os.path.join(path, name), prefix=name + '.'): - yield prefix + m - else: - yield prefix + name diff --git a/_pytest/standalonetemplate.py b/_pytest/standalonetemplate.py deleted file mode 100755 index 50799b0dd..000000000 --- a/_pytest/standalonetemplate.py +++ /dev/null @@ -1,89 +0,0 @@ -#! /usr/bin/env python - -# Hi There! -# You may be wondering what this giant blob of binary data here is, you might -# even be worried that we're up to something nefarious (good for you for being -# paranoid!). This is a base64 encoding of a zip file, this zip file contains -# a fully functional basic pytest script. -# -# Pytest is a thing that tests packages, pytest itself is a package that some- -# one might want to install, especially if they're looking to run tests inside -# some package they want to install. Pytest has a lot of code to collect and -# execute tests, and other such sort of "tribal knowledge" that has been en- -# coded in its code base. Because of this we basically include a basic copy -# of pytest inside this blob. We do this because it let's you as a maintainer -# or application developer who wants people who don't deal with python much to -# easily run tests without installing the complete pytest package. -# -# If you're wondering how this is created: you can create it yourself if you -# have a complete pytest installation by using this command on the command- -# line: ``pytest --genscript=runtests.py``. - -sources = """ -@SOURCES@""" - -import sys -import base64 -import zlib - -class DictImporter(object): - def __init__(self, sources): - self.sources = sources - - def find_module(self, fullname, path=None): - if fullname == "argparse" and sys.version_info >= (2,7): - # we were generated with = (3, 0): - exec("def do_exec(co, loc): exec(co, loc)\n") - import pickle - sources = sources.encode("ascii") # ensure bytes - sources = pickle.loads(zlib.decompress(base64.decodebytes(sources))) - else: - import cPickle as pickle - exec("def do_exec(co, loc): exec co in loc\n") - sources = pickle.loads(zlib.decompress(base64.decodestring(sources))) - - importer = DictImporter(sources) - sys.meta_path.insert(0, importer) - entry = "@ENTRY@" - do_exec(entry, locals()) # noqa diff --git a/_pytest/terminal.py b/_pytest/terminal.py index 825f553ef..b88a19e13 100644 --- a/_pytest/terminal.py +++ b/_pytest/terminal.py @@ -27,9 +27,6 @@ def pytest_addoption(parser): group._addoption('-l', '--showlocals', action="store_true", dest="showlocals", default=False, help="show locals in tracebacks (disabled by default).") - group._addoption('--report', - action="store", dest="report", default=None, metavar="opts", - help="(deprecated, use -r)") group._addoption('--tb', metavar="style", action="store", dest="tbstyle", default='auto', choices=['auto', 'long', 'short', 'no', 'line', 'native'], @@ -54,17 +51,6 @@ def pytest_configure(config): def getreportopt(config): reportopts = "" - optvalue = config.option.report - if optvalue: - py.builtin.print_("DEPRECATED: use -r instead of --report option.", - file=sys.stderr) - if optvalue: - for setting in optvalue.split(","): - setting = setting.strip() - if setting == "skipped": - reportopts += "s" - elif setting == "xfailed": - reportopts += "x" reportchars = config.option.reportchars if reportchars: for char in reportchars: diff --git a/doc/en/assert.rst b/doc/en/assert.rst index 03bcc8a3d..bde51fd35 100644 --- a/doc/en/assert.rst +++ b/doc/en/assert.rst @@ -314,3 +314,6 @@ For further information, Benjamin Peterson wrote up `Behind the scenes of pytest .. versionchanged:: 2.1 Introduce the ``--assert`` option. Deprecate ``--no-assert`` and ``--nomagic``. + +.. versionchanged:: 3.0 + Removes the ``--no-assert`` and``--nomagic`` options. diff --git a/doc/en/getting-started.rst b/doc/en/getting-started.rst index 5455d4a5d..6981ff4a9 100644 --- a/doc/en/getting-started.rst +++ b/doc/en/getting-started.rst @@ -193,45 +193,9 @@ Where to go next Here are a few suggestions where to go next: * :ref:`cmdline` for command line invocation examples -* :ref:`good practices ` for virtualenv, test layout, genscript support +* :ref:`good practices ` for virtualenv, test layout * :ref:`fixtures` for providing a functional baseline to your tests * :ref:`apiref` for documentation and examples on using ``pytest`` * :ref:`plugins` managing and writing plugins -.. _`installation issues`: - -Known Installation issues ------------------------------- - -easy_install or pip not found? -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -.. _`install pip`: http://www.pip-installer.org/en/latest/index.html - -`Install pip`_ for a state of the art python package installer. - -Install `setuptools`_ to get ``easy_install`` which allows to install -``.egg`` binary format packages in addition to source-based ones. - -pytest not found on Windows despite installation? -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -.. _`Python for Windows`: http://www.imladris.com/Scripts/PythonForWindows.html - -- **Windows**: If "easy_install" or "pytest" are not found - you need to add the Python script path to your ``PATH``, see here: - `Python for Windows`_. You may alternatively use an `ActivePython install`_ - which does this for you automatically. - -.. _`ActivePython install`: http://www.activestate.com/activepython/downloads - -.. _`Jython does not create command line launchers`: http://bugs.jython.org/issue1491 - -- **Jython2.5.1 on Windows XP**: `Jython does not create command line launchers`_ - so ``pytest`` will not work correctly. You may install pytest on - CPython and type ``pytest --genscript=mytest`` and then use - ``jython mytest`` to run your tests with Jython using ``pytest``. - - :ref:`examples` for more complex examples - .. include:: links.inc diff --git a/doc/en/goodpractices.rst b/doc/en/goodpractices.rst index 2cd96ea31..e1c4b0b5c 100644 --- a/doc/en/goodpractices.rst +++ b/doc/en/goodpractices.rst @@ -243,38 +243,4 @@ using the ``--pytest-args`` or ``-a`` command-line option. For example:: is equivalent to running ``pytest --durations=5``. -.. _standalone: -.. _`genscript method`: - -(deprecated) Create a pytest standalone script ------------------------------------------------ - -.. deprecated:: 2.8 - -.. note:: - - ``genscript`` has been deprecated because: - - * It cannot support plugins, rendering its usefulness extremely limited; - * Tooling has become much better since ``genscript`` was introduced; - * It is possible to build a zipped ``pytest`` application without the - shortcomings above. - - There's no planned version in which this command will be removed - at the moment of this writing, but its use is discouraged for new - applications. - -If you are a maintainer or application developer and want people -who don't deal with python much to easily run tests you may generate -a standalone ``pytest`` script:: - - pytest --genscript=runtests.py - -This generates a ``runtests.py`` script which is a fully functional basic -``pytest`` script, running unchanged under Python2 and Python3. -You can tell people to download the script and then e.g. run it like this:: - - python runtests.py - - .. include:: links.inc diff --git a/doc/en/plugins.rst b/doc/en/plugins.rst index 0d5ca7e05..0a83c9b8b 100644 --- a/doc/en/plugins.rst +++ b/doc/en/plugins.rst @@ -138,7 +138,6 @@ in the `pytest repository `_. _pytest.capture _pytest.config _pytest.doctest - _pytest.genscript _pytest.helpconfig _pytest.junitxml _pytest.mark diff --git a/doc/en/test/plugin/genscript.rst b/doc/en/test/plugin/genscript.rst deleted file mode 100644 index ee80f233f..000000000 --- a/doc/en/test/plugin/genscript.rst +++ /dev/null @@ -1,28 +0,0 @@ - -(deprecated) generate standalone test script to be distributed along with an application. -============================================================================ - - -.. contents:: - :local: - - - -command line options --------------------- - - -``--genscript=path`` - create standalone ``pytest`` script at given target path. - -Start improving this plugin in 30 seconds -========================================= - - -1. Download `pytest_genscript.py`_ plugin source code -2. put it somewhere as ``pytest_genscript.py`` into your import path -3. a subsequent ``pytest`` run will use your local version - -Checkout customize_, other plugins_ or `get in contact`_. - -.. include:: links.txt diff --git a/doc/en/test/plugin/helpconfig.rst b/doc/en/test/plugin/helpconfig.rst index 00399b690..326b75c45 100644 --- a/doc/en/test/plugin/helpconfig.rst +++ b/doc/en/test/plugin/helpconfig.rst @@ -18,8 +18,6 @@ command line options early-load given plugin (multi-allowed). ``--trace-config`` trace considerations of conftest.py files. -``--nomagic`` - don't reinterpret asserts, no traceback cutting. ``--debug`` generate and show internal debugging information. ``--help-config`` diff --git a/doc/en/test/plugin/links.rst b/doc/en/test/plugin/links.rst index aa965e730..6dec2b484 100644 --- a/doc/en/test/plugin/links.rst +++ b/doc/en/test/plugin/links.rst @@ -2,10 +2,8 @@ .. _`pytest_recwarn.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_recwarn.py .. _`unittest`: unittest.html .. _`pytest_monkeypatch.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_monkeypatch.py -.. _`pytest_genscript.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_genscript.py .. _`pastebin`: pastebin.html .. _`skipping`: skipping.html -.. _`genscript`: genscript.html .. _`plugins`: index.html .. _`mark`: mark.html .. _`tmpdir`: tmpdir.html diff --git a/doc/en/test/plugin/terminal.rst b/doc/en/test/plugin/terminal.rst index 0c0796415..e07d4f721 100644 --- a/doc/en/test/plugin/terminal.rst +++ b/doc/en/test/plugin/terminal.rst @@ -18,8 +18,6 @@ command line options show extra test summary info as specified by chars (f)ailed, (s)skipped, (x)failed, (X)passed. ``-l, --showlocals`` show locals in tracebacks (disabled by default). -``--report=opts`` - (deprecated, use -r) ``--tb=style`` traceback print mode (long/short/line/no). ``--full-trace`` diff --git a/testing/test_assertion.py b/testing/test_assertion.py index dfa1b9420..15d494332 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -474,16 +474,8 @@ def test_assertion_options(testdir): """) result = testdir.runpytest() assert "3 == 4" in result.stdout.str() - off_options = (("--no-assert",), - ("--nomagic",), - ("--no-assert", "--nomagic"), - ("--assert=plain",), - ("--assert=plain", "--no-assert"), - ("--assert=plain", "--nomagic"), - ("--assert=plain", "--no-assert", "--nomagic")) - for opt in off_options: - result = testdir.runpytest_subprocess(*opt) - assert "3 == 4" not in result.stdout.str() + result = testdir.runpytest_subprocess("--assert=plain") + assert "3 == 4" not in result.stdout.str() def test_old_assert_mode(testdir): testdir.makepyfile(""" @@ -559,7 +551,7 @@ def test_warn_missing(testdir): result.stderr.fnmatch_lines([ "*WARNING*assert statements are not executed*", ]) - result = testdir.run(sys.executable, "-OO", "-m", "pytest", "--no-assert") + result = testdir.run(sys.executable, "-OO", "-m", "pytest") result.stderr.fnmatch_lines([ "*WARNING*assert statements are not executed*", ]) diff --git a/testing/test_config.py b/testing/test_config.py index db007c2d1..fe550dbdd 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -365,7 +365,7 @@ def test_options_on_small_file_do_not_blow_up(testdir): """) for opts in ([], ['-l'], ['-s'], ['--tb=no'], ['--tb=short'], - ['--tb=long'], ['--fulltrace'], ['--nomagic'], + ['--tb=long'], ['--fulltrace'], ['--traceconfig'], ['-v'], ['-v', '-v']): runfiletest(opts + [path]) diff --git a/testing/test_genscript.py b/testing/test_genscript.py deleted file mode 100644 index 1260a5a6b..000000000 --- a/testing/test_genscript.py +++ /dev/null @@ -1,51 +0,0 @@ -import pytest -import sys - - -@pytest.fixture(scope="module") -def standalone(request): - return Standalone(request) - -class Standalone: - def __init__(self, request): - self.testdir = request.getfuncargvalue("testdir") - script = "mypytest" - result = self.testdir.runpytest("--genscript=%s" % script) - assert result.ret == 0 - self.script = self.testdir.tmpdir.join(script) - assert self.script.check() - - def run(self, anypython, testdir, *args): - return testdir._run(anypython, self.script, *args) - -def test_gen(testdir, anypython, standalone): - if sys.version_info >= (2,7): - result = testdir._run(anypython, "-c", - "import sys;print (sys.version_info >=(2,7))") - assert result.ret == 0 - if result.stdout.str() == "False": - pytest.skip("genscript called from python2.7 cannot work " - "earlier python versions") - result = standalone.run(anypython, testdir, '--version') - if result.ret == 2: - result.stderr.fnmatch_lines(["*ERROR: setuptools not installed*"]) - elif result.ret == 0: - result.stderr.fnmatch_lines([ - "*imported from*mypytest*" - ]) - p = testdir.makepyfile("def test_func(): assert 0") - result = standalone.run(anypython, testdir, p) - assert result.ret != 0 - else: - pytest.fail("Unexpected return code") - - -def test_freeze_includes(): - """ - Smoke test for freeze_includes(), to ensure that it works across all - supported python versions. - """ - includes = pytest.freeze_includes() - assert len(includes) > 1 - assert '_pytest.genscript' in includes - diff --git a/testing/test_skipping.py b/testing/test_skipping.py index f8e85d446..d2a925a4e 100644 --- a/testing/test_skipping.py +++ b/testing/test_skipping.py @@ -209,7 +209,7 @@ class TestXFail: def test_this_false(): assert 1 """) - result = testdir.runpytest(p, '--report=xfailed', ) + result = testdir.runpytest(p, '-rx', ) result.stdout.fnmatch_lines([ "*test_one*test_this*", "*NOTRUN*noway", @@ -227,7 +227,7 @@ class TestXFail: def setup_module(mod): raise ValueError(42) """) - result = testdir.runpytest(p, '--report=xfailed', ) + result = testdir.runpytest(p, '-rx', ) result.stdout.fnmatch_lines([ "*test_one*test_this*", "*NOTRUN*hello", @@ -688,7 +688,7 @@ def test_skipped_reasons_functional(testdir): pytest.skip('test') """ ) - result = testdir.runpytest('--report=skipped') + result = testdir.runpytest('-rs') result.stdout.fnmatch_lines([ "*SKIP*2*conftest.py:3: test", ]) diff --git a/testing/test_terminal.py b/testing/test_terminal.py index 589881c23..0d1aac999 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -590,16 +590,7 @@ def test_getreportopt(): class config: class option: reportchars = "" - config.option.report = "xfailed" - assert getreportopt(config) == "x" - config.option.report = "xfailed,skipped" - assert getreportopt(config) == "xs" - - config.option.report = "skipped,xfailed" - assert getreportopt(config) == "sx" - - config.option.report = "skipped" config.option.reportchars = "sf" assert getreportopt(config) == "sf" From 1b0dbd8c406771530e6dbf42927774b65d40ba6a Mon Sep 17 00:00:00 2001 From: RedBeardCode Date: Sat, 25 Jun 2016 14:11:39 +0200 Subject: [PATCH 23/31] Move the freezing function from genscript.py to a new module freeze_support.py --- _pytest/config.py | 3 ++- _pytest/freeze_support.py | 45 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 _pytest/freeze_support.py diff --git a/_pytest/config.py b/_pytest/config.py index 8ed77c61d..463d8f04f 100644 --- a/_pytest/config.py +++ b/_pytest/config.py @@ -65,7 +65,8 @@ _preinit = [] default_plugins = ( "mark main terminal runner python pdb unittest capture skipping " "tmpdir monkeypatch recwarn pastebin helpconfig nose assertion " - "junitxml resultlog doctest cacheprovider setuponly setupplan").split() + "junitxml resultlog doctest cacheprovider freeze_support " + "setuponly setupplan").split() builtin_plugins = set(default_plugins) builtin_plugins.add("pytester") diff --git a/_pytest/freeze_support.py b/_pytest/freeze_support.py new file mode 100644 index 000000000..f78ccd298 --- /dev/null +++ b/_pytest/freeze_support.py @@ -0,0 +1,45 @@ +""" +Provides a function to report all internal modules for using freezing tools +pytest +""" + +def pytest_namespace(): + return {'freeze_includes': freeze_includes} + + +def freeze_includes(): + """ + Returns a list of module names used by py.test that should be + included by cx_freeze. + """ + import py + import _pytest + result = list(_iter_all_modules(py)) + result += list(_iter_all_modules(_pytest)) + return result + + +def _iter_all_modules(package, prefix=''): + """ + Iterates over the names of all modules that can be found in the given + package, recursively. + Example: + _iter_all_modules(_pytest) -> + ['_pytest.assertion.newinterpret', + '_pytest.capture', + '_pytest.core', + ... + ] + """ + import os + import pkgutil + if type(package) is not str: + path, prefix = package.__path__[0], package.__name__ + '.' + else: + path = package + for _, name, is_package in pkgutil.iter_modules([path]): + if is_package: + for m in _iter_all_modules(os.path.join(path, name), prefix=name + '.'): + yield prefix + m + else: + yield prefix + name \ No newline at end of file From 7239f36466aadded38b91f02ce6d4ed116595915 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sun, 26 Jun 2016 19:41:01 +0200 Subject: [PATCH 24/31] Improve formatting in CHANGELOG --- CHANGELOG.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 86e0d2b7e..6068b4c32 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -20,10 +20,10 @@ * Removing the following deprecated commandline options - * genscript - * no-assert - * nomagic - * report + * ``--genscript`` + * ``--no-assert`` + * ``--nomagic`` + * ``--report`` Thanks to `@RedBeardCode`_ for the PR(`#1664`_) From b9536608c523141450897a208755a738306022fa Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sun, 26 Jun 2016 20:36:04 +0200 Subject: [PATCH 25/31] Add issue and obestwalter to CHANGELOG Fix #1632 --- CHANGELOG.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2c4a8906e..e17847787 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -86,7 +86,8 @@ * Remove all py.test-X* entry points. The versioned, suffixed entry points were never documented and a leftover from a pre-virtualenv era. These entry points also created broken entry points in wheels, so removing them also - removes a source of confusion for users. + removes a source of confusion for users (`#1632`_). + Thanks `@obestwalter`_ for the PR. **Changes** @@ -152,6 +153,7 @@ * +.. _#1632: https://github.com/pytest-dev/pytest/issues/1632 .. _#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 @@ -165,6 +167,7 @@ .. _@Vogtinator: https://github.com/Vogtinator .. _@blueyed: https://github.com/blueyed .. _@fengxx: https://github.com/fengxx +.. _@obestwalter: https://github.com/obestwalter * Fix `#1421`_: Exit tests if a collection error occurs and add ``--continue-on-collection-errors`` option to restore previous behaviour. From 44695ae46c6b8e2c5fdc9978b1fe798486869fe5 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sun, 26 Jun 2016 23:44:07 +0200 Subject: [PATCH 26/31] Fix CHANGELOG: obestwalter appearing twice due to mergig separate PRs --- CHANGELOG.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 802c169e0..b9315c9ca 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -184,7 +184,6 @@ .. _@Vogtinator: https://github.com/Vogtinator .. _@blueyed: https://github.com/blueyed .. _@fengxx: https://github.com/fengxx -.. _@obestwalter: https://github.com/obestwalter * Fix `#1421`_: Exit tests if a collection error occurs and add ``--continue-on-collection-errors`` option to restore previous behaviour. From 76756c0c0b0385ec6bed2f883a2149ed42186180 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Mon, 27 Jun 2016 11:57:21 +0200 Subject: [PATCH 27/31] mark tests: use better name of the test for #568 --- testing/test_mark.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/test_mark.py b/testing/test_mark.py index cf7dc6f16..cf59baed9 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -420,8 +420,8 @@ class TestFunctional: @pytest.mark.issue568 - @pytest.mark.xfail(reason="markers smear, needs fixing") - def test_mark_decorator_subclass_does_not_propagate_to_base2(self, testdir): + @pytest.mark.xfail(reason="markers smear on methods of base classes") + def test_mark_should_not_pass_to_siebling_class(self, testdir): p = testdir.makepyfile(""" import pytest From e877e255873777d6cff6040a638dd1d749bc1add Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Mon, 27 Jun 2016 14:26:12 +0200 Subject: [PATCH 28/31] drop python 3.0-3.2 support code from setup.py addresses #1627 --- CHANGELOG.rst | 2 ++ setup.py | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b9315c9ca..74a3dff7a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -27,10 +27,12 @@ Thanks to `@RedBeardCode`_ for the PR(`#1664`_) +* removed support code for python 3 < 3.3 addresssing (`#1627`_) .. _#607: https://github.com/pytest-dev/pytest/issues/607 .. _#1519: https://github.com/pytest-dev/pytest/pull/1519 .. _#1664: https://github.com/pytest-dev/pytest/pull/1664 +.. _#1627: https://github.com/pytest-dev/pytest/pull/1627 2.10.0.dev1 diff --git a/setup.py b/setup.py index bcc1f1766..23ac0eb03 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ classifiers = ['Development Status :: 6 - Mature', 'Topic :: Software Development :: Libraries', 'Topic :: Utilities'] + [ ('Programming Language :: Python :: %s' % x) for x in - '2 2.6 2.7 3 3.2 3.3 3.4 3.5'.split()] + '2 2.6 2.7 3 3.3 3.4 3.5'.split()] with open('README.rst') as fd: long_description = fd.read() @@ -51,10 +51,10 @@ def main(): install_requires = ['py>=1.4.29'] # pluggy is vendored in _pytest.vendored_packages extras_require = {} if has_environment_marker_support(): - extras_require[':python_version=="2.6" or python_version=="3.0" or python_version=="3.1"'] = ['argparse'] + extras_require[':python_version=="2.6"'] = ['argparse'] extras_require[':sys_platform=="win32"'] = ['colorama'] else: - if sys.version_info < (2, 7) or (3,) <= sys.version_info < (3, 2): + if sys.version_info < (2, 7): install_requires.append('argparse') if sys.platform == 'win32': install_requires.append('colorama') From 7dc8d1ab60a8ab0616070a582225b8930f32bc51 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Mon, 27 Jun 2016 18:19:00 +0200 Subject: [PATCH 29/31] fix typo and remove python3.2 from readme --- CHANGELOG.rst | 2 +- README.rst | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 74a3dff7a..e67cffc70 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -27,7 +27,7 @@ Thanks to `@RedBeardCode`_ for the PR(`#1664`_) -* removed support code for python 3 < 3.3 addresssing (`#1627`_) +* removed support code for python 3 < 3.3 addressing (`#1627`_) .. _#607: https://github.com/pytest-dev/pytest/issues/607 .. _#1519: https://github.com/pytest-dev/pytest/pull/1519 diff --git a/README.rst b/README.rst index 3c658ee93..a9d0ea3e6 100644 --- a/README.rst +++ b/README.rst @@ -17,7 +17,7 @@ :target: https://ci.appveyor.com/project/pytestbot/pytest The ``pytest`` framework makes it easy to write small tests, yet -scales to support complex functional testing for applications and libraries. +scales to support complex functional testing for applications and libraries. An example of a simple test: @@ -35,7 +35,7 @@ To execute it:: $ pytest ======= test session starts ======== - platform linux -- Python 3.4.3, pytest-2.8.5, py-1.4.31, pluggy-0.3.1 + platform linux -- Python 3.4.3, pytest-2.8.5, py-1.4.31, pluggy-0.3.1 collected 1 items test_sample.py F @@ -52,7 +52,7 @@ To execute it:: ======= 1 failed in 0.12 seconds ======== Due to ``pytest``'s detailed assertion introspection, only plain ``assert`` statements are used. See `getting-started `_ for more examples. - + Features -------- @@ -69,7 +69,7 @@ Features - Can run `unittest `_ (or trial), `nose `_ test suites out of the box; -- Python2.6+, Python3.2+, PyPy-2.3, Jython-2.5 (untested); +- Python2.6+, Python3.3+, PyPy-2.3, Jython-2.5 (untested); - Rich plugin architecture, with over 150+ `external plugins `_ and thriving community; From 2a43237527eeb304f50d5c81fcb81b1f66a357fa Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Mon, 27 Jun 2016 18:20:56 +0200 Subject: [PATCH 30/31] docs: no longer include python 3.0-3.2 in the index page --- doc/en/index.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/doc/en/index.rst b/doc/en/index.rst index 04b4512da..feb0d4bcc 100644 --- a/doc/en/index.rst +++ b/doc/en/index.rst @@ -6,7 +6,7 @@ pytest: helps you write better programs **a mature full-featured Python testing tool** - - runs on Posix/Windows, Python 2.6-3.5, PyPy and (possibly still) Jython-2.5.1 + - runs on Posix/Windows, Python 2.6, 2.7 and 3.3-3.5, PyPy and (possibly still) Jython-2.5.1 - free and open source software, distributed under the terms of the :ref:`MIT license ` - **well tested** with more than a thousand tests against itself - **strict backward compatibility policy** for safe pytest upgrades @@ -57,5 +57,3 @@ pytest: helps you write better programs .. _`easy`: http://bruynooghe.blogspot.com/2009/12/skipping-slow-test-by-default-in-pytest.html - - From 1451a1ab002db532550277cb9e1981af5b35088f Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Thu, 30 Jun 2016 10:03:40 +0200 Subject: [PATCH 31/31] remove unsupported python versions from code/source xfail --- testing/code/test_source.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/testing/code/test_source.py b/testing/code/test_source.py index 007ad1433..e78f4b241 100644 --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -385,8 +385,7 @@ def test_deindent(): lines = deindent(source.splitlines()) assert lines == ['', 'def f():', ' def g():', ' pass', ' '] -@pytest.mark.xfail("sys.version_info[:3] < (2,7,0) or " - "((3,0) <= sys.version_info[:2] < (3,2))") +@pytest.mark.xfail("sys.version_info[:3] < (2,7,0)") def test_source_of_class_at_eof_without_newline(tmpdir): # this test fails because the implicit inspect.getsource(A) below # does not return the "x = 1" last line. @@ -656,4 +655,3 @@ something '''""" result = getstatement(1, source) assert str(result) == "'''\n'''" -