From e23af009f9b3a03002296e760e8f067fc84b840e Mon Sep 17 00:00:00 2001 From: Christoph Buchner Date: Mon, 23 Oct 2017 22:09:21 +0200 Subject: [PATCH 01/20] Introduce a dedicated section about conftest.py Also reorganize conftest-related content a bit. Closes #1505, closes #1770. --- changelog/1505.doc | 1 + doc/en/assert.rst | 4 ++-- doc/en/fixture.rst | 44 +++++++++++++++++++++++++++----------- doc/en/plugins.rst | 3 +-- doc/en/writing_plugins.rst | 2 -- 5 files changed, 35 insertions(+), 19 deletions(-) create mode 100644 changelog/1505.doc diff --git a/changelog/1505.doc b/changelog/1505.doc new file mode 100644 index 000000000..1b303d1bd --- /dev/null +++ b/changelog/1505.doc @@ -0,0 +1 @@ +Introduce a dedicated section about conftest.py. diff --git a/doc/en/assert.rst b/doc/en/assert.rst index a8ddaecd8..d9e044356 100644 --- a/doc/en/assert.rst +++ b/doc/en/assert.rst @@ -209,8 +209,8 @@ the ``pytest_assertrepr_compare`` hook. .. autofunction:: _pytest.hookspec.pytest_assertrepr_compare :noindex: -As an example consider adding the following hook in a conftest.py which -provides an alternative explanation for ``Foo`` objects:: +As an example consider adding the following hook in a :ref:`conftest.py ` +file which provides an alternative explanation for ``Foo`` objects:: # content of conftest.py from test_foocompare import Foo diff --git a/doc/en/fixture.rst b/doc/en/fixture.rst index dace0514e..1d7ba8640 100644 --- a/doc/en/fixture.rst +++ b/doc/en/fixture.rst @@ -127,10 +127,39 @@ It's a prime example of `dependency injection`_ where fixture functions take the role of the *injector* and test functions are the *consumers* of fixture objects. +.. _`conftest.py`: +.. _`conftest`: + +``conftest.py``: sharing fixture functions +------------------------------------------ + +If during implementing your tests you realize that you +want to use a fixture function from multiple test files you can move it +to a ``conftest.py`` file. +You don't need to import the fixture you want to use in a test, it +automatically gets discovered by pytest. The discovery of +fixture functions starts at test classes, then test modules, then +``conftest.py`` files and finally builtin and third party plugins. + +You can also use the ``conftest.py`` file to implement +:ref:`local per-directory plugins `. + +Sharing test data +----------------- + +If you want to make test data from files available to your tests, a good way +to do this is by loading these data in a fixture for use by your tests. +This makes use of the automatic caching mechanisms of pytest. + +Another good approach is by adding the data files in the ``tests`` folder. +There are also community plugins available to help managing this aspect of +testing, e.g. `pytest-datadir `__ +and `pytest-datafiles `__. + .. _smtpshared: -Scope: Sharing a fixture across tests in a class, module or session -------------------------------------------------------------------- +Scope: sharing a fixture instance across tests in a class, module or session +---------------------------------------------------------------------------- .. regendoc:wipe @@ -878,17 +907,6 @@ All test methods in this TestClass will use the transaction fixture while other test classes or functions in the module will not use it unless they also add a ``transact`` reference. - -Shifting (visibility of) fixture functions ----------------------------------------------------- - -If during implementing your tests you realize that you -want to use a fixture function from multiple test files you can move it -to a :ref:`conftest.py ` file or even separately installable -:ref:`plugins ` without changing test code. The discovery of -fixtures functions starts at test classes, then test modules, then -``conftest.py`` files and finally builtin and third party plugins. - Overriding fixtures on various levels ------------------------------------- diff --git a/doc/en/plugins.rst b/doc/en/plugins.rst index ec031e9e0..4a6772ca3 100644 --- a/doc/en/plugins.rst +++ b/doc/en/plugins.rst @@ -94,7 +94,7 @@ environment you can type:: and will get an extended test header which shows activated plugins and their names. It will also print local plugins aka -:ref:`conftest.py ` files when they are loaded. +:ref:`conftest.py ` files when they are loaded. .. _`cmdunregister`: @@ -155,4 +155,3 @@ in the `pytest repository `_. _pytest.terminal _pytest.tmpdir _pytest.unittest - diff --git a/doc/en/writing_plugins.rst b/doc/en/writing_plugins.rst index d5ad73b4b..5dccdb884 100644 --- a/doc/en/writing_plugins.rst +++ b/doc/en/writing_plugins.rst @@ -57,9 +57,7 @@ Plugin discovery order at tool startup .. _`pytest/plugin`: http://bitbucket.org/pytest-dev/pytest/src/tip/pytest/plugin/ .. _`conftest.py plugins`: -.. _`conftest.py`: .. _`localplugin`: -.. _`conftest`: .. _`local conftest plugins`: conftest.py: local per-directory plugins From 52aadcd7c126f05a7219db88ac8d3d233b3de5c3 Mon Sep 17 00:00:00 2001 From: Sviatoslav Abakumov Date: Tue, 24 Oct 2017 11:17:01 +0300 Subject: [PATCH 02/20] Strip whitespace from markers in INI config Resolves #2856. --- _pytest/mark.py | 5 +++-- changelog/2856.bugfix | 1 + testing/test_mark.py | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 changelog/2856.bugfix diff --git a/_pytest/mark.py b/_pytest/mark.py index 91aa3747e..2a4a0f265 100644 --- a/_pytest/mark.py +++ b/_pytest/mark.py @@ -272,8 +272,9 @@ class MarkGenerator: pass self._markers = l = set() for line in self._config.getini("markers"): - beginning = line.split(":", 1) - x = beginning[0].split("(", 1)[0] + marker, _ = line.split(":", 1) + marker = marker.rstrip() + x = marker.split("(", 1)[0] l.add(x) if name not in self._markers: raise AttributeError("%r not a registered marker" % (name,)) diff --git a/changelog/2856.bugfix b/changelog/2856.bugfix new file mode 100644 index 000000000..7e5fc8fc7 --- /dev/null +++ b/changelog/2856.bugfix @@ -0,0 +1 @@ +Strip whitespace from marker names when reading them from INI config. diff --git a/testing/test_mark.py b/testing/test_mark.py index dc51bbac0..9ae88a665 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -169,6 +169,23 @@ def test_markers_option(testdir): ]) +def test_ini_markers_whitespace(testdir): + testdir.makeini(""" + [pytest] + markers = + a1 : this is a whitespace marker + """) + testdir.makepyfile(""" + import pytest + + @pytest.mark.a1 + def test_markers(): + assert True + """) + rec = testdir.inline_run("--strict", "-m", "a1") + rec.assertoutcome(passed=1) + + def test_markers_option_with_plugin_in_current_dir(testdir): testdir.makeconftest('pytest_plugins = "flip_flop"') testdir.makepyfile(flip_flop="""\ From 3427d27d5a517a265502feba359df4f7c46ed611 Mon Sep 17 00:00:00 2001 From: Sviatoslav Abakumov Date: Wed, 25 Oct 2017 10:54:43 +0300 Subject: [PATCH 03/20] Try to get docstring from module node --- _pytest/assertion/rewrite.py | 11 ++++++++--- testing/test_assertrewrite.py | 34 +++++++++++++++++++++------------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/_pytest/assertion/rewrite.py b/_pytest/assertion/rewrite.py index 992002b81..06687a0c8 100644 --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -595,15 +595,17 @@ class AssertionRewriter(ast.NodeVisitor): # docstrings and __future__ imports. aliases = [ast.alias(py.builtin.builtins.__name__, "@py_builtins"), ast.alias("_pytest.assertion.rewrite", "@pytest_ar")] - expect_docstring = True + doc = getattr(mod, "docstring", None) + expect_docstring = doc is None + if doc is not None and self.is_rewrite_disabled(doc): + return pos = 0 lineno = 0 for item in mod.body: if (expect_docstring and isinstance(item, ast.Expr) and isinstance(item.value, ast.Str)): doc = item.value.s - if "PYTEST_DONT_REWRITE" in doc: - # The module has disabled assertion rewriting. + if self.is_rewrite_disabled(doc): return lineno += len(doc) - 1 expect_docstring = False @@ -637,6 +639,9 @@ class AssertionRewriter(ast.NodeVisitor): not isinstance(field, ast.expr)): nodes.append(field) + def is_rewrite_disabled(self, docstring): + return "PYTEST_DONT_REWRITE" in docstring + def variable(self): """Get a new variable.""" # Use a character invalid in python identifiers to avoid clashing. diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index 2d61b7440..c935a7862 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -65,13 +65,15 @@ class TestAssertionRewrite(object): def test_place_initial_imports(self): s = """'Doc string'\nother = stuff""" m = rewrite(s) - assert isinstance(m.body[0], ast.Expr) - assert isinstance(m.body[0].value, ast.Str) - for imp in m.body[1:3]: + if sys.version_info < (3, 7): + assert isinstance(m.body[0], ast.Expr) + assert isinstance(m.body[0].value, ast.Str) + del m.body[0] + for imp in m.body[0:2]: assert isinstance(imp, ast.Import) assert imp.lineno == 2 assert imp.col_offset == 0 - assert isinstance(m.body[3], ast.Assign) + assert isinstance(m.body[2], ast.Assign) s = """from __future__ import with_statement\nother_stuff""" m = rewrite(s) assert isinstance(m.body[0], ast.ImportFrom) @@ -82,14 +84,16 @@ class TestAssertionRewrite(object): assert isinstance(m.body[3], ast.Expr) s = """'doc string'\nfrom __future__ import with_statement\nother""" m = rewrite(s) - assert isinstance(m.body[0], ast.Expr) - assert isinstance(m.body[0].value, ast.Str) - assert isinstance(m.body[1], ast.ImportFrom) - for imp in m.body[2:4]: + if sys.version_info < (3, 7): + assert isinstance(m.body[0], ast.Expr) + assert isinstance(m.body[0].value, ast.Str) + del m.body[0] + assert isinstance(m.body[0], ast.ImportFrom) + for imp in m.body[1:3]: assert isinstance(imp, ast.Import) assert imp.lineno == 3 assert imp.col_offset == 0 - assert isinstance(m.body[4], ast.Expr) + assert isinstance(m.body[3], ast.Expr) s = """from . import relative\nother_stuff""" m = rewrite(s) for imp in m.body[0:2]: @@ -101,10 +105,14 @@ class TestAssertionRewrite(object): def test_dont_rewrite(self): s = """'PYTEST_DONT_REWRITE'\nassert 14""" m = rewrite(s) - assert len(m.body) == 2 - assert isinstance(m.body[0].value, ast.Str) - assert isinstance(m.body[1], ast.Assert) - assert m.body[1].msg is None + if sys.version_info < (3, 7): + assert len(m.body) == 2 + assert isinstance(m.body[0], ast.Expr) + assert isinstance(m.body[0].value, ast.Str) + del m.body[0] + else: + assert len(m.body) == 1 + assert m.body[0].msg is None def test_name(self): def f(): From fd7bfa30d0a6d2415f5669bdbe035dba1fcad5b2 Mon Sep 17 00:00:00 2001 From: Sviatoslav Abakumov Date: Wed, 25 Oct 2017 11:05:07 +0300 Subject: [PATCH 04/20] Put imports on the last line unless there are other exprs --- _pytest/assertion/rewrite.py | 5 +++-- testing/test_assertrewrite.py | 11 +++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/_pytest/assertion/rewrite.py b/_pytest/assertion/rewrite.py index 06687a0c8..c3966340a 100644 --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -600,20 +600,21 @@ class AssertionRewriter(ast.NodeVisitor): if doc is not None and self.is_rewrite_disabled(doc): return pos = 0 - lineno = 0 + lineno = 1 for item in mod.body: if (expect_docstring and isinstance(item, ast.Expr) and isinstance(item.value, ast.Str)): doc = item.value.s if self.is_rewrite_disabled(doc): return - lineno += len(doc) - 1 expect_docstring = False elif (not isinstance(item, ast.ImportFrom) or item.level > 0 or item.module != "__future__"): lineno = item.lineno break pos += 1 + else: + lineno = item.lineno imports = [ast.Import([alias], lineno=lineno, col_offset=0) for alias in aliases] mod.body[pos:pos] = imports diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index c935a7862..45c0c7b16 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -82,6 +82,17 @@ class TestAssertionRewrite(object): assert imp.lineno == 2 assert imp.col_offset == 0 assert isinstance(m.body[3], ast.Expr) + s = """'doc string'\nfrom __future__ import with_statement""" + m = rewrite(s) + if sys.version_info < (3, 7): + assert isinstance(m.body[0], ast.Expr) + assert isinstance(m.body[0].value, ast.Str) + del m.body[0] + assert isinstance(m.body[0], ast.ImportFrom) + for imp in m.body[1:3]: + assert isinstance(imp, ast.Import) + assert imp.lineno == 2 + assert imp.col_offset == 0 s = """'doc string'\nfrom __future__ import with_statement\nother""" m = rewrite(s) if sys.version_info < (3, 7): From 383239cafccabec6b03d1a46d69da4c2376e4445 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 26 Oct 2017 17:14:29 +0100 Subject: [PATCH 05/20] doc: Include collector config in the skip doc None of the decorators are sufficient to skip an entire file, for example if the file contain invalid code for a given Python version. Simply link to details about customizing the collector. Signed-off-by: Stephen Finucane --- doc/en/example/pythoncollection.rst | 30 +++++++++++++++-------------- doc/en/skipping.rst | 12 +++++++++++- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/doc/en/example/pythoncollection.rst b/doc/en/example/pythoncollection.rst index 8d36c2e37..5fb63035a 100644 --- a/doc/en/example/pythoncollection.rst +++ b/doc/en/example/pythoncollection.rst @@ -175,21 +175,23 @@ You can always peek at the collection tree without running tests like this:: ======= no tests ran in 0.12 seconds ======== -customizing test collection to find all .py files ---------------------------------------------------------- +.. _customizing-test-collection: + +Customizing test collection +--------------------------- .. regendoc:wipe -You can easily instruct ``pytest`` to discover tests from every python file:: - +You can easily instruct ``pytest`` to discover tests from every Python file:: # content of pytest.ini [pytest] python_files = *.py -However, many projects will have a ``setup.py`` which they don't want to be imported. Moreover, there may files only importable by a specific python version. -For such cases you can dynamically define files to be ignored by listing -them in a ``conftest.py`` file:: +However, many projects will have a ``setup.py`` which they don't want to be +imported. Moreover, there may files only importable by a specific python +version. For such cases you can dynamically define files to be ignored by +listing them in a ``conftest.py`` file:: # content of conftest.py import sys @@ -198,7 +200,7 @@ them in a ``conftest.py`` file:: if sys.version_info[0] > 2: collect_ignore.append("pkg/module_py2.py") -And then if you have a module file like this:: +and then if you have a module file like this:: # content of pkg/module_py2.py def test_only_on_python2(): @@ -207,13 +209,13 @@ And then if you have a module file like this:: except Exception, e: pass -and a setup.py dummy file like this:: +and a ``setup.py`` dummy file like this:: # content of setup.py 0/0 # will raise exception if imported -then a pytest run on Python2 will find the one test and will leave out the -setup.py file:: +If you run with a Python 2 interpreter then you will find the one test and will +leave out the ``setup.py`` file:: #$ pytest --collect-only ====== test session starts ====== @@ -225,13 +227,13 @@ setup.py file:: ====== no tests ran in 0.04 seconds ====== -If you run with a Python3 interpreter both the one test and the setup.py file -will be left out:: +If you run with a Python 3 interpreter both the one test and the ``setup.py`` +file will be left out:: $ pytest --collect-only ======= test session starts ======== platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini collected 0 items - + ======= no tests ran in 0.12 seconds ======== diff --git a/doc/en/skipping.rst b/doc/en/skipping.rst index f8cfb73ca..d6d1e2414 100644 --- a/doc/en/skipping.rst +++ b/doc/en/skipping.rst @@ -3,7 +3,7 @@ .. _skipping: Skip and xfail: dealing with tests that cannot succeed -===================================================================== +====================================================== You can mark test functions that cannot be run on certain platforms or that you expect to fail so pytest can deal with them accordingly and @@ -142,6 +142,16 @@ will be skipped if any of the skip conditions is true. .. _`whole class- or module level`: mark.html#scoped-marking +Skipping files or directories +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sometimes you may need to skip an entire file or directory, for example if the +tests rely on Python version-specific features or contain code that you do not +wish pytest to run. In this case, you must exclude the files and directories +from collection. Refer to :ref:`customizing-test-collection` for more +information. + + Skipping on a missing import dependency ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 27bb2eceb43f9c2c3747cf3c0a2e999292d382fc Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 26 Oct 2017 20:15:05 -0200 Subject: [PATCH 06/20] Add comment about why we remove docstrings on test_assertrewrite As explained in pytest-dev/pytest#2870 --- testing/test_assertrewrite.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index 45c0c7b16..02270e157 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -65,6 +65,9 @@ class TestAssertionRewrite(object): def test_place_initial_imports(self): s = """'Doc string'\nother = stuff""" m = rewrite(s) + # Module docstrings in 3.7 are part of Module node, it's not in the body + # so we remove it so the following body items have the same indexes on + # all Python versions if sys.version_info < (3, 7): assert isinstance(m.body[0], ast.Expr) assert isinstance(m.body[0].value, ast.Str) From c3ba9225ef5f04371fc7da222b50c55e274c42a5 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 26 Oct 2017 21:33:36 -0200 Subject: [PATCH 07/20] Change directory for py27 xdist-related envs The "filter_traceback" function was not filtering the frames that belonged to the pytest internals. "filter_traceback" was receiving *relative* paths when running with xdist, and full paths in non-distributed runs; for this reason the traceback function did not consider the received path to be relative to the pytest internal modules. Fix #2843 --- tox.ini | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 33e5fa02c..e9c1dfa96 100644 --- a/tox.ini +++ b/tox.ini @@ -64,8 +64,9 @@ deps = mock nose hypothesis>=3.5.2 +changedir=testing commands = - pytest -n1 -rfsxX {posargs:testing} + pytest -n1 -rfsxX {posargs:.} [testenv:py36-xdist] deps = {[testenv:py27-xdist]deps} @@ -91,10 +92,11 @@ deps = pytest-xdist>=1.13 hypothesis>=3.5.2 distribute = true +changedir=testing setenv = PYTHONDONTWRITEBYTECODE=1 commands = - pytest -n3 -rfsxX {posargs:testing} + pytest -n3 -rfsxX {posargs:.} [testenv:py27-trial] deps = twisted From 27cea340f34dd4fd7f225895656a89f5468f7b1f Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 26 Oct 2017 21:55:28 -0200 Subject: [PATCH 08/20] Remove trailing whitespace --- testing/test_assertrewrite.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index 02270e157..78a5f2bae 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -66,7 +66,7 @@ class TestAssertionRewrite(object): s = """'Doc string'\nother = stuff""" m = rewrite(s) # Module docstrings in 3.7 are part of Module node, it's not in the body - # so we remove it so the following body items have the same indexes on + # so we remove it so the following body items have the same indexes on # all Python versions if sys.version_info < (3, 7): assert isinstance(m.body[0], ast.Expr) From af5e9238c895e51b583a6a8b4517355ce0dd7b85 Mon Sep 17 00:00:00 2001 From: Daw-Ran Liou Date: Sat, 28 Oct 2017 14:14:37 -0700 Subject: [PATCH 09/20] Document pytest.param Append example for pytest.param in the example/parametrize document. --- AUTHORS | 1 + changelog/2658.doc | 1 + doc/en/example/parametrize.rst | 50 ++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 changelog/2658.doc diff --git a/AUTHORS b/AUTHORS index 6e341d64e..204e5150e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -46,6 +46,7 @@ Dave Hunt David Díaz-Barquero David Mohr David Vierra +Daw-Ran Liou Denis Kirisov Diego Russo Dmitry Dygalo diff --git a/changelog/2658.doc b/changelog/2658.doc new file mode 100644 index 000000000..2da7f3d6c --- /dev/null +++ b/changelog/2658.doc @@ -0,0 +1 @@ +Append example for pytest.param in the example/parametrize document. \ No newline at end of file diff --git a/doc/en/example/parametrize.rst b/doc/en/example/parametrize.rst index ffeb5a951..1a8de235a 100644 --- a/doc/en/example/parametrize.rst +++ b/doc/en/example/parametrize.rst @@ -485,4 +485,54 @@ of our ``test_func1`` was skipped. A few notes: values as well. +Set marks or test ID for individual parametrized test +-------------------------------------------------------------------- +Use ``pytest.param`` to apply marks or set test ID to individual parametrized test. +For example:: + + # content of test_pytest_param_example.py + import pytest + @pytest.mark.parametrize('test_input,expected', [ + ('3+5', 8), + pytest.param('1+7', 8, + marks=pytest.mark.basic), + pytest.param('2+4', 6, + marks=pytest.mark.basic, + id='basic_2+4'), + pytest.param('6*9', 42, + marks=[pytest.mark.basic, pytest.mark.xfail], + id='basic_6*9'), + ]) + def test_eval(test_input, expected): + assert eval(test_input) == expected + +In this example, we have 4 parametrized tests. Except for the first test, +we mark the rest three parametrized tests with the custom marker ``basic``, +and for the fourth test we also use the built-in mark ``xfail`` to indicate this +test is expected to fail. For explicitness, we set test ids for some tests. + +Then run ``pytest`` with verbose mode and with only the ``basic`` marker:: + + pytest -v -m basic + ============================================ test session starts ============================================= + platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y + rootdir: $REGENDOC_TMPDIR, inifile: + collected 4 items + + test_pytest_param_example.py::test_eval[1+7-8] PASSED + test_pytest_param_example.py::test_eval[basic_2+4] PASSED + test_pytest_param_example.py::test_eval[basic_6*9] xfail + ========================================== short test summary info =========================================== + XFAIL test_pytest_param_example.py::test_eval[basic_6*9] + + ============================================= 1 tests deselected ============================================= + +As the result: + +- Four tests were collected +- One test was deselected because it doesn't have the ``basic`` mark. +- Three tests with the ``basic`` mark was selected. +- The test ``test_eval[1+7-8]`` passed, but the name is autogenerated and confusing. +- The test ``test_eval[basic_2+4]`` passed. +- The test ``test_eval[basic_6*9]`` was expected to fail and did fail. From 2f993af54a1401460cc0f70915f28251f007344d Mon Sep 17 00:00:00 2001 From: Thomas Hisch Date: Sun, 29 Oct 2017 19:37:01 +0000 Subject: [PATCH 10/20] Fix context output handling for doctests Show full context of doctest source in the pytest output, if the lineno of failed example in the docstring is < 9. --- _pytest/doctest.py | 2 +- changelog/2882.bugfix | 1 + testing/test_doctest.py | 30 ++++++++++++++++++++++++++++-- 3 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 changelog/2882.bugfix diff --git a/_pytest/doctest.py b/_pytest/doctest.py index cc505c8d0..4c05acddf 100644 --- a/_pytest/doctest.py +++ b/_pytest/doctest.py @@ -120,7 +120,7 @@ class DoctestItem(pytest.Item): lines = ["%03d %s" % (i + test.lineno + 1, x) for (i, x) in enumerate(lines)] # trim docstring error lines to 10 - lines = lines[example.lineno - 9:example.lineno + 1] + lines = lines[max(example.lineno - 9, 0):example.lineno + 1] else: lines = ['EXAMPLE LOCATION UNKNOWN, not showing all tests of that example'] indent = '>>>' diff --git a/changelog/2882.bugfix b/changelog/2882.bugfix new file mode 100644 index 000000000..2bda24c01 --- /dev/null +++ b/changelog/2882.bugfix @@ -0,0 +1 @@ +Show full context of doctest source in the pytest output, if the lineno of failed example in the docstring is < 9. \ No newline at end of file diff --git a/testing/test_doctest.py b/testing/test_doctest.py index 8a81ea0ed..6616d2eae 100644 --- a/testing/test_doctest.py +++ b/testing/test_doctest.py @@ -173,7 +173,7 @@ class TestDoctests(object): "*UNEXPECTED*ZeroDivision*", ]) - def test_docstring_context_around_error(self, testdir): + def test_docstring_partial_context_around_error(self, testdir): """Test that we show some context before the actual line of a failing doctest. """ @@ -199,7 +199,7 @@ class TestDoctests(object): ''') result = testdir.runpytest('--doctest-modules') result.stdout.fnmatch_lines([ - '*docstring_context_around_error*', + '*docstring_partial_context_around_error*', '005*text-line-3', '006*text-line-4', '013*text-line-11', @@ -213,6 +213,32 @@ class TestDoctests(object): assert 'text-line-2' not in result.stdout.str() assert 'text-line-after' not in result.stdout.str() + def test_docstring_full_context_around_error(self, testdir): + """Test that we show the whole context before the actual line of a failing + doctest, provided that the context is up to 10 lines long. + """ + testdir.makepyfile(''' + def foo(): + """ + text-line-1 + text-line-2 + + >>> 1 + 1 + 3 + """ + ''') + result = testdir.runpytest('--doctest-modules') + result.stdout.fnmatch_lines([ + '*docstring_full_context_around_error*', + '003*text-line-1', + '004*text-line-2', + '006*>>> 1 + 1', + 'Expected:', + ' 3', + 'Got:', + ' 2', + ]) + def test_doctest_linedata_missing(self, testdir): testdir.tmpdir.join('hello.py').write(_pytest._code.Source(""" class Fun(object): From 802585cb669a669cb6dd9ac9ed7ec4557fd727fd Mon Sep 17 00:00:00 2001 From: Franck Michea Date: Fri, 3 Nov 2017 22:13:47 +0100 Subject: [PATCH 11/20] Clarify language of proposal for parametrized fixtures This change slightly modifies the language of the proposal document around use of fixture as parameters of pytest.mark.parametrize. When looking for documentation around this, I very quickly scrolled through this document and landed on the last paragraph thinking it was documenting a real function. This change attempts to make it less likely for this to happen. --- doc/en/proposals/parametrize_with_fixtures.rst | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/doc/en/proposals/parametrize_with_fixtures.rst b/doc/en/proposals/parametrize_with_fixtures.rst index 381bc98f1..4cff28dd8 100644 --- a/doc/en/proposals/parametrize_with_fixtures.rst +++ b/doc/en/proposals/parametrize_with_fixtures.rst @@ -1,8 +1,13 @@ :orphan: -========================= -Parametrize with fixtures -========================= +=================================== +PROPOSAL: Parametrize with fixtures +=================================== + +.. warning:: + + This document outlines a proposal around using fixtures as input + of parametrized tests or fixtures. Problem ------- @@ -108,8 +113,8 @@ the following values. Alternative approach -------------------- -A new helper function named ``fixture_request`` tells pytest to yield all -parameters of a fixture. +A new helper function named ``fixture_request`` would tell pytest to yield +all parameters marked as a fixture. .. code-block:: python From 22e9b006daac4e4a124184387c15b4bd989758ab Mon Sep 17 00:00:00 2001 From: Franck Michea Date: Fri, 3 Nov 2017 22:24:05 +0100 Subject: [PATCH 12/20] Add fragment per PR's guidelines. --- changelog/2893.doc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/2893.doc diff --git a/changelog/2893.doc b/changelog/2893.doc new file mode 100644 index 000000000..a305f1890 --- /dev/null +++ b/changelog/2893.doc @@ -0,0 +1 @@ +Clarify language of proposal for fixtures parameters From 03829fde8afde32c7ee4ff0d01b728b405e24b5d Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 4 Nov 2017 13:17:20 -0200 Subject: [PATCH 13/20] Fix linting E741: ambiguous variable name --- _pytest/_code/code.py | 8 +- _pytest/_code/source.py | 16 +- _pytest/assertion/util.py | 8 +- _pytest/config.py | 12 +- _pytest/fixtures.py | 8 +- _pytest/mark.py | 4 +- _pytest/pytester.py | 28 +- _pytest/python.py | 14 +- _pytest/skipping.py | 6 +- _pytest/terminal.py | 24 +- _pytest/unittest.py | 8 +- testing/code/test_excinfo.py | 4 +- testing/code/test_source.py | 8 +- testing/code/test_source_multiline_block.py | 4 +- testing/python/collect.py | 8 +- testing/python/fixture.py | 402 ++++++++++---------- testing/python/integration.py | 8 +- testing/python/metafunc.py | 6 +- testing/test_assertion.py | 12 +- testing/test_assertrewrite.py | 4 +- testing/test_collection.py | 6 +- testing/test_config.py | 70 ++-- testing/test_conftest.py | 28 +- testing/test_mark.py | 28 +- testing/test_nose.py | 70 ++-- testing/test_pluginmanager.py | 36 +- testing/test_recwarn.py | 4 +- testing/test_runner.py | 8 +- testing/test_runner_xunit.py | 8 +- testing/test_session.py | 28 +- testing/test_skipping.py | 6 +- testing/test_terminal.py | 8 +- testing/test_unittest.py | 22 +- tox.ini | 2 - 34 files changed, 457 insertions(+), 459 deletions(-) diff --git a/_pytest/_code/code.py b/_pytest/_code/code.py index cf10fb6bc..34655abeb 100644 --- a/_pytest/_code/code.py +++ b/_pytest/_code/code.py @@ -338,16 +338,16 @@ class Traceback(list): # XXX needs a test key = entry.frame.code.path, id(entry.frame.code.raw), entry.lineno # print "checking for recursion at", key - l = cache.setdefault(key, []) - if l: + values = cache.setdefault(key, []) + if values: f = entry.frame loc = f.f_locals - for otherloc in l: + for otherloc in values: if f.is_true(f.eval(co_equal, __recursioncache_locals_1=loc, __recursioncache_locals_2=otherloc)): return i - l.append(entry.frame.f_locals) + values.append(entry.frame.f_locals) return None diff --git a/_pytest/_code/source.py b/_pytest/_code/source.py index e21fecb1e..96c88451b 100644 --- a/_pytest/_code/source.py +++ b/_pytest/_code/source.py @@ -319,22 +319,22 @@ def get_statement_startend2(lineno, node): import ast # flatten all statements and except handlers into one lineno-list # AST's line numbers start indexing at 1 - l = [] + values = [] for x in ast.walk(node): if isinstance(x, _ast.stmt) or isinstance(x, _ast.ExceptHandler): - l.append(x.lineno - 1) + values.append(x.lineno - 1) for name in "finalbody", "orelse": val = getattr(x, name, None) if val: # treat the finally/orelse part as its own statement - l.append(val[0].lineno - 1 - 1) - l.sort() - insert_index = bisect_right(l, lineno) - start = l[insert_index - 1] - if insert_index >= len(l): + values.append(val[0].lineno - 1 - 1) + values.sort() + insert_index = bisect_right(values, lineno) + start = values[insert_index - 1] + if insert_index >= len(values): end = None else: - end = l[insert_index] + end = values[insert_index] return start, end diff --git a/_pytest/assertion/util.py b/_pytest/assertion/util.py index 41e66448d..9f0092907 100644 --- a/_pytest/assertion/util.py +++ b/_pytest/assertion/util.py @@ -53,11 +53,11 @@ def _split_explanation(explanation): """ raw_lines = (explanation or u('')).split('\n') lines = [raw_lines[0]] - for l in raw_lines[1:]: - if l and l[0] in ['{', '}', '~', '>']: - lines.append(l) + for values in raw_lines[1:]: + if values and values[0] in ['{', '}', '~', '>']: + lines.append(values) else: - lines[-1] += '\\n' + l + lines[-1] += '\\n' + values return lines diff --git a/_pytest/config.py b/_pytest/config.py index 364ac13c6..19835d2c3 100644 --- a/_pytest/config.py +++ b/_pytest/config.py @@ -1170,10 +1170,10 @@ class Config(object): return [] if type == "pathlist": dp = py.path.local(self.inicfg.config.path).dirpath() - l = [] + values = [] for relpath in shlex.split(value): - l.append(dp.join(relpath, abs=True)) - return l + values.append(dp.join(relpath, abs=True)) + return values elif type == "args": return shlex.split(value) elif type == "linelist": @@ -1190,13 +1190,13 @@ class Config(object): except KeyError: return None modpath = py.path.local(mod.__file__).dirpath() - l = [] + values = [] for relroot in relroots: if not isinstance(relroot, py.path.local): relroot = relroot.replace("/", py.path.local.sep) relroot = modpath.join(relroot, abs=True) - l.append(relroot) - return l + values.append(relroot) + return values def _get_override_ini_value(self, name): value = None diff --git a/_pytest/fixtures.py b/_pytest/fixtures.py index f71f35768..6c9f251f8 100644 --- a/_pytest/fixtures.py +++ b/_pytest/fixtures.py @@ -460,13 +460,13 @@ class FixtureRequest(FuncargnamesCompatAttr): def _get_fixturestack(self): current = self - l = [] + values = [] while 1: fixturedef = getattr(current, "_fixturedef", None) if fixturedef is None: - l.reverse() - return l - l.append(fixturedef) + values.reverse() + return values + values.append(fixturedef) current = current._parent_request def _getfixturevalue(self, fixturedef): diff --git a/_pytest/mark.py b/_pytest/mark.py index 2a4a0f265..454722ca2 100644 --- a/_pytest/mark.py +++ b/_pytest/mark.py @@ -270,12 +270,12 @@ class MarkGenerator: return except AttributeError: pass - self._markers = l = set() + self._markers = values = set() for line in self._config.getini("markers"): marker, _ = line.split(":", 1) marker = marker.rstrip() x = marker.split("(", 1)[0] - l.add(x) + values.add(x) if name not in self._markers: raise AttributeError("%r not a registered marker" % (name,)) diff --git a/_pytest/pytester.py b/_pytest/pytester.py index 263f29e88..82aa00e0d 100644 --- a/_pytest/pytester.py +++ b/_pytest/pytester.py @@ -182,9 +182,9 @@ class PytestArg: return hookrecorder -def get_public_names(l): - """Only return names from iterator l without a leading underscore.""" - return [x for x in l if x[0] != "_"] +def get_public_names(values): + """Only return names from iterator values without a leading underscore.""" + return [x for x in values if x[0] != "_"] class ParsedCall: @@ -258,9 +258,9 @@ class HookRecorder: pytest.fail("\n".join(lines)) def getcall(self, name): - l = self.getcalls(name) - assert len(l) == 1, (name, l) - return l[0] + values = self.getcalls(name) + assert len(values) == 1, (name, values) + return values[0] # functionality for test reports @@ -271,7 +271,7 @@ class HookRecorder: def matchreport(self, inamepart="", names="pytest_runtest_logreport pytest_collectreport", when=None): """ return a testreport whose dotted import path matches """ - l = [] + values = [] for rep in self.getreports(names=names): try: if not when and rep.when != "call" and rep.passed: @@ -282,14 +282,14 @@ class HookRecorder: if when and getattr(rep, 'when', None) != when: continue if not inamepart or inamepart in rep.nodeid.split("::"): - l.append(rep) - if not l: + values.append(rep) + if not values: raise ValueError("could not find test report matching %r: " "no test reports at all!" % (inamepart,)) - if len(l) > 1: + if len(values) > 1: raise ValueError( - "found 2 or more testreports matching %r: %s" % (inamepart, l)) - return l[0] + "found 2 or more testreports matching %r: %s" % (inamepart, values)) + return values[0] def getfailures(self, names='pytest_runtest_logreport pytest_collectreport'): @@ -673,8 +673,8 @@ class Testdir: """ p = self.makepyfile(source) - l = list(cmdlineargs) + [p] - return self.inline_run(*l) + values = list(cmdlineargs) + [p] + return self.inline_run(*values) def inline_genitems(self, *args): """Run ``pytest.main(['--collectonly'])`` in-process. diff --git a/_pytest/python.py b/_pytest/python.py index 6c130f93e..41fd2bdb7 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -321,7 +321,7 @@ class PyCollector(PyobjMixin, main.Collector): for basecls in inspect.getmro(self.obj.__class__): dicts.append(basecls.__dict__) seen = {} - l = [] + values = [] for dic in dicts: for name, obj in list(dic.items()): if name in seen: @@ -332,9 +332,9 @@ class PyCollector(PyobjMixin, main.Collector): continue if not isinstance(res, list): res = [res] - l.extend(res) - l.sort(key=lambda item: item.reportinfo()[:2]) - return l + values.extend(res) + values.sort(key=lambda item: item.reportinfo()[:2]) + return values def makeitem(self, name, obj): # assert self.ihook.fspath == self.fspath, self @@ -592,7 +592,7 @@ class Generator(FunctionMixin, PyCollector): self.session._setupstate.prepare(self) # see FunctionMixin.setup and test_setupstate_is_preserved_134 self._preservedparent = self.parent.obj - l = [] + values = [] seen = {} for i, x in enumerate(self.obj()): name, call, args = self.getcallargs(x) @@ -605,9 +605,9 @@ class Generator(FunctionMixin, PyCollector): if name in seen: raise ValueError("%r generated tests with non-unique name %r" % (self, name)) seen[name] = True - l.append(self.Function(name, self, args=args, callobj=call)) + values.append(self.Function(name, self, args=args, callobj=call)) self.warn('C1', deprecated.YIELD_TESTS) - return l + return values def getcallargs(self, obj): if not isinstance(obj, (tuple, list)): diff --git a/_pytest/skipping.py b/_pytest/skipping.py index 2fd61448a..b92800d10 100644 --- a/_pytest/skipping.py +++ b/_pytest/skipping.py @@ -346,10 +346,10 @@ def folded_skips(skipped): key = event.longrepr assert len(key) == 3, (event, key) d.setdefault(key, []).append(event) - l = [] + values = [] for key, events in d.items(): - l.append((len(events),) + key) - return l + values.append((len(events),) + key) + return values def show_skipped(terminalreporter, lines): diff --git a/_pytest/terminal.py b/_pytest/terminal.py index f56b966f3..9da94d0c9 100644 --- a/_pytest/terminal.py +++ b/_pytest/terminal.py @@ -445,9 +445,9 @@ class TerminalReporter: line = self.config.cwd_relative_nodeid(nodeid) if domain and line.endswith(domain): line = line[:-len(domain)] - l = domain.split("[") - l[0] = l[0].replace('.', '::') # don't replace '.' in params - line += "[".join(l) + values = domain.split("[") + values[0] = values[0].replace('.', '::') # don't replace '.' in params + line += "[".join(values) return line # collect_fspath comes from testid which has a "/"-normalized path @@ -479,11 +479,11 @@ class TerminalReporter: # summaries for sessionfinish # def getreports(self, name): - l = [] + values = [] for x in self.stats.get(name, []): if not hasattr(x, '_pdbshown'): - l.append(x) - return l + values.append(x) + return values def summary_warnings(self): if self.hasopt("w"): @@ -594,8 +594,8 @@ def repr_pythonversion(v=None): return str(v) -def flatten(l): - for x in l: +def flatten(values): + for x in values: if isinstance(x, (list, tuple)): for y in flatten(x): yield y @@ -636,7 +636,7 @@ def build_summary_stats_line(stats): def _plugin_nameversions(plugininfo): - l = [] + values = [] for plugin, dist in plugininfo: # gets us name and version! name = '{dist.project_name}-{dist.version}'.format(dist=dist) @@ -645,6 +645,6 @@ def _plugin_nameversions(plugininfo): name = name[7:] # we decided to print python package names # they can have more than one plugin - if name not in l: - l.append(name) - return l + if name not in values: + values.append(name) + return values diff --git a/_pytest/unittest.py b/_pytest/unittest.py index 585f81472..939e45206 100644 --- a/_pytest/unittest.py +++ b/_pytest/unittest.py @@ -109,10 +109,10 @@ class TestCaseFunction(Function): except TypeError: try: try: - l = traceback.format_exception(*rawexcinfo) - l.insert(0, "NOTE: Incompatible Exception Representation, " - "displaying natively:\n\n") - fail("".join(l), pytrace=False) + values = traceback.format_exception(*rawexcinfo) + values.insert(0, "NOTE: Incompatible Exception Representation, " + "displaying natively:\n\n") + fail("".join(values), pytrace=False) except (fail.Exception, KeyboardInterrupt): raise except: diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py index f8f8a0365..35ab1cfcc 100644 --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -77,8 +77,8 @@ def test_excinfo_getstatement(): linenumbers = [_pytest._code.getrawcode(f).co_firstlineno - 1 + 4, _pytest._code.getrawcode(f).co_firstlineno - 1 + 1, _pytest._code.getrawcode(g).co_firstlineno - 1 + 1, ] - l = list(excinfo.traceback) - foundlinenumbers = [x.lineno for x in l] + values = list(excinfo.traceback) + foundlinenumbers = [x.lineno for x in values] assert foundlinenumbers == linenumbers # for x in info: # print "%s:%d %s" %(x.path.relto(root), x.lineno, x.statement) diff --git a/testing/code/test_source.py b/testing/code/test_source.py index 1d315aa9b..4f3796cb4 100644 --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -155,8 +155,8 @@ class TestAccesses(object): assert len(self.source) == 4 def test_iter(self): - l = [x for x in self.source] - assert len(l) == 4 + values = [x for x in self.source] + assert len(values) == 4 class TestSourceParsingAndCompiling(object): @@ -331,8 +331,8 @@ def test_getstartingblock_singleline(): x = A('x', 'y') - l = [i for i in x.source.lines if i.strip()] - assert len(l) == 1 + values = [i for i in x.source.lines if i.strip()] + assert len(values) == 1 def test_getline_finally(): diff --git a/testing/code/test_source_multiline_block.py b/testing/code/test_source_multiline_block.py index 4e8735d0c..b356d191f 100644 --- a/testing/code/test_source_multiline_block.py +++ b/testing/code/test_source_multiline_block.py @@ -22,5 +22,5 @@ def test_getstartingblock_multiline(): , 'z') - l = [i for i in x.source.lines if i.strip()] - assert len(l) == 4 + values = [i for i in x.source.lines if i.strip()] + assert len(values) == 4 diff --git a/testing/python/collect.py b/testing/python/collect.py index b24c0b2fd..7b361a89e 100644 --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -873,11 +873,11 @@ class TestConftestCustomization(object): def test_makeitem_non_underscore(self, testdir, monkeypatch): modcol = testdir.getmodulecol("def _hello(): pass") - l = [] + values = [] monkeypatch.setattr(pytest.Module, 'makeitem', - lambda self, name, obj: l.append(name)) - l = modcol.collect() - assert '_hello' not in l + lambda self, name, obj: values.append(name)) + values = modcol.collect() + assert '_hello' not in values def test_issue2369_collect_module_fileext(self, testdir): """Ensure we can collect files with weird file extensions as Python diff --git a/testing/python/fixture.py b/testing/python/fixture.py index 06b08d68e..ac385c995 100644 --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -548,12 +548,12 @@ class TestRequestBasic(object): def test_getfixturevalue(self, testdir, getfixmethod): item = testdir.getitem(""" import pytest - l = [2] + values = [2] @pytest.fixture def something(request): return 1 @pytest.fixture def other(request): - return l.pop() + return values.pop() def test_func(something): pass """) import contextlib @@ -622,15 +622,15 @@ class TestRequestBasic(object): def test_request_addfinalizer_failing_setup(self, testdir): testdir.makepyfile(""" import pytest - l = [1] + values = [1] @pytest.fixture def myfix(request): - request.addfinalizer(l.pop) + request.addfinalizer(values.pop) assert 0 def test_fix(myfix): pass def test_finalizer_ran(): - assert not l + assert not values """) reprec = testdir.inline_run("-s") reprec.assertoutcome(failed=1, passed=1) @@ -638,30 +638,30 @@ class TestRequestBasic(object): def test_request_addfinalizer_failing_setup_module(self, testdir): testdir.makepyfile(""" import pytest - l = [1, 2] + values = [1, 2] @pytest.fixture(scope="module") def myfix(request): - request.addfinalizer(l.pop) - request.addfinalizer(l.pop) + request.addfinalizer(values.pop) + request.addfinalizer(values.pop) assert 0 def test_fix(myfix): pass """) reprec = testdir.inline_run("-s") mod = reprec.getcalls("pytest_runtest_setup")[0].item.module - assert not mod.l + assert not mod.values def test_request_addfinalizer_partial_setup_failure(self, testdir): p = testdir.makepyfile(""" import pytest - l = [] + values = [] @pytest.fixture def something(request): - request.addfinalizer(lambda: l.append(None)) + request.addfinalizer(lambda: values.append(None)) def test_func(something, missingarg): pass def test_second(): - assert len(l) == 1 + assert len(values) == 1 """) result = testdir.runpytest(p) result.stdout.fnmatch_lines([ @@ -675,7 +675,7 @@ class TestRequestBasic(object): """ testdir.makepyfile(""" import pytest - l = [] + values = [] def _excepts(where): raise Exception('Error in %s fixture' % where) @pytest.fixture @@ -683,17 +683,17 @@ class TestRequestBasic(object): return request @pytest.fixture def something(subrequest): - subrequest.addfinalizer(lambda: l.append(1)) - subrequest.addfinalizer(lambda: l.append(2)) + subrequest.addfinalizer(lambda: values.append(1)) + subrequest.addfinalizer(lambda: values.append(2)) subrequest.addfinalizer(lambda: _excepts('something')) @pytest.fixture def excepts(subrequest): subrequest.addfinalizer(lambda: _excepts('excepts')) - subrequest.addfinalizer(lambda: l.append(3)) + subrequest.addfinalizer(lambda: values.append(3)) def test_first(something, excepts): pass def test_second(): - assert l == [3, 2, 1] + assert values == [3, 2, 1] """) result = testdir.runpytest() result.stdout.fnmatch_lines([ @@ -748,13 +748,13 @@ class TestRequestBasic(object): def test_setupdecorator_and_xunit(self, testdir): testdir.makepyfile(""" import pytest - l = [] + values = [] @pytest.fixture(scope='module', autouse=True) def setup_module(): - l.append("module") + values.append("module") @pytest.fixture(autouse=True) def setup_function(): - l.append("function") + values.append("function") def test_func(): pass @@ -762,14 +762,14 @@ class TestRequestBasic(object): class TestClass(object): @pytest.fixture(scope="class", autouse=True) def setup_class(self): - l.append("class") + values.append("class") @pytest.fixture(autouse=True) def setup_method(self): - l.append("method") + values.append("method") def test_method(self): pass def test_all(): - assert l == ["module", "function", "class", + assert values == ["module", "function", "class", "function", "method", "function"] """) reprec = testdir.inline_run("-v") @@ -930,10 +930,10 @@ class TestRequestCachedSetup(object): def test_request_cachedsetup_extrakey(self, testdir): item1 = testdir.getitem("def test_func(): pass") req1 = fixtures.FixtureRequest(item1) - l = ["hello", "world"] + values = ["hello", "world"] def setup(): - return l.pop() + return values.pop() ret1 = req1.cached_setup(setup, extrakey=1) ret2 = req1.cached_setup(setup, extrakey=2) @@ -947,24 +947,24 @@ class TestRequestCachedSetup(object): def test_request_cachedsetup_cache_deletion(self, testdir): item1 = testdir.getitem("def test_func(): pass") req1 = fixtures.FixtureRequest(item1) - l = [] + values = [] def setup(): - l.append("setup") + values.append("setup") def teardown(val): - l.append("teardown") + values.append("teardown") req1.cached_setup(setup, teardown, scope="function") - assert l == ['setup'] + assert values == ['setup'] # artificial call of finalizer setupstate = req1._pyfuncitem.session._setupstate setupstate._callfinalizers(item1) - assert l == ["setup", "teardown"] + assert values == ["setup", "teardown"] req1.cached_setup(setup, teardown, scope="function") - assert l == ["setup", "teardown", "setup"] + assert values == ["setup", "teardown", "setup"] setupstate._callfinalizers(item1) - assert l == ["setup", "teardown", "setup", "teardown"] + assert values == ["setup", "teardown", "setup", "teardown"] def test_request_cached_setup_two_args(self, testdir): testdir.makepyfile(""" @@ -1006,17 +1006,17 @@ class TestRequestCachedSetup(object): def test_request_cached_setup_functional(self, testdir): testdir.makepyfile(test_0=""" import pytest - l = [] + values = [] @pytest.fixture def something(request): val = request.cached_setup(fsetup, fteardown) return val def fsetup(mycache=[1]): - l.append(mycache.pop()) - return l + values.append(mycache.pop()) + return values def fteardown(something): - l.remove(something[0]) - l.append(2) + values.remove(something[0]) + values.append(2) def test_list_once(something): assert something == [1] def test_list_twice(something): @@ -1025,7 +1025,7 @@ class TestRequestCachedSetup(object): testdir.makepyfile(test_1=""" import test_0 # should have run already def test_check_test0_has_teardown_correct(): - assert test_0.l == [2] + assert test_0.values == [2] """) result = testdir.runpytest("-v") result.stdout.fnmatch_lines([ @@ -1150,10 +1150,10 @@ class TestFixtureUsages(object): def test_funcarg_parametrized_and_used_twice(self, testdir): testdir.makepyfile(""" import pytest - l = [] + values = [] @pytest.fixture(params=[1,2]) def arg1(request): - l.append(1) + values.append(1) return request.param @pytest.fixture() @@ -1162,7 +1162,7 @@ class TestFixtureUsages(object): def test_add(arg1, arg2): assert arg2 == arg1 + 1 - assert len(l) == arg1 + assert len(values) == arg1 """) result = testdir.runpytest() result.stdout.fnmatch_lines([ @@ -1203,8 +1203,8 @@ class TestFixtureUsages(object): """) reprec = testdir.inline_run() - l = reprec.getfailedcollections() - assert len(l) == 1 + values = reprec.getfailedcollections() + assert len(values) == 1 def test_request_can_be_overridden(self, testdir): testdir.makepyfile(""" @@ -1223,20 +1223,20 @@ class TestFixtureUsages(object): testdir.makepyfile(""" import pytest - l = [] + values = [] @pytest.fixture(scope="class") def myfix(request): request.cls.hello = "world" - l.append(1) + values.append(1) class TestClass(object): def test_one(self): assert self.hello == "world" - assert len(l) == 1 + assert len(values) == 1 def test_two(self): assert self.hello == "world" - assert len(l) == 1 + assert len(values) == 1 pytest.mark.usefixtures("myfix")(TestClass) """) reprec = testdir.inline_run() @@ -1290,7 +1290,7 @@ class TestFixtureUsages(object): testdir.makepyfile(""" import pytest - l = [] + values = [] def f(): yield 1 yield 2 @@ -1304,14 +1304,14 @@ class TestFixtureUsages(object): return request.param def test_1(arg): - l.append(arg) + values.append(arg) def test_2(arg2): - l.append(arg2*10) + values.append(arg2*10) """) reprec = testdir.inline_run("-v") reprec.assertoutcome(passed=4) - l = reprec.getcalls("pytest_runtest_call")[0].item.module.l - assert l == [1, 2, 10, 20] + values = reprec.getcalls("pytest_runtest_call")[0].item.module.values + assert values == [1, 2, 10, 20] class TestFixtureManagerParseFactories(object): @@ -1461,19 +1461,19 @@ class TestAutouseDiscovery(object): testdir.makepyfile(""" import pytest class TestA(object): - l = [] + values = [] @pytest.fixture(autouse=True) def setup1(self): - self.l.append(1) + self.values.append(1) def test_setup1(self): - assert self.l == [1] + assert self.values == [1] class TestB(object): - l = [] + values = [] @pytest.fixture(autouse=True) def setup2(self): - self.l.append(1) + self.values.append(1) def test_setup2(self): - assert self.l == [1] + assert self.values == [1] """) reprec = testdir.inline_run() reprec.assertoutcome(passed=2) @@ -1556,22 +1556,22 @@ class TestAutouseDiscovery(object): def test_autouse_in_module_and_two_classes(self, testdir): testdir.makepyfile(""" import pytest - l = [] + values = [] @pytest.fixture(autouse=True) def append1(): - l.append("module") + values.append("module") def test_x(): - assert l == ["module"] + assert values == ["module"] class TestA(object): @pytest.fixture(autouse=True) def append2(self): - l.append("A") + values.append("A") def test_hello(self): - assert l == ["module", "module", "A"], l + assert values == ["module", "module", "A"], values class TestA2(object): def test_world(self): - assert l == ["module", "module", "A", "module"], l + assert values == ["module", "module", "A", "module"], values """) reprec = testdir.inline_run() reprec.assertoutcome(passed=3) @@ -1615,23 +1615,23 @@ class TestAutouseManagement(object): def test_funcarg_and_setup(self, testdir): testdir.makepyfile(""" import pytest - l = [] + values = [] @pytest.fixture(scope="module") def arg(): - l.append(1) + values.append(1) return 0 @pytest.fixture(scope="module", autouse=True) def something(arg): - l.append(2) + values.append(2) def test_hello(arg): - assert len(l) == 2 - assert l == [1,2] + assert len(values) == 2 + assert values == [1,2] assert arg == 0 def test_hello2(arg): - assert len(l) == 2 - assert l == [1,2] + assert len(values) == 2 + assert values == [1,2] assert arg == 0 """) reprec = testdir.inline_run() @@ -1640,20 +1640,20 @@ class TestAutouseManagement(object): def test_uses_parametrized_resource(self, testdir): testdir.makepyfile(""" import pytest - l = [] + values = [] @pytest.fixture(params=[1,2]) def arg(request): return request.param @pytest.fixture(autouse=True) def something(arg): - l.append(arg) + values.append(arg) def test_hello(): - if len(l) == 1: - assert l == [1] - elif len(l) == 2: - assert l == [1, 2] + if len(values) == 1: + assert values == [1] + elif len(values) == 2: + assert values == [1, 2] else: 0/0 @@ -1665,7 +1665,7 @@ class TestAutouseManagement(object): testdir.makepyfile(""" import pytest - l = [] + values = [] @pytest.fixture(scope="session", params=[1,2]) def arg(request): @@ -1674,14 +1674,14 @@ class TestAutouseManagement(object): @pytest.fixture(scope="function", autouse=True) def append(request, arg): if request.function.__name__ == "test_some": - l.append(arg) + values.append(arg) def test_some(): pass def test_result(arg): - assert len(l) == arg - assert l[:arg] == [1,2][:arg] + assert len(values) == arg + assert values[:arg] == [1,2][:arg] """) reprec = testdir.inline_run("-v", "-s") reprec.assertoutcome(passed=4) @@ -1691,7 +1691,7 @@ class TestAutouseManagement(object): import pytest import pprint - l = [] + values = [] @pytest.fixture(scope="function", params=[1,2]) def farg(request): @@ -1704,7 +1704,7 @@ class TestAutouseManagement(object): @pytest.fixture(scope="function", autouse=True) def append(request, farg, carg): def fin(): - l.append("fin_%s%s" % (carg, farg)) + values.append("fin_%s%s" % (carg, farg)) request.addfinalizer(fin) """) testdir.makepyfile(""" @@ -1721,26 +1721,26 @@ class TestAutouseManagement(object): reprec = testdir.inline_run("-v", "-s", confcut) reprec.assertoutcome(passed=8) config = reprec.getcalls("pytest_unconfigure")[0].config - l = config.pluginmanager._getconftestmodules(p)[0].l - assert l == ["fin_a1", "fin_a2", "fin_b1", "fin_b2"] * 2 + values = config.pluginmanager._getconftestmodules(p)[0].values + assert values == ["fin_a1", "fin_a2", "fin_b1", "fin_b2"] * 2 def test_scope_ordering(self, testdir): testdir.makepyfile(""" import pytest - l = [] + values = [] @pytest.fixture(scope="function", autouse=True) def fappend2(): - l.append(2) + values.append(2) @pytest.fixture(scope="class", autouse=True) def classappend3(): - l.append(3) + values.append(3) @pytest.fixture(scope="module", autouse=True) def mappend(): - l.append(1) + values.append(1) class TestHallo(object): def test_method(self): - assert l == [1,3,2] + assert values == [1,3,2] """) reprec = testdir.inline_run() reprec.assertoutcome(passed=1) @@ -1748,23 +1748,23 @@ class TestAutouseManagement(object): def test_parametrization_setup_teardown_ordering(self, testdir): testdir.makepyfile(""" import pytest - l = [] + values = [] def pytest_generate_tests(metafunc): if metafunc.cls is not None: metafunc.parametrize("item", [1,2], scope="class") class TestClass(object): @pytest.fixture(scope="class", autouse=True) def addteardown(self, item, request): - l.append("setup-%d" % item) - request.addfinalizer(lambda: l.append("teardown-%d" % item)) + values.append("setup-%d" % item) + request.addfinalizer(lambda: values.append("teardown-%d" % item)) def test_step1(self, item): - l.append("step1-%d" % item) + values.append("step1-%d" % item) def test_step2(self, item): - l.append("step2-%d" % item) + values.append("step2-%d" % item) def test_finish(): - print (l) - assert l == ["setup-1", "step1-1", "step2-1", "teardown-1", + print (values) + assert values == ["setup-1", "step1-1", "step2-1", "teardown-1", "setup-2", "step1-2", "step2-2", "teardown-2",] """) reprec = testdir.inline_run() @@ -1774,15 +1774,15 @@ class TestAutouseManagement(object): testdir.makepyfile(""" import pytest - l = [] + values = [] @pytest.fixture(autouse=True) def fix1(): - l.append(1) + values.append(1) @pytest.fixture() def arg1(): - l.append(2) + values.append(2) def test_hello(arg1): - assert l == [1,2] + assert values == [1,2] """) reprec = testdir.inline_run() reprec.assertoutcome(passed=1) @@ -1793,20 +1793,20 @@ class TestAutouseManagement(object): def test_ordering_dependencies_torndown_first(self, testdir, param1, param2): testdir.makepyfile(""" import pytest - l = [] + values = [] @pytest.fixture(%(param1)s) def arg1(request): - request.addfinalizer(lambda: l.append("fin1")) - l.append("new1") + request.addfinalizer(lambda: values.append("fin1")) + values.append("new1") @pytest.fixture(%(param2)s) def arg2(request, arg1): - request.addfinalizer(lambda: l.append("fin2")) - l.append("new2") + request.addfinalizer(lambda: values.append("fin2")) + values.append("new2") def test_arg(arg2): pass def test_check(): - assert l == ["new1", "new2", "fin2", "fin1"] + assert values == ["new1", "new2", "fin2", "fin1"] """ % locals()) reprec = testdir.inline_run("-s") reprec.assertoutcome(passed=2) @@ -1819,11 +1819,11 @@ class TestFixtureMarker(object): @pytest.fixture(params=["a", "b", "c"]) def arg(request): return request.param - l = [] + values = [] def test_param(arg): - l.append(arg) + values.append(arg) def test_result(): - assert l == list("abc") + assert values == list("abc") """) reprec = testdir.inline_run() reprec.assertoutcome(passed=4) @@ -1867,21 +1867,21 @@ class TestFixtureMarker(object): def test_scope_session(self, testdir): testdir.makepyfile(""" import pytest - l = [] + values = [] @pytest.fixture(scope="module") def arg(): - l.append(1) + values.append(1) return 1 def test_1(arg): assert arg == 1 def test_2(arg): assert arg == 1 - assert len(l) == 1 + assert len(values) == 1 class TestClass(object): def test3(self, arg): assert arg == 1 - assert len(l) == 1 + assert len(values) == 1 """) reprec = testdir.inline_run() reprec.assertoutcome(passed=3) @@ -1889,10 +1889,10 @@ class TestFixtureMarker(object): def test_scope_session_exc(self, testdir): testdir.makepyfile(""" import pytest - l = [] + values = [] @pytest.fixture(scope="session") def fix(): - l.append(1) + values.append(1) pytest.skip('skipping') def test_1(fix): @@ -1900,7 +1900,7 @@ class TestFixtureMarker(object): def test_2(fix): pass def test_last(): - assert l == [1] + assert values == [1] """) reprec = testdir.inline_run() reprec.assertoutcome(skipped=2, passed=1) @@ -1908,11 +1908,11 @@ class TestFixtureMarker(object): def test_scope_session_exc_two_fix(self, testdir): testdir.makepyfile(""" import pytest - l = [] + values = [] m = [] @pytest.fixture(scope="session") def a(): - l.append(1) + values.append(1) pytest.skip('skipping') @pytest.fixture(scope="session") def b(a): @@ -1923,7 +1923,7 @@ class TestFixtureMarker(object): def test_2(b): pass def test_last(): - assert l == [1] + assert values == [1] assert m == [] """) reprec = testdir.inline_run() @@ -1961,21 +1961,21 @@ class TestFixtureMarker(object): def test_scope_module_uses_session(self, testdir): testdir.makepyfile(""" import pytest - l = [] + values = [] @pytest.fixture(scope="module") def arg(): - l.append(1) + values.append(1) return 1 def test_1(arg): assert arg == 1 def test_2(arg): assert arg == 1 - assert len(l) == 1 + assert len(values) == 1 class TestClass(object): def test3(self, arg): assert arg == 1 - assert len(l) == 1 + assert len(values) == 1 """) reprec = testdir.inline_run() reprec.assertoutcome(passed=3) @@ -2070,17 +2070,17 @@ class TestFixtureMarker(object): @pytest.fixture(scope="module", params=["a", "b", "c"]) def arg(request): return request.param - l = [] + values = [] def test_param(arg): - l.append(arg) + values.append(arg) """) reprec = testdir.inline_run("-v") reprec.assertoutcome(passed=3) - l = reprec.getcalls("pytest_runtest_call")[0].item.module.l - assert len(l) == 3 - assert "a" in l - assert "b" in l - assert "c" in l + values = reprec.getcalls("pytest_runtest_call")[0].item.module.values + assert len(values) == 3 + assert "a" in values + assert "b" in values + assert "c" in values def test_scope_mismatch(self, testdir): testdir.makeconftest(""" @@ -2111,16 +2111,16 @@ class TestFixtureMarker(object): def arg(request): return request.param - l = [] + values = [] def test_1(arg): - l.append(arg) + values.append(arg) def test_2(arg): - l.append(arg) + values.append(arg) """) reprec = testdir.inline_run("-v") reprec.assertoutcome(passed=4) - l = reprec.getcalls("pytest_runtest_call")[0].item.module.l - assert l == [1, 1, 2, 2] + values = reprec.getcalls("pytest_runtest_call")[0].item.module.values + assert values == [1, 1, 2, 2] def test_module_parametrized_ordering(self, testdir): testdir.makeconftest(""" @@ -2172,7 +2172,7 @@ class TestFixtureMarker(object): testdir.makeconftest(""" import pytest - l = [] + values = [] @pytest.fixture(scope="function", params=[1,2]) def farg(request): @@ -2185,7 +2185,7 @@ class TestFixtureMarker(object): @pytest.fixture(scope="function", autouse=True) def append(request, farg, carg): def fin(): - l.append("fin_%s%s" % (carg, farg)) + values.append("fin_%s%s" % (carg, farg)) request.addfinalizer(fin) """) testdir.makepyfile(""" @@ -2223,30 +2223,30 @@ class TestFixtureMarker(object): @pytest.fixture(scope="function", params=[1, 2]) def arg(request): param = request.param - request.addfinalizer(lambda: l.append("fin:%s" % param)) - l.append("create:%s" % param) + request.addfinalizer(lambda: values.append("fin:%s" % param)) + values.append("create:%s" % param) return request.param @pytest.fixture(scope="module", params=["mod1", "mod2"]) def modarg(request): param = request.param - request.addfinalizer(lambda: l.append("fin:%s" % param)) - l.append("create:%s" % param) + request.addfinalizer(lambda: values.append("fin:%s" % param)) + values.append("create:%s" % param) return request.param - l = [] + values = [] def test_1(arg): - l.append("test1") + values.append("test1") def test_2(modarg): - l.append("test2") + values.append("test2") def test_3(arg, modarg): - l.append("test3") + values.append("test3") def test_4(modarg, arg): - l.append("test4") + values.append("test4") """) reprec = testdir.inline_run("-v") reprec.assertoutcome(passed=12) - l = reprec.getcalls("pytest_runtest_call")[0].item.module.l + values = reprec.getcalls("pytest_runtest_call")[0].item.module.values expected = [ 'create:1', 'test1', 'fin:1', 'create:2', 'test1', 'fin:2', 'create:mod1', 'test2', 'create:1', 'test3', @@ -2257,8 +2257,8 @@ class TestFixtureMarker(object): 'test4', 'fin:1', 'create:2', 'test4', 'fin:2', 'fin:mod2'] import pprint - pprint.pprint(list(zip(l, expected))) - assert l == expected + pprint.pprint(list(zip(values, expected))) + assert values == expected def test_parametrized_fixture_teardown_order(self, testdir): testdir.makepyfile(""" @@ -2267,29 +2267,29 @@ class TestFixtureMarker(object): def param1(request): return request.param - l = [] + values = [] class TestClass(object): @classmethod @pytest.fixture(scope="class", autouse=True) def setup1(self, request, param1): - l.append(1) + values.append(1) request.addfinalizer(self.teardown1) @classmethod def teardown1(self): - assert l.pop() == 1 + assert values.pop() == 1 @pytest.fixture(scope="class", autouse=True) def setup2(self, request, param1): - l.append(2) + values.append(2) request.addfinalizer(self.teardown2) @classmethod def teardown2(self): - assert l.pop() == 2 + assert values.pop() == 2 def test(self): pass def test_finish(): - assert not l + assert not values """) result = testdir.runpytest("-v") result.stdout.fnmatch_lines(""" @@ -2354,42 +2354,42 @@ class TestFixtureMarker(object): def test_request_is_clean(self, testdir): testdir.makepyfile(""" import pytest - l = [] + values = [] @pytest.fixture(params=[1, 2]) def fix(request): - request.addfinalizer(lambda: l.append(request.param)) + request.addfinalizer(lambda: values.append(request.param)) def test_fix(fix): pass """) reprec = testdir.inline_run("-s") - l = reprec.getcalls("pytest_runtest_call")[0].item.module.l - assert l == [1, 2] + values = reprec.getcalls("pytest_runtest_call")[0].item.module.values + assert values == [1, 2] def test_parametrize_separated_lifecycle(self, testdir): testdir.makepyfile(""" import pytest - l = [] + values = [] @pytest.fixture(scope="module", params=[1, 2]) def arg(request): x = request.param - request.addfinalizer(lambda: l.append("fin%s" % x)) + request.addfinalizer(lambda: values.append("fin%s" % x)) return request.param def test_1(arg): - l.append(arg) + values.append(arg) def test_2(arg): - l.append(arg) + values.append(arg) """) reprec = testdir.inline_run("-vs") reprec.assertoutcome(passed=4) - l = reprec.getcalls("pytest_runtest_call")[0].item.module.l + values = reprec.getcalls("pytest_runtest_call")[0].item.module.values import pprint - pprint.pprint(l) - # assert len(l) == 6 - assert l[0] == l[1] == 1 - assert l[2] == "fin1" - assert l[3] == l[4] == 2 - assert l[5] == "fin2" + pprint.pprint(values) + # assert len(values) == 6 + assert values[0] == values[1] == 1 + assert values[2] == "fin1" + assert values[3] == values[4] == 2 + assert values[5] == "fin2" def test_parametrize_function_scoped_finalizers_called(self, testdir): testdir.makepyfile(""" @@ -2398,17 +2398,17 @@ class TestFixtureMarker(object): @pytest.fixture(scope="function", params=[1, 2]) def arg(request): x = request.param - request.addfinalizer(lambda: l.append("fin%s" % x)) + request.addfinalizer(lambda: values.append("fin%s" % x)) return request.param - l = [] + values = [] def test_1(arg): - l.append(arg) + values.append(arg) def test_2(arg): - l.append(arg) + values.append(arg) def test_3(): - assert len(l) == 8 - assert l == [1, "fin1", 2, "fin2", 1, "fin1", 2, "fin2"] + assert len(values) == 8 + assert values == [1, "fin1", 2, "fin2", 1, "fin1", 2, "fin2"] """) reprec = testdir.inline_run("-v") reprec.assertoutcome(passed=5) @@ -2418,7 +2418,7 @@ class TestFixtureMarker(object): def test_finalizer_order_on_parametrization(self, scope, testdir): testdir.makepyfile(""" import pytest - l = [] + values = [] @pytest.fixture(scope=%(scope)r, params=["1"]) def fix1(request): @@ -2427,13 +2427,13 @@ class TestFixtureMarker(object): @pytest.fixture(scope=%(scope)r) def fix2(request, base): def cleanup_fix2(): - assert not l, "base should not have been finalized" + assert not values, "base should not have been finalized" request.addfinalizer(cleanup_fix2) @pytest.fixture(scope=%(scope)r) def base(request, fix1): def cleanup_base(): - l.append("fin_base") + values.append("fin_base") print ("finalizing base") request.addfinalizer(cleanup_base) @@ -2451,29 +2451,29 @@ class TestFixtureMarker(object): def test_class_scope_parametrization_ordering(self, testdir): testdir.makepyfile(""" import pytest - l = [] + values = [] @pytest.fixture(params=["John", "Doe"], scope="class") def human(request): - request.addfinalizer(lambda: l.append("fin %s" % request.param)) + request.addfinalizer(lambda: values.append("fin %s" % request.param)) return request.param class TestGreetings(object): def test_hello(self, human): - l.append("test_hello") + values.append("test_hello") class TestMetrics(object): def test_name(self, human): - l.append("test_name") + values.append("test_name") def test_population(self, human): - l.append("test_population") + values.append("test_population") """) reprec = testdir.inline_run() reprec.assertoutcome(passed=6) - l = reprec.getcalls("pytest_runtest_call")[0].item.module.l - assert l == ["test_hello", "fin John", "test_hello", "fin Doe", - "test_name", "test_population", "fin John", - "test_name", "test_population", "fin Doe"] + values = reprec.getcalls("pytest_runtest_call")[0].item.module.values + assert values == ["test_hello", "fin John", "test_hello", "fin Doe", + "test_name", "test_population", "fin John", + "test_name", "test_population", "fin Doe"] def test_parametrize_setup_function(self, testdir): testdir.makepyfile(""" @@ -2485,21 +2485,21 @@ class TestFixtureMarker(object): @pytest.fixture(scope="module", autouse=True) def mysetup(request, arg): - request.addfinalizer(lambda: l.append("fin%s" % arg)) - l.append("setup%s" % arg) + request.addfinalizer(lambda: values.append("fin%s" % arg)) + values.append("setup%s" % arg) - l = [] + values = [] def test_1(arg): - l.append(arg) + values.append(arg) def test_2(arg): - l.append(arg) + values.append(arg) def test_3(): import pprint - pprint.pprint(l) + pprint.pprint(values) if arg == 1: - assert l == ["setup1", 1, 1, ] + assert values == ["setup1", 1, 1, ] elif arg == 2: - assert l == ["setup1", 1, 1, "fin1", + assert values == ["setup1", 1, 1, "fin1", "setup2", 2, 2, ] """) @@ -2660,13 +2660,13 @@ class TestErrors(object): request.addfinalizer(f) return object() - l = [] + values = [] def test_1(fix1): - l.append(fix1) + values.append(fix1) def test_2(fix1): - l.append(fix1) + values.append(fix1) def test_3(): - assert l[0] != l[1] + assert values[0] != values[1] """) result = testdir.runpytest() result.stdout.fnmatch_lines(""" diff --git a/testing/python/integration.py b/testing/python/integration.py index 1a98eae2a..6ea29fa98 100644 --- a/testing/python/integration.py +++ b/testing/python/integration.py @@ -93,8 +93,8 @@ class TestMockDecoration(object): def f(x): pass - l = getfuncargnames(f) - assert l == ("x",) + values = getfuncargnames(f) + assert values == ("x",) def test_wrapped_getfuncargnames_patching(self): from _pytest.compat import getfuncargnames @@ -110,8 +110,8 @@ class TestMockDecoration(object): def f(x, y, z): pass - l = getfuncargnames(f) - assert l == ("y", "z") + values = getfuncargnames(f) + assert values == ("y", "z") def test_unittest_mock(self, testdir): pytest.importorskip("unittest.mock") diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index a0025a15a..2acdf669e 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -1071,21 +1071,21 @@ class TestMetafuncFunctional(object): def test_parametrize_scope_overrides(self, testdir, scope, length): testdir.makepyfile(""" import pytest - l = [] + values = [] def pytest_generate_tests(metafunc): if "arg" in metafunc.funcargnames: metafunc.parametrize("arg", [1,2], indirect=True, scope=%r) @pytest.fixture def arg(request): - l.append(request.param) + values.append(request.param) return request.param def test_hello(arg): assert arg in (1,2) def test_world(arg): assert arg in (1,2) def test_checklength(): - assert len(l) == %d + assert len(values) == %d """ % (scope, length)) reprec = testdir.inline_run() reprec.assertoutcome(passed=5) diff --git a/testing/test_assertion.py b/testing/test_assertion.py index a5174cc8c..4cd050d8c 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -229,9 +229,9 @@ class TestImportHookInstallation(object): return pkg.helper.tool """, 'pkg/other.py': """ - l = [3, 2] + values = [3, 2] def tool(): - assert l.pop() == 3 + assert values.pop() == 3 """, 'conftest.py': """ pytest_plugins = ['pkg.plugin'] @@ -248,7 +248,7 @@ class TestImportHookInstallation(object): result = testdir.runpytest_subprocess('--assert=rewrite') result.stdout.fnmatch_lines(['>*assert a == b*', 'E*assert 2 == 3*', - '>*assert l.pop() == 3*', + '>*assert values.pop() == 3*', 'E*AssertionError']) def test_register_assert_rewrite_checks_types(self): @@ -263,13 +263,13 @@ class TestBinReprIntegration(object): def test_pytest_assertrepr_compare_called(self, testdir): testdir.makeconftest(""" import pytest - l = [] + values = [] def pytest_assertrepr_compare(op, left, right): - l.append((op, left, right)) + values.append((op, left, right)) @pytest.fixture def list(request): - return l + return values """) testdir.makepyfile(""" def test_hello(): diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index 78a5f2bae..31e996052 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -473,8 +473,8 @@ class TestAssertionRewrite(object): def test_len(self): def f(): - l = list(range(10)) - assert len(l) == 11 + values = list(range(10)) + assert len(values) == 11 assert getmsg(f).startswith("""assert 10 == 11 + where 10 = len([""") diff --git a/testing/test_collection.py b/testing/test_collection.py index 49a290060..cf13d4b00 100644 --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -703,9 +703,9 @@ class TestNodekeywords(object): def test_pass(): pass def test_fail(): assert 0 """) - l = list(modcol.keywords) - assert modcol.name in l - for x in l: + values = list(modcol.keywords) + assert modcol.name in values + for x in values: assert not x.startswith("_") assert modcol.name in repr(modcol.keywords) diff --git a/testing/test_config.py b/testing/test_config.py index 3cad6d587..f21d1821e 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -123,11 +123,11 @@ class TestConfigCmdlineParsing(object): class TestConfigAPI(object): def test_config_trace(self, testdir): config = testdir.parseconfig() - l = [] - config.trace.root.setwriter(l.append) + values = [] + config.trace.root.setwriter(values.append) config.trace("hello") - assert len(l) == 1 - assert l[0] == "hello [config]\n" + assert len(values) == 1 + assert values[0] == "hello [config]\n" def test_config_getoption(self, testdir): testdir.makeconftest(""" @@ -209,10 +209,10 @@ class TestConfigAPI(object): paths=hello world/sub.py """) config = testdir.parseconfig() - l = config.getini("paths") - assert len(l) == 2 - assert l[0] == p.dirpath('hello') - assert l[1] == p.dirpath('world/sub.py') + values = config.getini("paths") + assert len(values) == 2 + assert values[0] == p.dirpath('hello') + assert values[1] == p.dirpath('world/sub.py') pytest.raises(ValueError, config.getini, 'other') def test_addini_args(self, testdir): @@ -226,11 +226,11 @@ class TestConfigAPI(object): args=123 "123 hello" "this" """) config = testdir.parseconfig() - l = config.getini("args") - assert len(l) == 3 - assert l == ["123", "123 hello", "this"] - l = config.getini("a2") - assert l == list("123") + values = config.getini("args") + assert len(values) == 3 + assert values == ["123", "123 hello", "this"] + values = config.getini("a2") + assert values == list("123") def test_addini_linelist(self, testdir): testdir.makeconftest(""" @@ -244,11 +244,11 @@ class TestConfigAPI(object): second line """) config = testdir.parseconfig() - l = config.getini("xy") - assert len(l) == 2 - assert l == ["123 345", "second line"] - l = config.getini("a2") - assert l == [] + values = config.getini("xy") + assert len(values) == 2 + assert values == ["123 345", "second line"] + values = config.getini("a2") + assert values == [] @pytest.mark.parametrize('str_val, bool_val', [('True', True), ('no', False), ('no-ini', True)]) @@ -275,13 +275,13 @@ class TestConfigAPI(object): xy= 123 """) config = testdir.parseconfig() - l = config.getini("xy") - assert len(l) == 1 - assert l == ["123"] + values = config.getini("xy") + assert len(values) == 1 + assert values == ["123"] config.addinivalue_line("xy", "456") - l = config.getini("xy") - assert len(l) == 2 - assert l == ["123", "456"] + values = config.getini("xy") + assert len(values) == 2 + assert values == ["123", "456"] def test_addinivalue_line_new(self, testdir): testdir.makeconftest(""" @@ -291,13 +291,13 @@ class TestConfigAPI(object): config = testdir.parseconfig() assert not config.getini("xy") config.addinivalue_line("xy", "456") - l = config.getini("xy") - assert len(l) == 1 - assert l == ["456"] + values = config.getini("xy") + assert len(values) == 1 + assert values == ["456"] config.addinivalue_line("xy", "123") - l = config.getini("xy") - assert len(l) == 2 - assert l == ["456", "123"] + values = config.getini("xy") + assert len(values) == 2 + assert values == ["456", "123"] def test_confcutdir_check_isdir(self, testdir): """Give an error if --confcutdir is not a valid directory (#2078)""" @@ -596,13 +596,13 @@ def test_load_initial_conftest_last_ordering(testdir): m = My() pm.register(m) hc = pm.hook.pytest_load_initial_conftests - l = hc._nonwrappers + hc._wrappers + values = hc._nonwrappers + hc._wrappers expected = [ "_pytest.config", 'test_config', '_pytest.capture', ] - assert [x.function.__module__ for x in l] == expected + assert [x.function.__module__ for x in values] == expected def test_get_plugin_specs_as_list(): @@ -623,17 +623,17 @@ def test_get_plugin_specs_as_list(): class TestWarning(object): def test_warn_config(self, testdir): testdir.makeconftest(""" - l = [] + values = [] def pytest_configure(config): config.warn("C1", "hello") def pytest_logwarning(code, message): if message == "hello" and code == "C1": - l.append(1) + values.append(1) """) testdir.makepyfile(""" def test_proper(pytestconfig): import conftest - assert conftest.l == [1] + assert conftest.values == [1] """) reprec = testdir.inline_run() reprec.assertoutcome(passed=1) diff --git a/testing/test_conftest.py b/testing/test_conftest.py index 39590f5f2..c0411b723 100644 --- a/testing/test_conftest.py +++ b/testing/test_conftest.py @@ -87,8 +87,8 @@ def test_doubledash_considered(testdir): conf.join("conftest.py").ensure() conftest = PytestPluginManager() conftest_setinitial(conftest, [conf.basename, conf.basename]) - l = conftest._getconftestmodules(conf) - assert len(l) == 1 + values = conftest._getconftestmodules(conf) + assert len(values) == 1 def test_issue151_load_all_conftests(testdir): @@ -130,28 +130,28 @@ def test_conftestcutdir(testdir): p = testdir.mkdir("x") conftest = PytestPluginManager() conftest_setinitial(conftest, [testdir.tmpdir], confcutdir=p) - l = conftest._getconftestmodules(p) - assert len(l) == 0 - l = conftest._getconftestmodules(conf.dirpath()) - assert len(l) == 0 + values = conftest._getconftestmodules(p) + assert len(values) == 0 + values = conftest._getconftestmodules(conf.dirpath()) + assert len(values) == 0 assert conf not in conftest._conftestpath2mod # but we can still import a conftest directly conftest._importconftest(conf) - l = conftest._getconftestmodules(conf.dirpath()) - assert l[0].__file__.startswith(str(conf)) + values = conftest._getconftestmodules(conf.dirpath()) + assert values[0].__file__.startswith(str(conf)) # and all sub paths get updated properly - l = conftest._getconftestmodules(p) - assert len(l) == 1 - assert l[0].__file__.startswith(str(conf)) + values = conftest._getconftestmodules(p) + assert len(values) == 1 + assert values[0].__file__.startswith(str(conf)) def test_conftestcutdir_inplace_considered(testdir): conf = testdir.makeconftest("") conftest = PytestPluginManager() conftest_setinitial(conftest, [conf.dirpath()], confcutdir=conf.dirpath()) - l = conftest._getconftestmodules(conf.dirpath()) - assert len(l) == 1 - assert l[0].__file__.startswith(str(conf)) + values = conftest._getconftestmodules(conf.dirpath()) + assert len(values) == 1 + assert values[0].__file__.startswith(str(conf)) @pytest.mark.parametrize("name", 'test tests whatever .dotdir'.split()) diff --git a/testing/test_mark.py b/testing/test_mark.py index 9ae88a665..3ac42daee 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -468,11 +468,11 @@ class TestFunctional(object): assert marker.kwargs == {'x': 1, 'y': 2, 'z': 4} # test the new __iter__ interface - l = list(marker) - assert len(l) == 3 - assert l[0].args == ("pos0",) - assert l[1].args == () - assert l[2].args == ("pos1", ) + values = list(marker) + assert len(values) == 3 + assert values[0].args == ("pos0",) + assert values[1].args == () + assert values[2].args == ("pos1", ) @pytest.mark.xfail(reason='unfixed') def test_merging_markers_deep(self, testdir): @@ -564,9 +564,9 @@ class TestFunctional(object): def test_func(): pass """) - l = reprec.getfailedcollections() - assert len(l) == 1 - assert "TypeError" in str(l[0].longrepr) + values = reprec.getfailedcollections() + assert len(values) == 1 + assert "TypeError" in str(values[0].longrepr) def test_mark_dynamically_in_funcarg(self, testdir): testdir.makeconftest(""" @@ -575,8 +575,8 @@ class TestFunctional(object): def arg(request): request.applymarker(pytest.mark.hello) def pytest_terminal_summary(terminalreporter): - l = terminalreporter.stats['passed'] - terminalreporter.writer.line("keyword: %s" % l[0].keywords) + values = terminalreporter.stats['passed'] + terminalreporter.writer.line("keyword: %s" % values[0].keywords) """) testdir.makepyfile(""" def test_func(arg): @@ -599,10 +599,10 @@ class TestFunctional(object): item, = items keywords = item.keywords marker = keywords['hello'] - l = list(marker) - assert len(l) == 2 - assert l[0].args == ("pos0",) - assert l[1].args == ("pos1",) + values = list(marker) + assert len(values) == 2 + assert values[0].args == ("pos0",) + assert values[1].args == ("pos1",) def test_no_marker_match_on_unmarked_names(self, testdir): p = testdir.makepyfile(""" diff --git a/testing/test_nose.py b/testing/test_nose.py index 872922ed4..df3e1a94b 100644 --- a/testing/test_nose.py +++ b/testing/test_nose.py @@ -8,18 +8,18 @@ def setup_module(mod): def test_nose_setup(testdir): p = testdir.makepyfile(""" - l = [] + values = [] from nose.tools import with_setup - @with_setup(lambda: l.append(1), lambda: l.append(2)) + @with_setup(lambda: values.append(1), lambda: values.append(2)) def test_hello(): - assert l == [1] + assert values == [1] def test_world(): - assert l == [1,2] + assert values == [1,2] - test_hello.setup = lambda: l.append(1) - test_hello.teardown = lambda: l.append(2) + test_hello.setup = lambda: values.append(1) + test_hello.teardown = lambda: values.append(2) """) result = testdir.runpytest(p, '-p', 'nose') result.assert_outcomes(passed=2) @@ -27,15 +27,15 @@ def test_nose_setup(testdir): def test_setup_func_with_setup_decorator(): from _pytest.nose import call_optional - l = [] + values = [] class A(object): @pytest.fixture(autouse=True) def f(self): - l.append(1) + values.append(1) call_optional(A(), "f") - assert not l + assert not values def test_setup_func_not_callable(): @@ -51,24 +51,24 @@ def test_nose_setup_func(testdir): p = testdir.makepyfile(""" from nose.tools import with_setup - l = [] + values = [] def my_setup(): a = 1 - l.append(a) + values.append(a) def my_teardown(): b = 2 - l.append(b) + values.append(b) @with_setup(my_setup, my_teardown) def test_hello(): - print (l) - assert l == [1] + print (values) + assert values == [1] def test_world(): - print (l) - assert l == [1,2] + print (values) + assert values == [1,2] """) result = testdir.runpytest(p, '-p', 'nose') @@ -79,18 +79,18 @@ def test_nose_setup_func_failure(testdir): p = testdir.makepyfile(""" from nose.tools import with_setup - l = [] + values = [] my_setup = lambda x: 1 my_teardown = lambda x: 2 @with_setup(my_setup, my_teardown) def test_hello(): - print (l) - assert l == [1] + print (values) + assert values == [1] def test_world(): - print (l) - assert l == [1,2] + print (values) + assert values == [1,2] """) result = testdir.runpytest(p, '-p', 'nose') @@ -101,13 +101,13 @@ def test_nose_setup_func_failure(testdir): def test_nose_setup_func_failure_2(testdir): testdir.makepyfile(""" - l = [] + values = [] my_setup = 1 my_teardown = 2 def test_hello(): - assert l == [] + assert values == [] test_hello.setup = my_setup test_hello.teardown = my_teardown @@ -121,26 +121,26 @@ def test_nose_setup_partial(testdir): p = testdir.makepyfile(""" from functools import partial - l = [] + values = [] def my_setup(x): a = x - l.append(a) + values.append(a) def my_teardown(x): b = x - l.append(b) + values.append(b) my_setup_partial = partial(my_setup, 1) my_teardown_partial = partial(my_teardown, 2) def test_hello(): - print (l) - assert l == [1] + print (values) + assert values == [1] def test_world(): - print (l) - assert l == [1,2] + print (values) + assert values == [1,2] test_hello.setup = my_setup_partial test_hello.teardown = my_teardown_partial @@ -251,19 +251,19 @@ def test_module_level_setup(testdir): def test_nose_style_setup_teardown(testdir): testdir.makepyfile(""" - l = [] + values = [] def setup_module(): - l.append(1) + values.append(1) def teardown_module(): - del l[0] + del values[0] def test_hello(): - assert l == [1] + assert values == [1] def test_world(): - assert l == [1] + assert values == [1] """) result = testdir.runpytest('-p', 'nose') result.stdout.fnmatch_lines([ diff --git a/testing/test_pluginmanager.py b/testing/test_pluginmanager.py index be7980c26..13c487c26 100644 --- a/testing/test_pluginmanager.py +++ b/testing/test_pluginmanager.py @@ -85,23 +85,23 @@ class TestPytestPluginInteractions(object): def test_configure(self, testdir): config = testdir.parseconfig() - l = [] + values = [] class A(object): def pytest_configure(self, config): - l.append(self) + values.append(self) config.pluginmanager.register(A()) - assert len(l) == 0 + assert len(values) == 0 config._do_configure() - assert len(l) == 1 + assert len(values) == 1 config.pluginmanager.register(A()) # leads to a configured() plugin - assert len(l) == 2 - assert l[0] != l[1] + assert len(values) == 2 + assert values[0] != values[1] config._ensure_unconfigure() config.pluginmanager.register(A()) - assert len(l) == 2 + assert len(values) == 2 def test_hook_tracing(self): pytestpm = get_config().pluginmanager # fully initialized with plugins @@ -116,19 +116,19 @@ class TestPytestPluginInteractions(object): saveindent.append(pytestpm.trace.root.indent) raise ValueError() - l = [] - pytestpm.trace.root.setwriter(l.append) + values = [] + pytestpm.trace.root.setwriter(values.append) undo = pytestpm.enable_tracing() try: indent = pytestpm.trace.root.indent p = api1() pytestpm.register(p) assert pytestpm.trace.root.indent == indent - assert len(l) >= 2 - assert 'pytest_plugin_registered' in l[0] - assert 'finish' in l[1] + assert len(values) >= 2 + assert 'pytest_plugin_registered' in values[0] + assert 'finish' in values[1] - l[:] = [] + values[:] = [] with pytest.raises(ValueError): pytestpm.register(api2()) assert pytestpm.trace.root.indent == indent @@ -230,12 +230,12 @@ class TestPytestPluginManager(object): mod = py.std.types.ModuleType("x.y.pytest_hello") pm.register(mod) assert pm.is_registered(mod) - l = pm.get_plugins() - assert mod in l + values = pm.get_plugins() + assert mod in values pytest.raises(ValueError, "pm.register(mod)") pytest.raises(ValueError, lambda: pm.register(mod)) # assert not pm.is_registered(mod2) - assert pm.get_plugins() == l + assert pm.get_plugins() == values def test_canonical_import(self, monkeypatch): mod = py.std.types.ModuleType("pytest_xyz") @@ -269,8 +269,8 @@ class TestPytestPluginManager(object): # check that it is not registered twice pytestpm.consider_module(mod) - l = reprec.getcalls("pytest_plugin_registered") - assert len(l) == 1 + values = reprec.getcalls("pytest_plugin_registered") + assert len(values) == 1 def test_consider_env_fails_to_import(self, monkeypatch, pytestpm): monkeypatch.setenv('PYTEST_PLUGINS', 'nonexisting', prepend=",") diff --git a/testing/test_recwarn.py b/testing/test_recwarn.py index 6895b1140..481bf0a04 100644 --- a/testing/test_recwarn.py +++ b/testing/test_recwarn.py @@ -30,10 +30,10 @@ class TestWarningsRecorderChecker(object): assert len(rec.list) == 2 warn = rec.pop() assert str(warn.message) == "hello" - l = rec.list + values = rec.list rec.clear() assert len(rec.list) == 0 - assert l is rec.list + assert values is rec.list pytest.raises(AssertionError, "rec.pop()") def test_typechecking(self): diff --git a/testing/test_runner.py b/testing/test_runner.py index 1ab449ba3..84d8f6c71 100644 --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -13,12 +13,12 @@ class TestSetupState(object): def test_setup(self, testdir): ss = runner.SetupState() item = testdir.getitem("def test_func(): pass") - l = [1] + values = [1] ss.prepare(item) - ss.addfinalizer(l.pop, colitem=item) - assert l + ss.addfinalizer(values.pop, colitem=item) + assert values ss._pop_and_teardown() - assert not l + assert not values def test_teardown_exact_stack_empty(self, testdir): item = testdir.getitem("def test_func(): pass") diff --git a/testing/test_runner_xunit.py b/testing/test_runner_xunit.py index f01eaca13..fc931f867 100644 --- a/testing/test_runner_xunit.py +++ b/testing/test_runner_xunit.py @@ -39,20 +39,20 @@ def test_module_and_function_setup(testdir): def test_module_setup_failure_no_teardown(testdir): reprec = testdir.inline_runsource(""" - l = [] + values = [] def setup_module(module): - l.append(1) + values.append(1) 0/0 def test_nothing(): pass def teardown_module(module): - l.append(2) + values.append(2) """) reprec.assertoutcome(failed=1) calls = reprec.getcalls("pytest_runtest_setup") - assert calls[0].item.module.l == [1] + assert calls[0].item.module.values == [1] def test_setup_function_failure_no_teardown(testdir): diff --git a/testing/test_session.py b/testing/test_session.py index f9eb95f3b..9ec13f523 100644 --- a/testing/test_session.py +++ b/testing/test_session.py @@ -45,9 +45,9 @@ class SessionTests(object): a = 1 """) reprec = testdir.inline_run(tfile) - l = reprec.getfailedcollections() - assert len(l) == 1 - out = str(l[0].longrepr) + values = reprec.getfailedcollections() + assert len(values) == 1 + out = str(values[0].longrepr) assert out.find('does_not_work') != -1 def test_raises_output(self, testdir): @@ -75,9 +75,9 @@ class SessionTests(object): def test_syntax_error_module(self, testdir): reprec = testdir.inline_runsource("this is really not python") - l = reprec.getfailedcollections() - assert len(l) == 1 - out = str(l[0].longrepr) + values = reprec.getfailedcollections() + assert len(values) == 1 + out = str(values[0].longrepr) assert out.find(str('not python')) != -1 def test_exit_first_problem(self, testdir): @@ -144,15 +144,15 @@ class TestNewSession(SessionTests): def test_order_of_execution(self, testdir): reprec = testdir.inline_runsource(""" - l = [] + values = [] def test_1(): - l.append(1) + values.append(1) def test_2(): - l.append(2) + values.append(2) def test_3(): - assert l == [1,2] + assert values == [1,2] class Testmygroup(object): - reslist = l + reslist = values def test_1(self): self.reslist.append(1) def test_2(self): @@ -242,13 +242,13 @@ def test_exclude(testdir): def test_sessionfinish_with_start(testdir): testdir.makeconftest(""" import os - l = [] + values = [] def pytest_sessionstart(): - l.append(os.getcwd()) + values.append(os.getcwd()) os.chdir("..") def pytest_sessionfinish(): - assert l[0] == os.getcwd() + assert values[0] == os.getcwd() """) res = testdir.runpytest("--collect-only") diff --git a/testing/test_skipping.py b/testing/test_skipping.py index 6608ccadf..a25c9460a 100644 --- a/testing/test_skipping.py +++ b/testing/test_skipping.py @@ -679,9 +679,9 @@ def test_skip_reasons_folding(): ev2.longrepr = longrepr ev2.skipped = True - l = folded_skips([ev1, ev2]) - assert len(l) == 1 - num, fspath, lineno, reason = l[0] + values = folded_skips([ev1, ev2]) + assert len(values) == 1 + num, fspath, lineno, reason = values[0] assert num == 2 assert fspath == path assert lineno == lineno diff --git a/testing/test_terminal.py b/testing/test_terminal.py index 9bd607783..0fa98b26e 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -24,12 +24,12 @@ class Option(object): @property def args(self): - l = [] + values = [] if self.verbose: - l.append('-v') + values.append('-v') if self.fulltrace: - l.append('--fulltrace') - return l + values.append('--fulltrace') + return values def pytest_generate_tests(metafunc): diff --git a/testing/test_unittest.py b/testing/test_unittest.py index 84f432a54..3273e81aa 100644 --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -73,19 +73,19 @@ def test_setup(testdir): def test_setUpModule(testdir): testpath = testdir.makepyfile(""" - l = [] + values = [] def setUpModule(): - l.append(1) + values.append(1) def tearDownModule(): - del l[0] + del values[0] def test_hello(): - assert l == [1] + assert values == [1] def test_world(): - assert l == [1] + assert values == [1] """) result = testdir.runpytest(testpath) result.stdout.fnmatch_lines([ @@ -95,13 +95,13 @@ def test_setUpModule(testdir): def test_setUpModule_failing_no_teardown(testdir): testpath = testdir.makepyfile(""" - l = [] + values = [] def setUpModule(): 0/0 def tearDownModule(): - l.append(1) + values.append(1) def test_hello(): pass @@ -109,7 +109,7 @@ def test_setUpModule_failing_no_teardown(testdir): reprec = testdir.inline_run(testpath) reprec.assertoutcome(passed=0, failed=1) call = reprec.getcalls("pytest_runtest_setup")[0] - assert not call.item.module.l + assert not call.item.module.values def test_new_instances(testdir): @@ -129,14 +129,14 @@ def test_teardown(testdir): testpath = testdir.makepyfile(""" import unittest class MyTestCase(unittest.TestCase): - l = [] + values = [] def test_one(self): pass def tearDown(self): - self.l.append(None) + self.values.append(None) class Second(unittest.TestCase): def test_check(self): - self.assertEqual(MyTestCase.l, [None]) + self.assertEqual(MyTestCase.values, [None]) """) reprec = testdir.inline_run(testpath) passed, skipped, failed = reprec.countoutcomes() diff --git a/tox.ini b/tox.ini index e9c1dfa96..1071324bc 100644 --- a/tox.ini +++ b/tox.ini @@ -218,5 +218,3 @@ exclude = _pytest/vendored_packages/pluggy.py ignore= # do not use bare except' E722 - # ambiguous variable name 'l' - E741 From b11640c1eb27a170e6390b4b39be8b06e23f3a5a Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 4 Nov 2017 13:21:34 -0200 Subject: [PATCH 14/20] Fix linting E722: do not use bare except --- _pytest/_code/code.py | 6 +++--- _pytest/_code/source.py | 2 +- _pytest/assertion/rewrite.py | 2 +- _pytest/fixtures.py | 2 +- _pytest/main.py | 4 ++-- _pytest/python_api.py | 2 +- _pytest/runner.py | 2 +- _pytest/unittest.py | 2 +- testing/code/test_excinfo.py | 8 ++++---- tox.ini | 3 --- 10 files changed, 15 insertions(+), 18 deletions(-) diff --git a/_pytest/_code/code.py b/_pytest/_code/code.py index 34655abeb..f3b7eedfc 100644 --- a/_pytest/_code/code.py +++ b/_pytest/_code/code.py @@ -250,7 +250,7 @@ class TracebackEntry(object): line = str(self.statement).lstrip() except KeyboardInterrupt: raise - except: + except: # noqa line = "???" return " File %r:%d in %s\n %s\n" % (fn, self.lineno + 1, name, line) @@ -478,12 +478,12 @@ class FormattedExcinfo(object): s = str(source.getstatement(len(source) - 1)) except KeyboardInterrupt: raise - except: + except: # noqa try: s = str(source[-1]) except KeyboardInterrupt: raise - except: + except: # noqa return 0 return 4 + (len(s) - len(s.lstrip())) diff --git a/_pytest/_code/source.py b/_pytest/_code/source.py index 96c88451b..fc4171264 100644 --- a/_pytest/_code/source.py +++ b/_pytest/_code/source.py @@ -254,7 +254,7 @@ def findsource(obj): sourcelines, lineno = py.std.inspect.findsource(obj) except py.builtin._sysex: raise - except: + except: # noqa return None, -1 source = Source() source.lines = [line.rstrip() for line in sourcelines] diff --git a/_pytest/assertion/rewrite.py b/_pytest/assertion/rewrite.py index c3966340a..d48b6648f 100644 --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -210,7 +210,7 @@ class AssertionRewritingHook(object): mod.__cached__ = pyc mod.__loader__ = self py.builtin.exec_(co, mod.__dict__) - except: + except: # noqa if name in sys.modules: del sys.modules[name] raise diff --git a/_pytest/fixtures.py b/_pytest/fixtures.py index 6c9f251f8..926396407 100644 --- a/_pytest/fixtures.py +++ b/_pytest/fixtures.py @@ -749,7 +749,7 @@ class FixtureDef: try: func = self._finalizer.pop() func() - except: + except: # noqa exceptions.append(sys.exc_info()) if exceptions: e = exceptions[0] diff --git a/_pytest/main.py b/_pytest/main.py index 91083c85f..3bd4022b7 100644 --- a/_pytest/main.py +++ b/_pytest/main.py @@ -118,7 +118,7 @@ def wrap_session(config, doit): excinfo.typename, excinfo.value.msg)) config.hook.pytest_keyboard_interrupt(excinfo=excinfo) session.exitstatus = EXIT_INTERRUPTED - except: + except: # noqa excinfo = _pytest._code.ExceptionInfo() config.notify_exception(excinfo, config.option) session.exitstatus = EXIT_INTERNALERROR @@ -375,7 +375,7 @@ class Node(object): res = function() except py.builtin._sysex: raise - except: + except: # noqa failure = sys.exc_info() setattr(self, exattrname, failure) raise diff --git a/_pytest/python_api.py b/_pytest/python_api.py index a3cf1c8cb..80684c131 100644 --- a/_pytest/python_api.py +++ b/_pytest/python_api.py @@ -84,7 +84,7 @@ class ApproxNumpy(ApproxBase): try: actual = np.asarray(actual) - except: + except: # noqa raise TypeError("cannot compare '{0}' to numpy.ndarray".format(actual)) if actual.shape != self.expected.shape: diff --git a/_pytest/runner.py b/_pytest/runner.py index ed58aceec..b22fa684f 100644 --- a/_pytest/runner.py +++ b/_pytest/runner.py @@ -197,7 +197,7 @@ class CallInfo: except KeyboardInterrupt: self.stop = time() raise - except: + except: # noqa self.excinfo = ExceptionInfo() self.stop = time() diff --git a/_pytest/unittest.py b/_pytest/unittest.py index 939e45206..52c9813e8 100644 --- a/_pytest/unittest.py +++ b/_pytest/unittest.py @@ -115,7 +115,7 @@ class TestCaseFunction(Function): fail("".join(values), pytrace=False) except (fail.Exception, KeyboardInterrupt): raise - except: + except: # noqa fail("ERROR: Unknown Incompatible Exception " "representation:\n%r" % (rawexcinfo,), pytrace=False) except KeyboardInterrupt: diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py index 35ab1cfcc..263d053b5 100644 --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -244,7 +244,7 @@ class TestTraceback_f_g_h(object): def f(n): try: do_stuff() - except: + except: # noqa reraise_me() excinfo = pytest.raises(RuntimeError, f, 8) @@ -434,7 +434,7 @@ class TestFormattedExcinfo(object): exec(source.compile()) except KeyboardInterrupt: raise - except: + except: # noqa return _pytest._code.ExceptionInfo() assert 0, "did not raise" @@ -1217,7 +1217,7 @@ def test_exception_repr_extraction_error_on_recursion(): try: a(numpy_like()) - except: + except: # noqa from _pytest._code.code import ExceptionInfo from _pytest.pytester import LineMatcher exc_info = ExceptionInfo() @@ -1241,7 +1241,7 @@ def test_no_recursion_index_on_recursion_error(): return getattr(self, '_' + attr) RecursionDepthError().trigger - except: + except: # noqa from _pytest._code.code import ExceptionInfo exc_info = ExceptionInfo() if sys.version_info[:2] == (2, 6): diff --git a/tox.ini b/tox.ini index 1071324bc..48913bd7b 100644 --- a/tox.ini +++ b/tox.ini @@ -215,6 +215,3 @@ filterwarnings = [flake8] max-line-length = 120 exclude = _pytest/vendored_packages/pluggy.py -ignore= - # do not use bare except' - E722 From fad1fbe381a9b33dc6205b4af59a1e7f8c3d898a Mon Sep 17 00:00:00 2001 From: Yorgos Pagles Date: Wed, 8 Nov 2017 18:13:34 +0200 Subject: [PATCH 15/20] List python 3.6 in the documented supported versions --- doc/en/getting-started.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/en/getting-started.rst b/doc/en/getting-started.rst index 1571e4f6b..0b336a41f 100644 --- a/doc/en/getting-started.rst +++ b/doc/en/getting-started.rst @@ -1,7 +1,7 @@ Installation and Getting Started =================================== -**Pythons**: Python 2.6,2.7,3.3,3.4,3.5, Jython, PyPy-2.3 +**Pythons**: Python 2.6,2.7,3.3,3.4,3.5,3.6 Jython, PyPy-2.3 **Platforms**: Unix/Posix and Windows From f13333afce107aaa944ee838f9459083719da051 Mon Sep 17 00:00:00 2001 From: Yorgos Pagles Date: Wed, 8 Nov 2017 18:19:59 +0200 Subject: [PATCH 16/20] Create changelog entry --- changelog/2903.trivial | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/2903.trivial diff --git a/changelog/2903.trivial b/changelog/2903.trivial new file mode 100644 index 000000000..492a8c685 --- /dev/null +++ b/changelog/2903.trivial @@ -0,0 +1 @@ +List python 3.6 in the documented supported versions in the getting started document. From d904981bf3612077ac66a0c6e6cd99444bfcdcce Mon Sep 17 00:00:00 2001 From: Yorgos Pagles Date: Wed, 8 Nov 2017 18:20:50 +0200 Subject: [PATCH 17/20] Rename 2903.trivial to 2903.doc --- changelog/{2903.trivial => 2903.doc} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelog/{2903.trivial => 2903.doc} (100%) diff --git a/changelog/2903.trivial b/changelog/2903.doc similarity index 100% rename from changelog/2903.trivial rename to changelog/2903.doc From 3900879a5c261dc06ac69415b7b3507ec6142a9c Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 9 Nov 2017 19:14:20 -0200 Subject: [PATCH 18/20] Mark test_py2_unicode as xfail in PyPy2 on Windows #2905 --- testing/test_warnings.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/testing/test_warnings.py b/testing/test_warnings.py index 1328cc3f2..12539f8ee 100644 --- a/testing/test_warnings.py +++ b/testing/test_warnings.py @@ -144,6 +144,8 @@ def test_unicode(testdir, pyfile_with_warnings): @pytest.mark.skipif(sys.version_info >= (3, 0), reason='warnings message is broken as it is not str instance') def test_py2_unicode(testdir, pyfile_with_warnings): + if getattr(sys, "pypy_version_info", ())[:2] == (5, 9) and sys.platform.startswith('win'): + pytest.xfail("fails with unicode error on PyPy2 5.9 and Windows (#2905)") testdir.makepyfile(''' # -*- coding: utf8 -*- import warnings From c09f69df2a5ce5b39697beb31f2bb34b6b46ae8a Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 9 Nov 2017 19:25:30 -0200 Subject: [PATCH 19/20] Make the "examples" section more prominent in the docs I spent some time today figuring out why PR #2881 was not showing up on doc/parametrize... then after some digging even on readthedocs wondering if the last documentation build had failed, I realized the docs I was looking for was in doc/example/parametrize instead. The section that mentions this is very easy to miss, this makes it a full fledged title and easier to find. --- doc/en/parametrize.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/en/parametrize.rst b/doc/en/parametrize.rst index ef9161546..ebbae31b2 100644 --- a/doc/en/parametrize.rst +++ b/doc/en/parametrize.rst @@ -201,6 +201,9 @@ list:: Note that when calling ``metafunc.parametrize`` multiple times with different parameter sets, all parameter names across those sets cannot be duplicated, otherwise an error will be raised. +More examples +------------- + For further examples, you might want to look at :ref:`more parametrization examples `. From e114feb4588b19f61b6ff096d083b730683272f1 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 9 Nov 2017 20:14:24 -0200 Subject: [PATCH 20/20] Mention pytest-lazy-fixture plugin in the proposal for parametrize_with_fixtures --- doc/en/proposals/parametrize_with_fixtures.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/en/proposals/parametrize_with_fixtures.rst b/doc/en/proposals/parametrize_with_fixtures.rst index 4cff28dd8..146032aa4 100644 --- a/doc/en/proposals/parametrize_with_fixtures.rst +++ b/doc/en/proposals/parametrize_with_fixtures.rst @@ -116,6 +116,11 @@ Alternative approach A new helper function named ``fixture_request`` would tell pytest to yield all parameters marked as a fixture. +.. note:: + + The `pytest-lazy-fixture `_ plugin implements a very + similar solution to the proposal below, make sure to check it out. + .. code-block:: python @pytest.fixture(params=[