Merge remote-tracking branch 'upstream/features' into davidszotten/stepwise
This commit is contained in:
		
						commit
						f947cb2613
					
				| 
						 | 
				
			
			@ -3,7 +3,7 @@ Thanks for submitting a PR, your contribution is really appreciated!
 | 
			
		|||
Here's a quick checklist that should be present in PRs (you can delete this text from the final description, this is
 | 
			
		||||
just a guideline):
 | 
			
		||||
 | 
			
		||||
- [ ] Create a new changelog file in the `changelog` folder, with a name like `<ISSUE NUMBER>.<TYPE>.rst`. See [changelog/README.rst](/changelog/README.rst) for details.
 | 
			
		||||
- [ ] Create a new changelog file in the `changelog` folder, with a name like `<ISSUE NUMBER>.<TYPE>.rst`. See [changelog/README.rst](https://github.com/pytest-dev/pytest/blob/master/changelog/README.rst) for details.
 | 
			
		||||
- [ ] Target the `master` branch for bug fixes, documentation updates and trivial changes.
 | 
			
		||||
- [ ] Target the `features` branch for new features and removals/deprecations.
 | 
			
		||||
- [ ] Include documentation when adding new features.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										26
									
								
								.travis.yml
								
								
								
								
							
							
						
						
									
										26
									
								
								.travis.yml
								
								
								
								
							| 
						 | 
				
			
			@ -12,19 +12,15 @@ install:
 | 
			
		|||
  - pip install --upgrade --pre tox
 | 
			
		||||
env:
 | 
			
		||||
  matrix:
 | 
			
		||||
    # note: please use "tox --listenvs" to populate the build matrix below
 | 
			
		||||
    # please remove the linting env in all cases
 | 
			
		||||
    - TOXENV=py27-pexpect
 | 
			
		||||
    - TOXENV=py27-xdist
 | 
			
		||||
    - TOXENV=py27-trial
 | 
			
		||||
    - TOXENV=py27-numpy
 | 
			
		||||
    - TOXENV=py27-pluggymaster PYTEST_NO_COVERAGE=1
 | 
			
		||||
    - TOXENV=py36-pexpect
 | 
			
		||||
    - TOXENV=py36-xdist
 | 
			
		||||
    - TOXENV=py36-trial
 | 
			
		||||
    - TOXENV=py36-numpy
 | 
			
		||||
    - TOXENV=py36-pluggymaster PYTEST_NO_COVERAGE=1
 | 
			
		||||
    # Specialized factors for py27.
 | 
			
		||||
    - TOXENV=py27-pexpect,py27-trial,py27-numpy
 | 
			
		||||
    - TOXENV=py27-nobyte
 | 
			
		||||
    - TOXENV=py27-xdist
 | 
			
		||||
    - TOXENV=py27-pluggymaster PYTEST_NO_COVERAGE=1
 | 
			
		||||
    # Specialized factors for py36.
 | 
			
		||||
    - TOXENV=py36-pexpect,py36-trial,py36-numpy
 | 
			
		||||
    - TOXENV=py36-xdist
 | 
			
		||||
    - TOXENV=py36-pluggymaster PYTEST_NO_COVERAGE=1
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  include:
 | 
			
		||||
| 
						 | 
				
			
			@ -97,12 +93,6 @@ after_success:
 | 
			
		|||
      coverage xml --ignore-errors
 | 
			
		||||
      coverage report -m --ignore-errors
 | 
			
		||||
      bash <(curl -s https://codecov.io/bash) -Z -X gcov -X coveragepy -X search -X xcode -X gcovout -X fix -f coverage.xml -F "${TOXENV//-/,},linux"
 | 
			
		||||
 | 
			
		||||
      # Coveralls does not support merged reports.
 | 
			
		||||
      if [[ "$TOXENV" = py37 ]]; then
 | 
			
		||||
        pip install coveralls
 | 
			
		||||
        coveralls
 | 
			
		||||
      fi
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
notifications:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								AUTHORS
								
								
								
								
							
							
						
						
									
										2
									
								
								AUTHORS
								
								
								
								
							| 
						 | 
				
			
			@ -204,6 +204,7 @@ Stefan Zimmermann
 | 
			
		|||
Stefano Taschini
 | 
			
		||||
Steffen Allner
 | 
			
		||||
Stephan Obermann
 | 
			
		||||
Sven-Hendrik Haase
 | 
			
		||||
Tadek Teleżyński
 | 
			
		||||
Tarcisio Fischer
 | 
			
		||||
Tareq Alayan
 | 
			
		||||
| 
						 | 
				
			
			@ -213,6 +214,7 @@ Thomas Hisch
 | 
			
		|||
Tim Strazny
 | 
			
		||||
Tom Dalton
 | 
			
		||||
Tom Viner
 | 
			
		||||
Tomer Keren
 | 
			
		||||
Trevor Bekolay
 | 
			
		||||
Tyler Goodlet
 | 
			
		||||
Tzu-ping Chung
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										157
									
								
								CHANGELOG.rst
								
								
								
								
							
							
						
						
									
										157
									
								
								CHANGELOG.rst
								
								
								
								
							| 
						 | 
				
			
			@ -18,6 +18,163 @@ with advance notice in the **Deprecations** section of releases.
 | 
			
		|||
 | 
			
		||||
.. towncrier release notes start
 | 
			
		||||
 | 
			
		||||
pytest 3.9.1 (2018-10-16)
 | 
			
		||||
=========================
 | 
			
		||||
 | 
			
		||||
Features
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
- `#4159 <https://github.com/pytest-dev/pytest/issues/4159>`_: For test-suites containing test classes, the information about the subclassed
 | 
			
		||||
  module is now output only if a higher verbosity level is specified (at least
 | 
			
		||||
  "-vv").
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pytest 3.9.0 (2018-10-15 - not published due to a release automation bug)
 | 
			
		||||
=========================================================================
 | 
			
		||||
 | 
			
		||||
Deprecations
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
- `#3616 <https://github.com/pytest-dev/pytest/issues/3616>`_: The following accesses have been documented as deprecated for years, but are now actually emitting deprecation warnings.
 | 
			
		||||
 | 
			
		||||
  * Access of ``Module``, ``Function``, ``Class``, ``Instance``, ``File`` and ``Item`` through ``Node`` instances. Now
 | 
			
		||||
    users will this warning::
 | 
			
		||||
 | 
			
		||||
          usage of Function.Module is deprecated, please use pytest.Module instead
 | 
			
		||||
 | 
			
		||||
    Users should just ``import pytest`` and access those objects using the ``pytest`` module.
 | 
			
		||||
 | 
			
		||||
  * ``request.cached_setup``, this was the precursor of the setup/teardown mechanism available to fixtures. You can
 | 
			
		||||
    consult `funcarg comparison section in the docs <https://docs.pytest.org/en/latest/funcarg_compare.html>`_.
 | 
			
		||||
 | 
			
		||||
  * Using objects named ``"Class"`` as a way to customize the type of nodes that are collected in ``Collector``
 | 
			
		||||
    subclasses has been deprecated. Users instead should use ``pytest_collect_make_item`` to customize node types during
 | 
			
		||||
    collection.
 | 
			
		||||
 | 
			
		||||
    This issue should affect only advanced plugins who create new collection types, so if you see this warning
 | 
			
		||||
    message please contact the authors so they can change the code.
 | 
			
		||||
 | 
			
		||||
  * The warning that produces the message below has changed to ``RemovedInPytest4Warning``::
 | 
			
		||||
 | 
			
		||||
          getfuncargvalue is deprecated, use getfixturevalue
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#3988 <https://github.com/pytest-dev/pytest/issues/3988>`_: Add a Deprecation warning for pytest.ensuretemp as it was deprecated since a while.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Features
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
- `#2293 <https://github.com/pytest-dev/pytest/issues/2293>`_: Improve usage errors messages by hiding internal details which can be distracting and noisy.
 | 
			
		||||
 | 
			
		||||
  This has the side effect that some error conditions that previously raised generic errors (such as
 | 
			
		||||
  ``ValueError`` for unregistered marks) are now raising ``Failed`` exceptions.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#3332 <https://github.com/pytest-dev/pytest/issues/3332>`_: Improve the error displayed when a ``conftest.py`` file could not be imported.
 | 
			
		||||
 | 
			
		||||
  In order to implement this, a new ``chain`` parameter was added to ``ExceptionInfo.getrepr``
 | 
			
		||||
  to show or hide chained tracebacks in Python 3 (defaults to ``True``).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#3849 <https://github.com/pytest-dev/pytest/issues/3849>`_: Add ``empty_parameter_set_mark=fail_at_collect`` ini option for raising an exception when parametrize collects an empty set.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#3964 <https://github.com/pytest-dev/pytest/issues/3964>`_: Log messages generated in the collection phase are shown when
 | 
			
		||||
  live-logging is enabled and/or when they are logged to a file.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#3985 <https://github.com/pytest-dev/pytest/issues/3985>`_: Introduce ``tmp_path`` as a fixture providing a Path object.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#4013 <https://github.com/pytest-dev/pytest/issues/4013>`_: Deprecation warnings are now shown even if you customize the warnings filters yourself. In the previous version
 | 
			
		||||
  any customization would override pytest's filters and deprecation warnings would fall back to being hidden by default.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#4073 <https://github.com/pytest-dev/pytest/issues/4073>`_: Allow specification of timeout for ``Testdir.runpytest_subprocess()`` and ``Testdir.run()``.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#4098 <https://github.com/pytest-dev/pytest/issues/4098>`_: Add returncode argument to pytest.exit() to exit pytest with a specific return code.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#4102 <https://github.com/pytest-dev/pytest/issues/4102>`_: Reimplement ``pytest.deprecated_call`` using ``pytest.warns`` so it supports the ``match='...'`` keyword argument.
 | 
			
		||||
 | 
			
		||||
  This has the side effect that ``pytest.deprecated_call`` now raises ``pytest.fail.Exception`` instead
 | 
			
		||||
  of ``AssertionError``.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#4149 <https://github.com/pytest-dev/pytest/issues/4149>`_: Require setuptools>=30.3 and move most of the metadata to ``setup.cfg``.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Bug Fixes
 | 
			
		||||
---------
 | 
			
		||||
 | 
			
		||||
- `#2535 <https://github.com/pytest-dev/pytest/issues/2535>`_: Improve error message when test functions of ``unittest.TestCase`` subclasses use a parametrized fixture.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#3057 <https://github.com/pytest-dev/pytest/issues/3057>`_: ``request.fixturenames`` now correctly returns the name of fixtures created by ``request.getfixturevalue()``.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#3946 <https://github.com/pytest-dev/pytest/issues/3946>`_: Warning filters passed as command line options using ``-W`` now take precedence over filters defined in ``ini``
 | 
			
		||||
  configuration files.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#4066 <https://github.com/pytest-dev/pytest/issues/4066>`_: Fix source reindenting by using ``textwrap.dedent`` directly.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#4102 <https://github.com/pytest-dev/pytest/issues/4102>`_: ``pytest.warn`` will capture previously-warned warnings in Python 2. Previously they were never raised.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#4108 <https://github.com/pytest-dev/pytest/issues/4108>`_: Resolve symbolic links for args.
 | 
			
		||||
 | 
			
		||||
  This fixes running ``pytest tests/test_foo.py::test_bar``, where ``tests``
 | 
			
		||||
  is a symlink to ``project/app/tests``:
 | 
			
		||||
  previously ``project/app/conftest.py`` would be ignored for fixtures then.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#4132 <https://github.com/pytest-dev/pytest/issues/4132>`_: Fix duplicate printing of internal errors when using ``--pdb``.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#4135 <https://github.com/pytest-dev/pytest/issues/4135>`_: pathlib based tmpdir cleanup now correctly handles symlinks in the folder.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#4152 <https://github.com/pytest-dev/pytest/issues/4152>`_: Display the filename when encountering ``SyntaxWarning``.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Improved Documentation
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
- `#3713 <https://github.com/pytest-dev/pytest/issues/3713>`_: Update usefixtures documentation to clarify that it can't be used with fixture functions.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#4058 <https://github.com/pytest-dev/pytest/issues/4058>`_: Update fixture documentation to specify that a fixture can be invoked twice in the scope it's defined for.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#4064 <https://github.com/pytest-dev/pytest/issues/4064>`_: According to unittest.rst, setUpModule and tearDownModule were not implemented, but it turns out they are. So updated the documentation for unittest.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#4151 <https://github.com/pytest-dev/pytest/issues/4151>`_: Add tempir testing example to CONTRIBUTING.rst guide
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Trivial/Internal Changes
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
- `#2293 <https://github.com/pytest-dev/pytest/issues/2293>`_: The internal ``MarkerError`` exception has been removed.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#3988 <https://github.com/pytest-dev/pytest/issues/3988>`_: Port the implementation of tmpdir to pathlib.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#4063 <https://github.com/pytest-dev/pytest/issues/4063>`_: Exclude 0.00 second entries from ``--duration`` output unless ``-vv`` is passed on the command-line.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- `#4093 <https://github.com/pytest-dev/pytest/issues/4093>`_: Fixed formatting of string literals in internal tests.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pytest 3.8.2 (2018-10-02)
 | 
			
		||||
=========================
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -280,6 +280,47 @@ Here is a simple overview, with pytest-specific bits:
 | 
			
		|||
    base: features        # if it's a feature
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Writing Tests
 | 
			
		||||
----------------------------
 | 
			
		||||
 | 
			
		||||
Writing tests for plugins or for pytest itself is often done using the `testdir fixture <https://docs.pytest.org/en/latest/reference.html#testdir>`_, as a "black-box" test.
 | 
			
		||||
 | 
			
		||||
For example, to ensure a simple test passes you can write:
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    def test_true_assertion(testdir):
 | 
			
		||||
        testdir.makepyfile(
 | 
			
		||||
            """
 | 
			
		||||
            def test_foo():
 | 
			
		||||
                assert True
 | 
			
		||||
        """
 | 
			
		||||
        )
 | 
			
		||||
        result = testdir.runpytest()
 | 
			
		||||
        result.assert_outcomes(failed=0, passed=1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Alternatively, it is possible to make checks based on the actual output of the termal using
 | 
			
		||||
*glob-like* expressions:
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    def test_true_assertion(testdir):
 | 
			
		||||
        testdir.makepyfile(
 | 
			
		||||
            """
 | 
			
		||||
            def test_foo():
 | 
			
		||||
                assert False
 | 
			
		||||
        """
 | 
			
		||||
        )
 | 
			
		||||
        result = testdir.runpytest()
 | 
			
		||||
        result.stdout.fnmatch_lines(["*assert False*", "*1 failed*"])
 | 
			
		||||
 | 
			
		||||
When choosing a file where to write a new test, take a look at the existing files and see if there's
 | 
			
		||||
one file which looks like a good fit. For example, a regression test about a bug in the ``--lf`` option
 | 
			
		||||
should go into ``test_cacheprovider.py``, given that this option is implemented in ``cacheprovider.py``.
 | 
			
		||||
If in doubt, go ahead and open a PR with your best guess and we can discuss this over the code.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Joining the Development Team
 | 
			
		||||
----------------------------
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										26
									
								
								appveyor.yml
								
								
								
								
							
							
						
						
									
										26
									
								
								appveyor.yml
								
								
								
								
							| 
						 | 
				
			
			@ -1,27 +1,29 @@
 | 
			
		|||
environment:
 | 
			
		||||
  matrix:
 | 
			
		||||
  - TOXENV: "linting,docs,doctesting"
 | 
			
		||||
    PYTEST_NO_COVERAGE: "1"
 | 
			
		||||
  - TOXENV: "py27"
 | 
			
		||||
  - TOXENV: "py34"
 | 
			
		||||
  - TOXENV: "py35"
 | 
			
		||||
  - TOXENV: "py36"
 | 
			
		||||
  - TOXENV: "py37"
 | 
			
		||||
    PYTEST_NO_COVERAGE: "1"
 | 
			
		||||
  - TOXENV: "linting,docs,doctesting"
 | 
			
		||||
  - TOXENV: "py36"
 | 
			
		||||
  - TOXENV: "py35"
 | 
			
		||||
  - TOXENV: "py34"
 | 
			
		||||
  - TOXENV: "pypy"
 | 
			
		||||
    PYTEST_NO_COVERAGE: "1"
 | 
			
		||||
  - TOXENV: "py27-xdist"
 | 
			
		||||
  - TOXENV: "py27-trial"
 | 
			
		||||
  - TOXENV: "py27-numpy"
 | 
			
		||||
  # Specialized factors for py27.
 | 
			
		||||
  - TOXENV: "py27-trial,py27-numpy,py27-nobyte"
 | 
			
		||||
  - TOXENV: "py27-pluggymaster"
 | 
			
		||||
    PYTEST_NO_COVERAGE: "1"
 | 
			
		||||
  - TOXENV: "py36-xdist"
 | 
			
		||||
  - TOXENV: "py36-trial"
 | 
			
		||||
  - TOXENV: "py36-numpy"
 | 
			
		||||
  - TOXENV: "py27-xdist"
 | 
			
		||||
  # Specialized factors for py36.
 | 
			
		||||
  - TOXENV: "py36-trial,py36-numpy"
 | 
			
		||||
  - TOXENV: "py36-pluggymaster"
 | 
			
		||||
    PYTEST_NO_COVERAGE: "1"
 | 
			
		||||
  - TOXENV: "py27-nobyte"
 | 
			
		||||
  - TOXENV: "py36-freeze"
 | 
			
		||||
    PYTEST_NO_COVERAGE: "1"
 | 
			
		||||
  - TOXENV: "py36-xdist"
 | 
			
		||||
 | 
			
		||||
matrix:
 | 
			
		||||
  fast_finish: true
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
  - echo Installed Pythons
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +0,0 @@
 | 
			
		|||
Improve usage errors messages by hiding internal details which can be distracting and noisy.
 | 
			
		||||
 | 
			
		||||
This has the side effect that some error conditions that previously raised generic errors (such as
 | 
			
		||||
``ValueError`` for unregistered marks) are now raising ``Failed`` exceptions.
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
The internal ``MarkerError`` exception has been removed.
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
Improve error message when test functions of ``unittest.TestCase`` subclasses use a parametrized fixture.
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
``request.fixturenames`` now correctly returns the name of fixtures created by ``request.getfixturevalue()``.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +0,0 @@
 | 
			
		|||
Improve the error displayed when a ``conftest.py`` file could not be imported.
 | 
			
		||||
 | 
			
		||||
In order to implement this, a new ``chain`` parameter was added to ``ExceptionInfo.getrepr``
 | 
			
		||||
to show or hide chained tracebacks in Python 3 (defaults to ``True``).
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
Fix unescaped XML raw objects in JUnit report for skipped tests
 | 
			
		||||
| 
						 | 
				
			
			@ -1,22 +0,0 @@
 | 
			
		|||
The following accesses have been documented as deprecated for years, but are now actually emitting deprecation warnings.
 | 
			
		||||
 | 
			
		||||
* Access of ``Module``, ``Function``, ``Class``, ``Instance``, ``File`` and ``Item`` through ``Node`` instances. Now
 | 
			
		||||
  users will this warning::
 | 
			
		||||
 | 
			
		||||
        usage of Function.Module is deprecated, please use pytest.Module instead
 | 
			
		||||
 | 
			
		||||
  Users should just ``import pytest`` and access those objects using the ``pytest`` module.
 | 
			
		||||
 | 
			
		||||
* ``request.cached_setup``, this was the precursor of the setup/teardown mechanism available to fixtures. You can
 | 
			
		||||
  consult `funcarg comparision section in the docs <https://docs.pytest.org/en/latest/funcarg_compare.html>`_.
 | 
			
		||||
 | 
			
		||||
* Using objects named ``"Class"`` as a way to customize the type of nodes that are collected in ``Collector``
 | 
			
		||||
  subclasses has been deprecated. Users instead should use ``pytest_collect_make_item`` to customize node types during
 | 
			
		||||
  collection.
 | 
			
		||||
 | 
			
		||||
  This issue should affect only advanced plugins who create new collection types, so if you see this warning
 | 
			
		||||
  message please contact the authors so they can change the code.
 | 
			
		||||
 | 
			
		||||
* The warning that produces the message below has changed to ``RemovedInPytest4Warning``::
 | 
			
		||||
 | 
			
		||||
        getfuncargvalue is deprecated, use getfixturevalue
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
Update usefixtures documentation to clarify that it can't be used with fixture functions.
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
Add ``empty_parameter_set_mark=fail_at_collect`` ini option for raising an exception when parametrize collects an empty set.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,2 +0,0 @@
 | 
			
		|||
Warning filters passed as command line options using ``-W`` now take precedence over filters defined in ``ini``
 | 
			
		||||
configuration files.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,2 +0,0 @@
 | 
			
		|||
Log messages generated in the collection phase are shown when
 | 
			
		||||
live-logging is enabled and/or when they are logged to a file.
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
Introduce ``tmp_path`` as a fixture providing a Path object.
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
Add a Deprecation warning for pytest.ensuretemp as it was deprecated since a while.
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
Port the implementation of tmpdir to pathlib.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,2 +0,0 @@
 | 
			
		|||
Deprecation warnings are now shown even if you customize the warnings filters yourself. In the previous version
 | 
			
		||||
any customization would override pytest's filters and deprecation warnings would fall back to being hidden by default.
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
Update fixture documentation to specify that a fixture can be invoked twice in the scope it's defined for.
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
According to unittest.rst, setUpModule and tearDownModule were not implemented, but it turns out they are. So updated the documentation for unittest.
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
Fix source reindenting by using ``textwrap.dedent`` directly.
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
Allow specification of timeout for ``Testdir.runpytest_subprocess()`` and ``Testdir.run()``.
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
Fixed formatting of string literals in internal tests.
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
Add returncode argument to pytest.exit() to exit pytest with a specific return code.
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
``pytest.warn`` will capture previously-warned warnings in Python 2. Previously they were never raised.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +0,0 @@
 | 
			
		|||
Reimplement ``pytest.deprecated_call`` using ``pytest.warns`` so it supports the ``match='...'`` keyword argument.
 | 
			
		||||
 | 
			
		||||
This has the side effect that ``pytest.deprecated_call`` now raises ``pytest.fail.Exception`` instead
 | 
			
		||||
of ``AssertionError``.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +0,0 @@
 | 
			
		|||
Resolve symbolic links for args.
 | 
			
		||||
 | 
			
		||||
This fixes running ``pytest tests/test_foo.py::test_bar``, where ``tests``
 | 
			
		||||
is a symlink to ``project/app/tests``:
 | 
			
		||||
previously ``project/app/conftest.py`` would be ignored for fixtures then.
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
pathlib based tmpdir cleanup now correctly handles symlinks in the folder.
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
Require setuptools>=30.3 and move most of the metadata to ``setup.cfg``.
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
Pin ``setuptools>=40.0`` to support ``py_modules`` in ``setup.cfg``
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
Restore the tmpdir behaviour of symlinking the current test run.
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
Make ``--color`` emit colorful dots when not running in verbose mode. Earlier, it would only colorize the test-by-test output if ``--verbose`` was also passed.
 | 
			
		||||
| 
						 | 
				
			
			@ -6,6 +6,8 @@ Release announcements
 | 
			
		|||
   :maxdepth: 2
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   release-3.9.1
 | 
			
		||||
   release-3.9.0
 | 
			
		||||
   release-3.8.2
 | 
			
		||||
   release-3.8.1
 | 
			
		||||
   release-3.8.0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
pytest-3.9.0
 | 
			
		||||
=======================================
 | 
			
		||||
 | 
			
		||||
The pytest team is proud to announce the 3.9.0 release!
 | 
			
		||||
 | 
			
		||||
pytest is a mature Python testing tool with more than a 2000 tests
 | 
			
		||||
against itself, passing on many different interpreters and platforms.
 | 
			
		||||
 | 
			
		||||
This release contains a number of bugs fixes and improvements, so users are encouraged
 | 
			
		||||
to take a look at the CHANGELOG:
 | 
			
		||||
 | 
			
		||||
    https://docs.pytest.org/en/latest/changelog.html
 | 
			
		||||
 | 
			
		||||
For complete documentation, please visit:
 | 
			
		||||
 | 
			
		||||
    https://docs.pytest.org/en/latest/
 | 
			
		||||
 | 
			
		||||
As usual, you can upgrade from pypi via:
 | 
			
		||||
 | 
			
		||||
    pip install -U pytest
 | 
			
		||||
 | 
			
		||||
Thanks to all who contributed to this release, among them:
 | 
			
		||||
 | 
			
		||||
* Andrea Cimatoribus
 | 
			
		||||
* Ankit Goel
 | 
			
		||||
* Anthony Sottile
 | 
			
		||||
* Ben Eyal
 | 
			
		||||
* Bruno Oliveira
 | 
			
		||||
* Daniel Hahler
 | 
			
		||||
* Jeffrey Rackauckas
 | 
			
		||||
* Jose Carlos Menezes
 | 
			
		||||
* Kyle Altendorf
 | 
			
		||||
* Niklas JQ
 | 
			
		||||
* Palash Chatterjee
 | 
			
		||||
* Ronny Pfannschmidt
 | 
			
		||||
* Thomas Hess
 | 
			
		||||
* Thomas Hisch
 | 
			
		||||
* Tomer Keren
 | 
			
		||||
* Victor Maryama
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Happy testing,
 | 
			
		||||
The Pytest Development Team
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
pytest-3.9.1
 | 
			
		||||
=======================================
 | 
			
		||||
 | 
			
		||||
pytest 3.9.1 has just been released to PyPI.
 | 
			
		||||
 | 
			
		||||
This is a bug-fix release, being a drop-in replacement. To upgrade::
 | 
			
		||||
 | 
			
		||||
  pip install --upgrade pytest
 | 
			
		||||
 | 
			
		||||
The full changelog is available at https://docs.pytest.org/en/latest/changelog.html.
 | 
			
		||||
 | 
			
		||||
Thanks to all who contributed to this release, among them:
 | 
			
		||||
 | 
			
		||||
* Bruno Oliveira
 | 
			
		||||
* Ronny Pfannschmidt
 | 
			
		||||
* Thomas Hisch
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Happy testing,
 | 
			
		||||
The pytest Development Team
 | 
			
		||||
| 
						 | 
				
			
			@ -104,7 +104,9 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
 | 
			
		|||
        See http://docs.python.org/library/warnings.html for information
 | 
			
		||||
        on warning categories.
 | 
			
		||||
    tmpdir_factory
 | 
			
		||||
        Return a TempdirFactory instance for the test session.
 | 
			
		||||
        Return a :class:`_pytest.tmpdir.TempdirFactory` instance for the test session.
 | 
			
		||||
    tmp_path_factory
 | 
			
		||||
        Return a :class:`_pytest.tmpdir.TempPathFactory` instance for the test session.
 | 
			
		||||
    tmpdir
 | 
			
		||||
        Return a temporary directory path object
 | 
			
		||||
        which is unique to each test function invocation,
 | 
			
		||||
| 
						 | 
				
			
			@ -113,6 +115,16 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
 | 
			
		|||
        path object.
 | 
			
		||||
 | 
			
		||||
        .. _`py.path.local`: https://py.readthedocs.io/en/latest/path.html
 | 
			
		||||
    tmp_path
 | 
			
		||||
        Return a temporary directory path object
 | 
			
		||||
        which is unique to each test function invocation,
 | 
			
		||||
        created as a sub directory of the base temporary
 | 
			
		||||
        directory.  The returned object is a :class:`pathlib.Path`
 | 
			
		||||
        object.
 | 
			
		||||
 | 
			
		||||
        .. note::
 | 
			
		||||
 | 
			
		||||
            in python < 3.6 this is a pathlib2.Path
 | 
			
		||||
 | 
			
		||||
    no tests ran in 0.12 seconds
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,7 +56,7 @@ This should be updated to make use of standard fixture mechanisms:
 | 
			
		|||
        session.close()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
You can consult `funcarg comparision section in the docs <https://docs.pytest.org/en/latest/funcarg_compare.html>`_ for
 | 
			
		||||
You can consult `funcarg comparison section in the docs <https://docs.pytest.org/en/latest/funcarg_compare.html>`_ for
 | 
			
		||||
more information.
 | 
			
		||||
 | 
			
		||||
This has been documented as deprecated for years, but only now we are actually emitting deprecation warnings.
 | 
			
		||||
| 
						 | 
				
			
			@ -68,7 +68,7 @@ Using ``Class`` in custom Collectors
 | 
			
		|||
.. deprecated:: 3.9
 | 
			
		||||
 | 
			
		||||
Using objects named ``"Class"`` as a way to customize the type of nodes that are collected in ``Collector``
 | 
			
		||||
subclasses has been deprecated. Users instead should use ``pytest_collect_make_item`` to customize node types during
 | 
			
		||||
subclasses has been deprecated. Users instead should use ``pytest_pycollect_makeitem`` to customize node types during
 | 
			
		||||
collection.
 | 
			
		||||
 | 
			
		||||
This issue should affect only advanced plugins who create new collection types, so if you see this warning
 | 
			
		||||
| 
						 | 
				
			
			@ -304,7 +304,7 @@ This form of test function doesn't support fixtures properly, and users should s
 | 
			
		|||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    @pytest.mark.parametrize("x, y", [(2, 4), (3, 9)])
 | 
			
		||||
    def test_squared():
 | 
			
		||||
    def test_squared(x, y):
 | 
			
		||||
        assert x ** x == y
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -574,7 +574,7 @@ We can run this::
 | 
			
		|||
    file $REGENDOC_TMPDIR/b/test_error.py, line 1
 | 
			
		||||
      def test_root(db):  # no db here, will error out
 | 
			
		||||
    E       fixture 'db' not found
 | 
			
		||||
    >       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_property, record_xml_attribute, record_xml_property, recwarn, tmpdir, tmpdir_factory
 | 
			
		||||
    >       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_property, record_xml_attribute, record_xml_property, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
 | 
			
		||||
    >       use 'pytest --fixtures [testpath]' for help on them.
 | 
			
		||||
 | 
			
		||||
    $REGENDOC_TMPDIR/b/test_error.py:1
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,16 +31,37 @@ created in the `base temporary directory`_.
 | 
			
		|||
        p = d / "hello.txt"
 | 
			
		||||
        p.write_text(CONTENT)
 | 
			
		||||
        assert p.read_text() == CONTENT
 | 
			
		||||
        assert len(tmpdir.listdir()) == 1
 | 
			
		||||
        assert len(list(tmp_path.iterdir())) == 1
 | 
			
		||||
        assert 0
 | 
			
		||||
 | 
			
		||||
Running this would result in a passed test except for the last
 | 
			
		||||
``assert 0`` line which we use to look at values::
 | 
			
		||||
 | 
			
		||||
    $ pytest test_tmp_path.py
 | 
			
		||||
    ... #fill fom regendoc
 | 
			
		||||
    =========================== 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 1 item
 | 
			
		||||
 | 
			
		||||
    test_tmp_path.py F                                                   [100%]
 | 
			
		||||
 | 
			
		||||
    ================================= FAILURES =================================
 | 
			
		||||
    _____________________________ test_create_file _____________________________
 | 
			
		||||
 | 
			
		||||
    tmp_path = PosixPath('PYTEST_TMPDIR/test_create_file0')
 | 
			
		||||
 | 
			
		||||
        def test_create_file(tmp_path):
 | 
			
		||||
            d = tmp_path / "sub"
 | 
			
		||||
            d.mkdir()
 | 
			
		||||
            p = d / "hello.txt"
 | 
			
		||||
            p.write_text(CONTENT)
 | 
			
		||||
            assert p.read_text() == CONTENT
 | 
			
		||||
            assert len(list(tmp_path.iterdir())) == 1
 | 
			
		||||
    >       assert 0
 | 
			
		||||
    E       assert 0
 | 
			
		||||
 | 
			
		||||
    test_tmp_path.py:13: AssertionError
 | 
			
		||||
    ========================= 1 failed in 0.12 seconds =========================
 | 
			
		||||
 | 
			
		||||
The ``tmp_path_factory`` fixture
 | 
			
		||||
--------------------------------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -269,6 +269,7 @@ To get a list of the slowest 10 test durations::
 | 
			
		|||
 | 
			
		||||
    pytest --durations=10
 | 
			
		||||
 | 
			
		||||
By default, pytest will not show test durations that are too small (<0.01s) unless ``-vv`` is passed on the command-line.
 | 
			
		||||
 | 
			
		||||
Creating JUnitXML format files
 | 
			
		||||
----------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,60 +75,6 @@ Both ``-W`` command-line option and ``filterwarnings`` ini option are based on P
 | 
			
		|||
`-W option`_ and `warnings.simplefilter`_, so please refer to those sections in the Python
 | 
			
		||||
documentation for other examples and advanced usage.
 | 
			
		||||
 | 
			
		||||
Disabling warning summary
 | 
			
		||||
-------------------------
 | 
			
		||||
 | 
			
		||||
Although not recommended, you can use the ``--disable-warnings`` command-line option to suppress the
 | 
			
		||||
warning summary entirely from the test run output.
 | 
			
		||||
 | 
			
		||||
Disabling warning capture entirely
 | 
			
		||||
----------------------------------
 | 
			
		||||
 | 
			
		||||
This plugin is enabled by default but can be disabled entirely in your ``pytest.ini`` file with:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: ini
 | 
			
		||||
 | 
			
		||||
        [pytest]
 | 
			
		||||
        addopts = -p no:warnings
 | 
			
		||||
 | 
			
		||||
Or passing ``-p no:warnings`` in the command-line. This might be useful if your test suites handles warnings
 | 
			
		||||
using an external system.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. _`deprecation-warnings`:
 | 
			
		||||
 | 
			
		||||
DeprecationWarning and PendingDeprecationWarning
 | 
			
		||||
------------------------------------------------
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 3.8
 | 
			
		||||
.. versionchanged:: 3.9
 | 
			
		||||
 | 
			
		||||
By default pytest will display ``DeprecationWarning`` and ``PendingDeprecationWarning``.
 | 
			
		||||
 | 
			
		||||
Sometimes it is useful to hide some specific deprecation warnings that happen in code that you have no control over
 | 
			
		||||
(such as third-party libraries), in which case you might use the standard warning filters options (ini or marks).
 | 
			
		||||
For example:
 | 
			
		||||
 | 
			
		||||
.. code-block:: ini
 | 
			
		||||
 | 
			
		||||
    [pytest]
 | 
			
		||||
    filterwarnings =
 | 
			
		||||
        ignore:.*U.*mode is deprecated:DeprecationWarning
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
    If warnings are configured at the interpreter level, using
 | 
			
		||||
    the `PYTHONWARNINGS <https://docs.python.org/3/using/cmdline.html#envvar-PYTHONWARNINGS>`_ environment variable or the
 | 
			
		||||
    ``-W`` command-line option, pytest will not configure any filters by default.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
    This feature makes pytest more compliant with `PEP-0506 <https://www.python.org/dev/peps/pep-0565/#recommended-filter-settings-for-test-runners>`_ which suggests that those warnings should
 | 
			
		||||
    be shown by default by test runners, but pytest doesn't follow ``PEP-0506`` completely because resetting all
 | 
			
		||||
    warning filters like suggested in the PEP will break existing test suites that configure warning filters themselves
 | 
			
		||||
    by calling ``warnings.simplefilter`` (see issue `#2430 <https://github.com/pytest-dev/pytest/issues/2430>`_
 | 
			
		||||
    for an example of that).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. _`filterwarnings`:
 | 
			
		||||
 | 
			
		||||
``@pytest.mark.filterwarnings``
 | 
			
		||||
| 
						 | 
				
			
			@ -167,24 +113,6 @@ decorator or to all tests in a module by setting the ``pytestmark`` variable:
 | 
			
		|||
    pytestmark = pytest.mark.filterwarnings("error")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
    Except for these features, pytest does not change the python warning filter; it only captures
 | 
			
		||||
    and displays the warnings which are issued with respect to the currently configured filter,
 | 
			
		||||
    including changes to the filter made by test functions or by the system under test.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
    ``DeprecationWarning`` and ``PendingDeprecationWarning`` are hidden by the standard library
 | 
			
		||||
    by default so you have to explicitly configure them to be displayed in your ``pytest.ini``:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: ini
 | 
			
		||||
 | 
			
		||||
        [pytest]
 | 
			
		||||
        filterwarnings =
 | 
			
		||||
            once::DeprecationWarning
 | 
			
		||||
            once::PendingDeprecationWarning
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
*Credits go to Florian Schulze for the reference implementation in the* `pytest-warnings`_
 | 
			
		||||
*plugin.*
 | 
			
		||||
| 
						 | 
				
			
			@ -193,6 +121,102 @@ decorator or to all tests in a module by setting the ``pytestmark`` variable:
 | 
			
		|||
.. _warnings.simplefilter: https://docs.python.org/3/library/warnings.html#warnings.simplefilter
 | 
			
		||||
.. _`pytest-warnings`: https://github.com/fschulze/pytest-warnings
 | 
			
		||||
 | 
			
		||||
Disabling warnings summary
 | 
			
		||||
--------------------------
 | 
			
		||||
 | 
			
		||||
Although not recommended, you can use the ``--disable-warnings`` command-line option to suppress the
 | 
			
		||||
warning summary entirely from the test run output.
 | 
			
		||||
 | 
			
		||||
Disabling warning capture entirely
 | 
			
		||||
----------------------------------
 | 
			
		||||
 | 
			
		||||
This plugin is enabled by default but can be disabled entirely in your ``pytest.ini`` file with:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: ini
 | 
			
		||||
 | 
			
		||||
        [pytest]
 | 
			
		||||
        addopts = -p no:warnings
 | 
			
		||||
 | 
			
		||||
Or passing ``-p no:warnings`` in the command-line. This might be useful if your test suites handles warnings
 | 
			
		||||
using an external system.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. _`deprecation-warnings`:
 | 
			
		||||
 | 
			
		||||
DeprecationWarning and PendingDeprecationWarning
 | 
			
		||||
------------------------------------------------
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 3.8
 | 
			
		||||
.. versionchanged:: 3.9
 | 
			
		||||
 | 
			
		||||
By default pytest will display ``DeprecationWarning`` and ``PendingDeprecationWarning`` warnings from
 | 
			
		||||
user code and third-party libraries, as recommended by `PEP-0506 <https://www.python.org/dev/peps/pep-0565>`_.
 | 
			
		||||
This helps users keep their code modern and avoid breakages when deprecated warnings are effectively removed.
 | 
			
		||||
 | 
			
		||||
Sometimes it is useful to hide some specific deprecation warnings that happen in code that you have no control over
 | 
			
		||||
(such as third-party libraries), in which case you might use the warning filters options (ini or marks) to ignore
 | 
			
		||||
those warnings.
 | 
			
		||||
 | 
			
		||||
For example:
 | 
			
		||||
 | 
			
		||||
.. code-block:: ini
 | 
			
		||||
 | 
			
		||||
    [pytest]
 | 
			
		||||
    filterwarnings =
 | 
			
		||||
        ignore:.*U.*mode is deprecated:DeprecationWarning
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
This will ignore all warnings of type ``DeprecationWarning`` where the start of the message matches
 | 
			
		||||
the regular expression ``".*U.*mode is deprecated"``.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
    If warnings are configured at the interpreter level, using
 | 
			
		||||
    the `PYTHONWARNINGS <https://docs.python.org/3/using/cmdline.html#envvar-PYTHONWARNINGS>`_ environment variable or the
 | 
			
		||||
    ``-W`` command-line option, pytest will not configure any filters by default.
 | 
			
		||||
 | 
			
		||||
    Also pytest doesn't follow ``PEP-0506`` suggestion of resetting all warning filters because
 | 
			
		||||
    it might break test suites that configure warning filters themselves
 | 
			
		||||
    by calling ``warnings.simplefilter`` (see issue `#2430 <https://github.com/pytest-dev/pytest/issues/2430>`_
 | 
			
		||||
    for an example of that).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. _`ensuring a function triggers a deprecation warning`:
 | 
			
		||||
 | 
			
		||||
.. _ensuring_function_triggers:
 | 
			
		||||
 | 
			
		||||
Ensuring code triggers a deprecation warning
 | 
			
		||||
--------------------------------------------
 | 
			
		||||
 | 
			
		||||
You can also call a global helper for checking
 | 
			
		||||
that a certain function call triggers a ``DeprecationWarning`` or
 | 
			
		||||
``PendingDeprecationWarning``::
 | 
			
		||||
 | 
			
		||||
    import pytest
 | 
			
		||||
 | 
			
		||||
    def test_global():
 | 
			
		||||
        pytest.deprecated_call(myfunction, 17)
 | 
			
		||||
 | 
			
		||||
By default, ``DeprecationWarning`` and ``PendingDeprecationWarning`` will not be
 | 
			
		||||
caught when using ``pytest.warns`` or ``recwarn`` because default Python warnings filters hide
 | 
			
		||||
them. If you wish to record them in your own code, use the
 | 
			
		||||
command ``warnings.simplefilter('always')``::
 | 
			
		||||
 | 
			
		||||
    import warnings
 | 
			
		||||
    import pytest
 | 
			
		||||
 | 
			
		||||
    def test_deprecation(recwarn):
 | 
			
		||||
        warnings.simplefilter('always')
 | 
			
		||||
        warnings.warn("deprecated", DeprecationWarning)
 | 
			
		||||
        assert len(recwarn) == 1
 | 
			
		||||
        assert recwarn.pop(DeprecationWarning)
 | 
			
		||||
 | 
			
		||||
You can also use it as a contextmanager::
 | 
			
		||||
 | 
			
		||||
    def test_global():
 | 
			
		||||
        with pytest.deprecated_call():
 | 
			
		||||
            myobject.deprecated_method()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. _`asserting warnings`:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -299,43 +323,6 @@ warnings, or index into it to get a particular recorded warning.
 | 
			
		|||
 | 
			
		||||
Full API: :class:`WarningsRecorder`.
 | 
			
		||||
 | 
			
		||||
.. _`ensuring a function triggers a deprecation warning`:
 | 
			
		||||
 | 
			
		||||
.. _ensuring_function_triggers:
 | 
			
		||||
 | 
			
		||||
Ensuring a function triggers a deprecation warning
 | 
			
		||||
-------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
You can also call a global helper for checking
 | 
			
		||||
that a certain function call triggers a ``DeprecationWarning`` or
 | 
			
		||||
``PendingDeprecationWarning``::
 | 
			
		||||
 | 
			
		||||
    import pytest
 | 
			
		||||
 | 
			
		||||
    def test_global():
 | 
			
		||||
        pytest.deprecated_call(myfunction, 17)
 | 
			
		||||
 | 
			
		||||
By default, ``DeprecationWarning`` and ``PendingDeprecationWarning`` will not be
 | 
			
		||||
caught when using ``pytest.warns`` or ``recwarn`` because default Python warnings filters hide
 | 
			
		||||
them. If you wish to record them in your own code, use the
 | 
			
		||||
command ``warnings.simplefilter('always')``::
 | 
			
		||||
 | 
			
		||||
    import warnings
 | 
			
		||||
    import pytest
 | 
			
		||||
 | 
			
		||||
    def test_deprecation(recwarn):
 | 
			
		||||
        warnings.simplefilter('always')
 | 
			
		||||
        warnings.warn("deprecated", DeprecationWarning)
 | 
			
		||||
        assert len(recwarn) == 1
 | 
			
		||||
        assert recwarn.pop(DeprecationWarning)
 | 
			
		||||
 | 
			
		||||
You can also use it as a contextmanager::
 | 
			
		||||
 | 
			
		||||
    def test_global():
 | 
			
		||||
        with pytest.deprecated_call():
 | 
			
		||||
            myobject.deprecated_method()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. _internal-warnings:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -420,9 +420,21 @@ additionally it is possible to copy examples for a example folder before running
 | 
			
		|||
    ============================= warnings summary =============================
 | 
			
		||||
    $REGENDOC_TMPDIR/test_example.py:4: PytestExperimentalApiWarning: testdir.copy_example is an experimental api that may change over time
 | 
			
		||||
      testdir.copy_example("test_example.py")
 | 
			
		||||
    $PYTHON_PREFIX/lib/python3.6/site-packages/_pytest/compat.py:321: RemovedInPytest4Warning: usage of Session.Class is deprecated, please use pytest.Class instead
 | 
			
		||||
      return getattr(object, name, default)
 | 
			
		||||
    $PYTHON_PREFIX/lib/python3.6/site-packages/_pytest/compat.py:321: RemovedInPytest4Warning: usage of Session.File is deprecated, please use pytest.File instead
 | 
			
		||||
      return getattr(object, name, default)
 | 
			
		||||
    $PYTHON_PREFIX/lib/python3.6/site-packages/_pytest/compat.py:321: RemovedInPytest4Warning: usage of Session.Function is deprecated, please use pytest.Function instead
 | 
			
		||||
      return getattr(object, name, default)
 | 
			
		||||
    $PYTHON_PREFIX/lib/python3.6/site-packages/_pytest/compat.py:321: RemovedInPytest4Warning: usage of Session.Instance is deprecated, please use pytest.Instance instead
 | 
			
		||||
      return getattr(object, name, default)
 | 
			
		||||
    $PYTHON_PREFIX/lib/python3.6/site-packages/_pytest/compat.py:321: RemovedInPytest4Warning: usage of Session.Item is deprecated, please use pytest.Item instead
 | 
			
		||||
      return getattr(object, name, default)
 | 
			
		||||
    $PYTHON_PREFIX/lib/python3.6/site-packages/_pytest/compat.py:321: RemovedInPytest4Warning: usage of Session.Module is deprecated, please use pytest.Module instead
 | 
			
		||||
      return getattr(object, name, default)
 | 
			
		||||
 | 
			
		||||
    -- Docs: https://docs.pytest.org/en/latest/warnings.html
 | 
			
		||||
    =================== 2 passed, 1 warnings in 0.12 seconds ===================
 | 
			
		||||
    =================== 2 passed, 7 warnings in 0.12 seconds ===================
 | 
			
		||||
 | 
			
		||||
For more information about the result object that ``runpytest()`` returns, and
 | 
			
		||||
the methods that it provides please check out the :py:class:`RunResult
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
[build-system]
 | 
			
		||||
requires = [
 | 
			
		||||
  # sync with setup.py until we discard non-pep-517/518
 | 
			
		||||
  "setuptools>=30.3",
 | 
			
		||||
  "setuptools>=40.0",
 | 
			
		||||
  "setuptools-scm",
 | 
			
		||||
  "wheel",
 | 
			
		||||
]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,7 @@
 | 
			
		|||
name = pytest
 | 
			
		||||
description = pytest: simple powerful testing with Python
 | 
			
		||||
long_description = file: README.rst
 | 
			
		||||
url = "https://docs.pytest.org/en/latest/"
 | 
			
		||||
url = https://docs.pytest.org/en/latest/
 | 
			
		||||
project_urls =
 | 
			
		||||
    Source=https://github.com/pytest-dev/pytest
 | 
			
		||||
    Tracker=https://github.com/pytest-dev/pytest/issues
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								setup.py
								
								
								
								
							
							
						
						
									
										2
									
								
								setup.py
								
								
								
								
							| 
						 | 
				
			
			@ -26,7 +26,7 @@ if "_PYTEST_SETUP_SKIP_PLUGGY_DEP" not in os.environ:
 | 
			
		|||
def main():
 | 
			
		||||
    setup(
 | 
			
		||||
        use_scm_version={"write_to": "src/_pytest/_version.py"},
 | 
			
		||||
        setup_requires=["setuptools-scm", "setuptools>=30.3"],
 | 
			
		||||
        setup_requires=["setuptools-scm", "setuptools>=40.0"],
 | 
			
		||||
        package_dir={"": "src"},
 | 
			
		||||
        install_requires=INSTALL_REQUIRES,
 | 
			
		||||
    )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -399,7 +399,7 @@ def _rewrite_test(config, fn):
 | 
			
		|||
            finally:
 | 
			
		||||
                del state._indecode
 | 
			
		||||
    try:
 | 
			
		||||
        tree = ast.parse(source)
 | 
			
		||||
        tree = ast.parse(source, filename=fn.strpath)
 | 
			
		||||
    except SyntaxError:
 | 
			
		||||
        # Let this pop up again in the real import.
 | 
			
		||||
        state.trace("failed to parse: %r" % (fn,))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,12 @@
 | 
			
		|||
""" interactive debugging with PDB, the Python Debugger. """
 | 
			
		||||
from __future__ import absolute_import, division, print_function
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
import pdb
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
from doctest import UnexpectedException
 | 
			
		||||
 | 
			
		||||
from _pytest import outcomes
 | 
			
		||||
from _pytest.config import hookimpl
 | 
			
		||||
 | 
			
		||||
try:
 | 
			
		||||
| 
						 | 
				
			
			@ -109,9 +111,6 @@ class PdbInvoke(object):
 | 
			
		|||
        _enter_pdb(node, call.excinfo, report)
 | 
			
		||||
 | 
			
		||||
    def pytest_internalerror(self, excrepr, excinfo):
 | 
			
		||||
        for line in str(excrepr).split("\n"):
 | 
			
		||||
            sys.stderr.write("INTERNALERROR> %s\n" % line)
 | 
			
		||||
            sys.stderr.flush()
 | 
			
		||||
        tb = _postmortem_traceback(excinfo)
 | 
			
		||||
        post_mortem(tb)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -164,8 +163,9 @@ def _enter_pdb(node, excinfo, rep):
 | 
			
		|||
    rep.toterminal(tw)
 | 
			
		||||
    tw.sep(">", "entering PDB")
 | 
			
		||||
    tb = _postmortem_traceback(excinfo)
 | 
			
		||||
    post_mortem(tb)
 | 
			
		||||
    rep._pdbshown = True
 | 
			
		||||
    if post_mortem(tb):
 | 
			
		||||
        outcomes.exit("Quitting debugger")
 | 
			
		||||
    return rep
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -196,3 +196,4 @@ def post_mortem(t):
 | 
			
		|||
    p = Pdb()
 | 
			
		||||
    p.reset()
 | 
			
		||||
    p.interaction(None, t)
 | 
			
		||||
    return p.quitting
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1020,7 +1020,7 @@ class FixtureFunctionMarker(object):
 | 
			
		|||
 | 
			
		||||
    def __call__(self, function):
 | 
			
		||||
        if isclass(function):
 | 
			
		||||
            raise ValueError("class fixtures not supported (may be in the future)")
 | 
			
		||||
            raise ValueError("class fixtures not supported (maybe in the future)")
 | 
			
		||||
 | 
			
		||||
        if getattr(function, "_pytestfixturefunction", False):
 | 
			
		||||
            raise ValueError(
 | 
			
		||||
| 
						 | 
				
			
			@ -1371,8 +1371,7 @@ class FixtureManager(object):
 | 
			
		|||
            fixturedefs = self._arg2fixturedefs[argname]
 | 
			
		||||
        except KeyError:
 | 
			
		||||
            return None
 | 
			
		||||
        else:
 | 
			
		||||
            return tuple(self._matchfactories(fixturedefs, nodeid))
 | 
			
		||||
        return tuple(self._matchfactories(fixturedefs, nodeid))
 | 
			
		||||
 | 
			
		||||
    def _matchfactories(self, fixturedefs, nodeid):
 | 
			
		||||
        for fixturedef in fixturedefs:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -221,12 +221,14 @@ class _NodeReporter(object):
 | 
			
		|||
        else:
 | 
			
		||||
            filename, lineno, skipreason = report.longrepr
 | 
			
		||||
            if skipreason.startswith("Skipped: "):
 | 
			
		||||
                skipreason = bin_xml_escape(skipreason[9:])
 | 
			
		||||
                skipreason = skipreason[9:]
 | 
			
		||||
            details = "%s:%s: %s" % (filename, lineno, skipreason)
 | 
			
		||||
 | 
			
		||||
            self.append(
 | 
			
		||||
                Junit.skipped(
 | 
			
		||||
                    "%s:%s: %s" % (filename, lineno, skipreason),
 | 
			
		||||
                    bin_xml_escape(details),
 | 
			
		||||
                    type="pytest.skip",
 | 
			
		||||
                    message=skipreason,
 | 
			
		||||
                    message=bin_xml_escape(skipreason),
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            self.write_captured_output(report)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -279,7 +279,7 @@ class LogCaptureFixture(object):
 | 
			
		|||
        Unlike 'records', which contains the format string and parameters for interpolation, log messages in this list
 | 
			
		||||
        are all interpolated.
 | 
			
		||||
        Unlike 'text', which contains the output from the handler, log messages in this list are unadorned with
 | 
			
		||||
        levels, timestamps, etc, making exact comparisions more reliable.
 | 
			
		||||
        levels, timestamps, etc, making exact comparisons more reliable.
 | 
			
		||||
 | 
			
		||||
        Note that traceback or stack info (from :func:`logging.exception` or the `exc_info` or `stack_info` arguments
 | 
			
		||||
        to the logging functions) is not included, as this is added by the formatter in the handler.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -570,9 +570,7 @@ class Session(nodes.FSCollector):
 | 
			
		|||
        return True
 | 
			
		||||
 | 
			
		||||
    def _tryconvertpyarg(self, x):
 | 
			
		||||
        """Convert a dotted module name to path.
 | 
			
		||||
 | 
			
		||||
        """
 | 
			
		||||
        """Convert a dotted module name to path."""
 | 
			
		||||
        try:
 | 
			
		||||
            with _patched_find_module():
 | 
			
		||||
                loader = pkgutil.find_loader(x)
 | 
			
		||||
| 
						 | 
				
			
			@ -604,8 +602,7 @@ class Session(nodes.FSCollector):
 | 
			
		|||
                raise UsageError(
 | 
			
		||||
                    "file or package not found: " + arg + " (missing __init__.py?)"
 | 
			
		||||
                )
 | 
			
		||||
            else:
 | 
			
		||||
                raise UsageError("file not found: " + arg)
 | 
			
		||||
            raise UsageError("file not found: " + arg)
 | 
			
		||||
        parts[0] = path
 | 
			
		||||
        return parts
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,6 +100,26 @@ else:
 | 
			
		|||
    _max = max
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _force_symlink(root, target, link_to):
 | 
			
		||||
    """helper to create the current symlink
 | 
			
		||||
 | 
			
		||||
    its full of race conditions that are reasonably ok to ignore
 | 
			
		||||
    for the contex of best effort linking to the latest testrun
 | 
			
		||||
 | 
			
		||||
    the presumption being thatin case of much parallelism
 | 
			
		||||
    the inaccuracy is going to be acceptable
 | 
			
		||||
    """
 | 
			
		||||
    current_symlink = root.joinpath(target)
 | 
			
		||||
    try:
 | 
			
		||||
        current_symlink.unlink()
 | 
			
		||||
    except OSError:
 | 
			
		||||
        pass
 | 
			
		||||
    try:
 | 
			
		||||
        current_symlink.symlink_to(link_to)
 | 
			
		||||
    except Exception:
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def make_numbered_dir(root, prefix):
 | 
			
		||||
    """create a directory with a increased number as suffix for the given prefix"""
 | 
			
		||||
    for i in range(10):
 | 
			
		||||
| 
						 | 
				
			
			@ -112,6 +132,7 @@ def make_numbered_dir(root, prefix):
 | 
			
		|||
        except Exception:
 | 
			
		||||
            pass
 | 
			
		||||
        else:
 | 
			
		||||
            _force_symlink(root, prefix + "current", new_path)
 | 
			
		||||
            return new_path
 | 
			
		||||
    else:
 | 
			
		||||
        raise EnvironmentError(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@ from weakref import WeakKeyDictionary
 | 
			
		|||
 | 
			
		||||
from _pytest.capture import MultiCapture, SysCapture
 | 
			
		||||
from _pytest._code import Source
 | 
			
		||||
from _pytest.main import Session, EXIT_OK
 | 
			
		||||
from _pytest.main import Session, EXIT_INTERRUPTED, EXIT_OK
 | 
			
		||||
from _pytest.assertion.rewrite import AssertionRewritingHook
 | 
			
		||||
from _pytest.pathlib import Path
 | 
			
		||||
from _pytest.compat import safe_str
 | 
			
		||||
| 
						 | 
				
			
			@ -857,7 +857,7 @@ class Testdir(object):
 | 
			
		|||
 | 
			
		||||
            # typically we reraise keyboard interrupts from the child run
 | 
			
		||||
            # because it's our user requesting interruption of the testing
 | 
			
		||||
            if ret == 2 and not kwargs.get("no_reraise_ctrlc"):
 | 
			
		||||
            if ret == EXIT_INTERRUPTED and not kwargs.get("no_reraise_ctrlc"):
 | 
			
		||||
                calls = reprec.getcalls("pytest_keyboard_interrupt")
 | 
			
		||||
                if calls and calls[-1].excinfo.type == KeyboardInterrupt:
 | 
			
		||||
                    raise KeyboardInterrupt()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,7 @@ def pytest_addoption(parser):
 | 
			
		|||
 | 
			
		||||
def pytest_terminal_summary(terminalreporter):
 | 
			
		||||
    durations = terminalreporter.config.option.durations
 | 
			
		||||
    verbose = terminalreporter.config.getvalue("verbose")
 | 
			
		||||
    if durations is None:
 | 
			
		||||
        return
 | 
			
		||||
    tr = terminalreporter
 | 
			
		||||
| 
						 | 
				
			
			@ -49,6 +50,10 @@ def pytest_terminal_summary(terminalreporter):
 | 
			
		|||
        dlist = dlist[:durations]
 | 
			
		||||
 | 
			
		||||
    for rep in dlist:
 | 
			
		||||
        if verbose < 2 and rep.duration < 0.005:
 | 
			
		||||
            tr.write_line("")
 | 
			
		||||
            tr.write_line("(0.00 durations hidden.  Use -vv to show these durations.)")
 | 
			
		||||
            break
 | 
			
		||||
        nodeid = rep.nodeid.replace("::()::", "::")
 | 
			
		||||
        tr.write_line("%02.2fs %-8s %s" % (rep.duration, rep.when, nodeid))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -263,7 +263,7 @@ class TerminalReporter(object):
 | 
			
		|||
        char = {"xfailed": "x", "skipped": "s"}.get(char, char)
 | 
			
		||||
        return char in self.reportchars
 | 
			
		||||
 | 
			
		||||
    def write_fspath_result(self, nodeid, res):
 | 
			
		||||
    def write_fspath_result(self, nodeid, res, **markup):
 | 
			
		||||
        fspath = self.config.rootdir.join(nodeid.split("::")[0])
 | 
			
		||||
        if fspath != self.currentfspath:
 | 
			
		||||
            if self.currentfspath is not None and self._show_progress_info:
 | 
			
		||||
| 
						 | 
				
			
			@ -272,7 +272,7 @@ class TerminalReporter(object):
 | 
			
		|||
            fspath = self.startdir.bestrelpath(fspath)
 | 
			
		||||
            self._tw.line()
 | 
			
		||||
            self._tw.write(fspath + " ")
 | 
			
		||||
        self._tw.write(res)
 | 
			
		||||
        self._tw.write(res, **markup)
 | 
			
		||||
 | 
			
		||||
    def write_ensure_prefix(self, prefix, extra="", **kwargs):
 | 
			
		||||
        if self.currentfspath != prefix:
 | 
			
		||||
| 
						 | 
				
			
			@ -386,22 +386,22 @@ class TerminalReporter(object):
 | 
			
		|||
            # probably passed setup/teardown
 | 
			
		||||
            return
 | 
			
		||||
        running_xdist = hasattr(rep, "node")
 | 
			
		||||
        if markup is None:
 | 
			
		||||
            if rep.passed:
 | 
			
		||||
                markup = {"green": True}
 | 
			
		||||
            elif rep.failed:
 | 
			
		||||
                markup = {"red": True}
 | 
			
		||||
            elif rep.skipped:
 | 
			
		||||
                markup = {"yellow": True}
 | 
			
		||||
            else:
 | 
			
		||||
                markup = {}
 | 
			
		||||
        if self.verbosity <= 0:
 | 
			
		||||
            if not running_xdist and self.showfspath:
 | 
			
		||||
                self.write_fspath_result(rep.nodeid, letter)
 | 
			
		||||
                self.write_fspath_result(rep.nodeid, letter, **markup)
 | 
			
		||||
            else:
 | 
			
		||||
                self._tw.write(letter)
 | 
			
		||||
                self._tw.write(letter, **markup)
 | 
			
		||||
        else:
 | 
			
		||||
            self._progress_nodeids_reported.add(rep.nodeid)
 | 
			
		||||
            if markup is None:
 | 
			
		||||
                if rep.passed:
 | 
			
		||||
                    markup = {"green": True}
 | 
			
		||||
                elif rep.failed:
 | 
			
		||||
                    markup = {"red": True}
 | 
			
		||||
                elif rep.skipped:
 | 
			
		||||
                    markup = {"yellow": True}
 | 
			
		||||
                else:
 | 
			
		||||
                    markup = {}
 | 
			
		||||
            line = self._locationline(rep.nodeid, *rep.location)
 | 
			
		||||
            if not running_xdist:
 | 
			
		||||
                self.write_ensure_prefix(line, word, **markup)
 | 
			
		||||
| 
						 | 
				
			
			@ -676,7 +676,9 @@ class TerminalReporter(object):
 | 
			
		|||
 | 
			
		||||
        if fspath:
 | 
			
		||||
            res = mkrel(nodeid).replace("::()", "")  # parens-normalization
 | 
			
		||||
            if nodeid.split("::")[0] != fspath.replace("\\", nodes.SEP):
 | 
			
		||||
            if self.verbosity >= 2 and nodeid.split("::")[0] != fspath.replace(
 | 
			
		||||
                "\\", nodes.SEP
 | 
			
		||||
            ):
 | 
			
		||||
                res += " <- " + self.startdir.bestrelpath(fspath)
 | 
			
		||||
        else:
 | 
			
		||||
            res = "[location]"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,6 +12,13 @@ import pytest
 | 
			
		|||
from _pytest.main import EXIT_NOTESTSCOLLECTED, EXIT_USAGEERROR
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def prepend_pythonpath(*dirs):
 | 
			
		||||
    cur = os.getenv("PYTHONPATH")
 | 
			
		||||
    if cur:
 | 
			
		||||
        dirs += (cur,)
 | 
			
		||||
    return os.pathsep.join(str(p) for p in dirs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestGeneralUsage(object):
 | 
			
		||||
    def test_config_error(self, testdir):
 | 
			
		||||
        testdir.copy_example("conftest_usageerror/conftest.py")
 | 
			
		||||
| 
						 | 
				
			
			@ -590,14 +597,8 @@ class TestInvocationVariants(object):
 | 
			
		|||
        assert result.ret == 0
 | 
			
		||||
        result.stdout.fnmatch_lines(["*1 passed*"])
 | 
			
		||||
 | 
			
		||||
        def join_pythonpath(what):
 | 
			
		||||
            cur = os.environ.get("PYTHONPATH")
 | 
			
		||||
            if cur:
 | 
			
		||||
                return str(what) + os.pathsep + cur
 | 
			
		||||
            return what
 | 
			
		||||
 | 
			
		||||
        empty_package = testdir.mkpydir("empty_package")
 | 
			
		||||
        monkeypatch.setenv("PYTHONPATH", str(join_pythonpath(empty_package)))
 | 
			
		||||
        monkeypatch.setenv("PYTHONPATH", str(empty_package), prepend=os.pathsep)
 | 
			
		||||
        # the path which is not a package raises a warning on pypy;
 | 
			
		||||
        # no idea why only pypy and not normal python warn about it here
 | 
			
		||||
        with warnings.catch_warnings():
 | 
			
		||||
| 
						 | 
				
			
			@ -606,7 +607,7 @@ class TestInvocationVariants(object):
 | 
			
		|||
        assert result.ret == 0
 | 
			
		||||
        result.stdout.fnmatch_lines(["*2 passed*"])
 | 
			
		||||
 | 
			
		||||
        monkeypatch.setenv("PYTHONPATH", str(join_pythonpath(testdir)))
 | 
			
		||||
        monkeypatch.setenv("PYTHONPATH", str(testdir), prepend=os.pathsep)
 | 
			
		||||
        result = testdir.runpytest("--pyargs", "tpkg.test_missing", syspathinsert=True)
 | 
			
		||||
        assert result.ret != 0
 | 
			
		||||
        result.stderr.fnmatch_lines(["*not*found*test_missing*"])
 | 
			
		||||
| 
						 | 
				
			
			@ -646,18 +647,13 @@ class TestInvocationVariants(object):
 | 
			
		|||
        #             ├── __init__.py
 | 
			
		||||
        #             └── test_world.py
 | 
			
		||||
 | 
			
		||||
        def join_pythonpath(*dirs):
 | 
			
		||||
            cur = os.environ.get("PYTHONPATH")
 | 
			
		||||
            if cur:
 | 
			
		||||
                dirs += (cur,)
 | 
			
		||||
            return os.pathsep.join(str(p) for p in dirs)
 | 
			
		||||
 | 
			
		||||
        monkeypatch.setenv("PYTHONPATH", join_pythonpath(*search_path))
 | 
			
		||||
        # NOTE: the different/reversed ordering is intentional here.
 | 
			
		||||
        monkeypatch.setenv("PYTHONPATH", prepend_pythonpath(*search_path))
 | 
			
		||||
        for p in search_path:
 | 
			
		||||
            monkeypatch.syspath_prepend(p)
 | 
			
		||||
 | 
			
		||||
        # mixed module and filenames:
 | 
			
		||||
        os.chdir("world")
 | 
			
		||||
        monkeypatch.chdir("world")
 | 
			
		||||
        result = testdir.runpytest("--pyargs", "-v", "ns_pkg.hello", "ns_pkg/world")
 | 
			
		||||
        assert result.ret == 0
 | 
			
		||||
        result.stdout.fnmatch_lines(
 | 
			
		||||
| 
						 | 
				
			
			@ -708,8 +704,6 @@ class TestInvocationVariants(object):
 | 
			
		|||
                pytest.skip(six.text_type(e.args[0]))
 | 
			
		||||
        monkeypatch.delenv("PYTHONDONTWRITEBYTECODE", raising=False)
 | 
			
		||||
 | 
			
		||||
        search_path = ["lib", os.path.join("local", "lib")]
 | 
			
		||||
 | 
			
		||||
        dirname = "lib"
 | 
			
		||||
        d = testdir.mkdir(dirname)
 | 
			
		||||
        foo = d.mkdir("foo")
 | 
			
		||||
| 
						 | 
				
			
			@ -742,13 +736,9 @@ class TestInvocationVariants(object):
 | 
			
		|||
        #             ├── conftest.py
 | 
			
		||||
        #             └── test_bar.py
 | 
			
		||||
 | 
			
		||||
        def join_pythonpath(*dirs):
 | 
			
		||||
            cur = os.getenv("PYTHONPATH")
 | 
			
		||||
            if cur:
 | 
			
		||||
                dirs += (cur,)
 | 
			
		||||
            return os.pathsep.join(str(p) for p in dirs)
 | 
			
		||||
 | 
			
		||||
        monkeypatch.setenv("PYTHONPATH", join_pythonpath(*search_path))
 | 
			
		||||
        # NOTE: the different/reversed ordering is intentional here.
 | 
			
		||||
        search_path = ["lib", os.path.join("local", "lib")]
 | 
			
		||||
        monkeypatch.setenv("PYTHONPATH", prepend_pythonpath(*search_path))
 | 
			
		||||
        for p in search_path:
 | 
			
		||||
            monkeypatch.syspath_prepend(p)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -760,16 +750,16 @@ class TestInvocationVariants(object):
 | 
			
		|||
        if hasattr(py.path.local, "mksymlinkto"):
 | 
			
		||||
            result.stdout.fnmatch_lines(
 | 
			
		||||
                [
 | 
			
		||||
                    "lib/foo/bar/test_bar.py::test_bar <- local/lib/foo/bar/test_bar.py PASSED*",
 | 
			
		||||
                    "lib/foo/bar/test_bar.py::test_other <- local/lib/foo/bar/test_bar.py PASSED*",
 | 
			
		||||
                    "lib/foo/bar/test_bar.py::test_bar PASSED*",
 | 
			
		||||
                    "lib/foo/bar/test_bar.py::test_other PASSED*",
 | 
			
		||||
                    "*2 passed*",
 | 
			
		||||
                ]
 | 
			
		||||
            )
 | 
			
		||||
        else:
 | 
			
		||||
            result.stdout.fnmatch_lines(
 | 
			
		||||
                [
 | 
			
		||||
                    "local/lib/foo/bar/test_bar.py::test_bar PASSED*",
 | 
			
		||||
                    "local/lib/foo/bar/test_bar.py::test_other PASSED*",
 | 
			
		||||
                    "*lib/foo/bar/test_bar.py::test_bar PASSED*",
 | 
			
		||||
                    "*lib/foo/bar/test_bar.py::test_other PASSED*",
 | 
			
		||||
                    "*2 passed*",
 | 
			
		||||
                ]
 | 
			
		||||
            )
 | 
			
		||||
| 
						 | 
				
			
			@ -846,7 +836,10 @@ class TestDurations(object):
 | 
			
		|||
        result = testdir.runpytest("--durations=10")
 | 
			
		||||
        assert result.ret == 0
 | 
			
		||||
        result.stdout.fnmatch_lines_random(
 | 
			
		||||
            ["*durations*", "*call*test_3*", "*call*test_2*", "*call*test_1*"]
 | 
			
		||||
            ["*durations*", "*call*test_3*", "*call*test_2*"]
 | 
			
		||||
        )
 | 
			
		||||
        result.stdout.fnmatch_lines(
 | 
			
		||||
            ["(0.00 durations hidden.  Use -vv to show these durations.)"]
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_calls_show_2(self, testdir):
 | 
			
		||||
| 
						 | 
				
			
			@ -860,6 +853,18 @@ class TestDurations(object):
 | 
			
		|||
        testdir.makepyfile(self.source)
 | 
			
		||||
        result = testdir.runpytest("--durations=0")
 | 
			
		||||
        assert result.ret == 0
 | 
			
		||||
        for x in "23":
 | 
			
		||||
            for y in ("call",):  # 'setup', 'call', 'teardown':
 | 
			
		||||
                for line in result.stdout.lines:
 | 
			
		||||
                    if ("test_%s" % x) in line and y in line:
 | 
			
		||||
                        break
 | 
			
		||||
                else:
 | 
			
		||||
                    raise AssertionError("not found {} {}".format(x, y))
 | 
			
		||||
 | 
			
		||||
    def test_calls_showall_verbose(self, testdir):
 | 
			
		||||
        testdir.makepyfile(self.source)
 | 
			
		||||
        result = testdir.runpytest("--durations=0", "-vv")
 | 
			
		||||
        assert result.ret == 0
 | 
			
		||||
        for x in "123":
 | 
			
		||||
            for y in ("call",):  # 'setup', 'call', 'teardown':
 | 
			
		||||
                for line in result.stdout.lines:
 | 
			
		||||
| 
						 | 
				
			
			@ -870,9 +875,9 @@ class TestDurations(object):
 | 
			
		|||
 | 
			
		||||
    def test_with_deselected(self, testdir):
 | 
			
		||||
        testdir.makepyfile(self.source)
 | 
			
		||||
        result = testdir.runpytest("--durations=2", "-k test_1")
 | 
			
		||||
        result = testdir.runpytest("--durations=2", "-k test_2")
 | 
			
		||||
        assert result.ret == 0
 | 
			
		||||
        result.stdout.fnmatch_lines(["*durations*", "*call*test_1*"])
 | 
			
		||||
        result.stdout.fnmatch_lines(["*durations*", "*call*test_2*"])
 | 
			
		||||
 | 
			
		||||
    def test_with_failing_collection(self, testdir):
 | 
			
		||||
        testdir.makepyfile(self.source)
 | 
			
		||||
| 
						 | 
				
			
			@ -892,13 +897,15 @@ class TestDurations(object):
 | 
			
		|||
 | 
			
		||||
class TestDurationWithFixture(object):
 | 
			
		||||
    source = """
 | 
			
		||||
        import pytest
 | 
			
		||||
        import time
 | 
			
		||||
        frag = 0.001
 | 
			
		||||
        def setup_function(func):
 | 
			
		||||
            time.sleep(frag * 3)
 | 
			
		||||
        def test_1():
 | 
			
		||||
            time.sleep(frag*2)
 | 
			
		||||
        def test_2():
 | 
			
		||||
        frag = 0.01
 | 
			
		||||
 | 
			
		||||
        @pytest.fixture
 | 
			
		||||
        def setup_fixt():
 | 
			
		||||
            time.sleep(frag)
 | 
			
		||||
 | 
			
		||||
        def test_1(setup_fixt):
 | 
			
		||||
            time.sleep(frag)
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -494,6 +494,12 @@ class TestRequestBasic(object):
 | 
			
		|||
        reason="this method of test doesn't work on pypy",
 | 
			
		||||
    )
 | 
			
		||||
    def test_request_garbage(self, testdir):
 | 
			
		||||
        try:
 | 
			
		||||
            import xdist  # noqa
 | 
			
		||||
        except ImportError:
 | 
			
		||||
            pass
 | 
			
		||||
        else:
 | 
			
		||||
            pytest.xfail("this test is flaky when executed with xdist")
 | 
			
		||||
        testdir.makepyfile(
 | 
			
		||||
            """
 | 
			
		||||
            import sys
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1222,3 +1222,19 @@ def test_set_suite_name(testdir, suite_name):
 | 
			
		|||
    assert result.ret == 0
 | 
			
		||||
    node = dom.find_first_by_tag("testsuite")
 | 
			
		||||
    node.assert_attr(name=expected)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_escaped_skipreason_issue3533(testdir):
 | 
			
		||||
    testdir.makepyfile(
 | 
			
		||||
        """
 | 
			
		||||
        import pytest
 | 
			
		||||
        @pytest.mark.skip(reason='1 <> 2')
 | 
			
		||||
        def test_skip():
 | 
			
		||||
            pass
 | 
			
		||||
    """
 | 
			
		||||
    )
 | 
			
		||||
    _, dom = runandparse(testdir)
 | 
			
		||||
    node = dom.find_first_by_tag("testcase")
 | 
			
		||||
    snode = node.find_first_by_tag("skipped")
 | 
			
		||||
    assert "1 <> 2" in snode.text
 | 
			
		||||
    snode.assert_attr(message="1 <> 2")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,8 @@ def custom_pdb_calls():
 | 
			
		|||
 | 
			
		||||
    # install dummy debugger class and track which methods were called on it
 | 
			
		||||
    class _CustomPdb(object):
 | 
			
		||||
        quitting = False
 | 
			
		||||
 | 
			
		||||
        def __init__(self, *args, **kwargs):
 | 
			
		||||
            called.append("init")
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -142,6 +144,9 @@ class TestPDB(object):
 | 
			
		|||
            def test_1():
 | 
			
		||||
                i = 0
 | 
			
		||||
                assert i == 1
 | 
			
		||||
 | 
			
		||||
            def test_not_called_due_to_quit():
 | 
			
		||||
                pass
 | 
			
		||||
        """
 | 
			
		||||
        )
 | 
			
		||||
        child = testdir.spawn_pytest("--pdb %s" % p1)
 | 
			
		||||
| 
						 | 
				
			
			@ -150,8 +155,9 @@ class TestPDB(object):
 | 
			
		|||
        child.expect("Pdb")
 | 
			
		||||
        child.sendeof()
 | 
			
		||||
        rest = child.read().decode("utf8")
 | 
			
		||||
        assert "1 failed" in rest
 | 
			
		||||
        assert "= 1 failed in" in rest
 | 
			
		||||
        assert "def test_1" not in rest
 | 
			
		||||
        assert "Exit: Quitting debugger" in rest
 | 
			
		||||
        self.flush(child)
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
| 
						 | 
				
			
			@ -321,7 +327,7 @@ class TestPDB(object):
 | 
			
		|||
        child = testdir.spawn_pytest("--pdb %s" % p1)
 | 
			
		||||
        # child.expect(".*import pytest.*")
 | 
			
		||||
        child.expect("Pdb")
 | 
			
		||||
        child.sendeof()
 | 
			
		||||
        child.sendline("c")
 | 
			
		||||
        child.expect("1 error")
 | 
			
		||||
        self.flush(child)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -334,8 +340,20 @@ class TestPDB(object):
 | 
			
		|||
        )
 | 
			
		||||
        p1 = testdir.makepyfile("def test_func(): pass")
 | 
			
		||||
        child = testdir.spawn_pytest("--pdb %s" % p1)
 | 
			
		||||
        # child.expect(".*import pytest.*")
 | 
			
		||||
        child.expect("Pdb")
 | 
			
		||||
 | 
			
		||||
        # INTERNALERROR is only displayed once via terminal reporter.
 | 
			
		||||
        assert (
 | 
			
		||||
            len(
 | 
			
		||||
                [
 | 
			
		||||
                    x
 | 
			
		||||
                    for x in child.before.decode().splitlines()
 | 
			
		||||
                    if x.startswith("INTERNALERROR> Traceback")
 | 
			
		||||
                ]
 | 
			
		||||
            )
 | 
			
		||||
            == 1
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        child.sendeof()
 | 
			
		||||
        self.flush(child)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -345,7 +363,7 @@ class TestPDB(object):
 | 
			
		|||
            import pytest
 | 
			
		||||
            def test_1():
 | 
			
		||||
                i = 0
 | 
			
		||||
                print ("hello17")
 | 
			
		||||
                print("hello17")
 | 
			
		||||
                pytest.set_trace()
 | 
			
		||||
                x = 3
 | 
			
		||||
        """
 | 
			
		||||
| 
						 | 
				
			
			@ -376,6 +394,7 @@ class TestPDB(object):
 | 
			
		|||
        rest = child.read().decode("utf8")
 | 
			
		||||
        assert "1 failed" in rest
 | 
			
		||||
        assert "reading from stdin while output" not in rest
 | 
			
		||||
        assert "BdbQuit" in rest
 | 
			
		||||
        self.flush(child)
 | 
			
		||||
 | 
			
		||||
    def test_pdb_and_capsys(self, testdir):
 | 
			
		||||
| 
						 | 
				
			
			@ -383,7 +402,7 @@ class TestPDB(object):
 | 
			
		|||
            """
 | 
			
		||||
            import pytest
 | 
			
		||||
            def test_1(capsys):
 | 
			
		||||
                print ("hello1")
 | 
			
		||||
                print("hello1")
 | 
			
		||||
                pytest.set_trace()
 | 
			
		||||
        """
 | 
			
		||||
        )
 | 
			
		||||
| 
						 | 
				
			
			@ -420,7 +439,7 @@ class TestPDB(object):
 | 
			
		|||
            def test_1():
 | 
			
		||||
                pdb.set_trace()
 | 
			
		||||
            def test_2():
 | 
			
		||||
                print ("hello")
 | 
			
		||||
                print("hello")
 | 
			
		||||
                assert 0
 | 
			
		||||
        """
 | 
			
		||||
        )
 | 
			
		||||
| 
						 | 
				
			
			@ -461,10 +480,10 @@ class TestPDB(object):
 | 
			
		|||
            import pytest
 | 
			
		||||
            def test_1():
 | 
			
		||||
                i = 0
 | 
			
		||||
                print ("hello17")
 | 
			
		||||
                print("hello17")
 | 
			
		||||
                pytest.set_trace()
 | 
			
		||||
                x = 3
 | 
			
		||||
                print ("hello18")
 | 
			
		||||
                print("hello18")
 | 
			
		||||
                pytest.set_trace()
 | 
			
		||||
                x = 4
 | 
			
		||||
        """
 | 
			
		||||
| 
						 | 
				
			
			@ -518,14 +537,16 @@ class TestPDB(object):
 | 
			
		|||
    def test_pdb_collection_failure_is_shown(self, testdir):
 | 
			
		||||
        p1 = testdir.makepyfile("xxx")
 | 
			
		||||
        result = testdir.runpytest_subprocess("--pdb", p1)
 | 
			
		||||
        result.stdout.fnmatch_lines(["*NameError*xxx*", "*1 error*"])
 | 
			
		||||
        result.stdout.fnmatch_lines(
 | 
			
		||||
            ["E   NameError: *xxx*", "*! *Exit: Quitting debugger !*"]  # due to EOF
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_enter_pdb_hook_is_called(self, testdir):
 | 
			
		||||
        testdir.makeconftest(
 | 
			
		||||
            """
 | 
			
		||||
            def pytest_enter_pdb(config):
 | 
			
		||||
                assert config.testing_verification == 'configured'
 | 
			
		||||
                print 'enter_pdb_hook'
 | 
			
		||||
                print('enter_pdb_hook')
 | 
			
		||||
 | 
			
		||||
            def pytest_configure(config):
 | 
			
		||||
                config.testing_verification = 'configured'
 | 
			
		||||
| 
						 | 
				
			
			@ -562,7 +583,7 @@ class TestPDB(object):
 | 
			
		|||
            custom_pdb="""
 | 
			
		||||
            class CustomPdb(object):
 | 
			
		||||
                def set_trace(*args, **kwargs):
 | 
			
		||||
                    print 'custom set_trace>'
 | 
			
		||||
                    print('custom set_trace>')
 | 
			
		||||
         """
 | 
			
		||||
        )
 | 
			
		||||
        p1 = testdir.makepyfile(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -154,7 +154,7 @@ class TestTerminal(object):
 | 
			
		|||
        )
 | 
			
		||||
        result = testdir.runpytest(p2)
 | 
			
		||||
        result.stdout.fnmatch_lines(["*test_p2.py .*", "*1 passed*"])
 | 
			
		||||
        result = testdir.runpytest("-v", p2)
 | 
			
		||||
        result = testdir.runpytest("-vv", p2)
 | 
			
		||||
        result.stdout.fnmatch_lines(
 | 
			
		||||
            ["*test_p2.py::TestMore::test_p1* <- *test_p1.py*PASSED*"]
 | 
			
		||||
        )
 | 
			
		||||
| 
						 | 
				
			
			@ -170,7 +170,7 @@ class TestTerminal(object):
 | 
			
		|||
                """
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
        result = testdir.runpytest("-v")
 | 
			
		||||
        result = testdir.runpytest("-vv")
 | 
			
		||||
        assert result.ret == 0
 | 
			
		||||
        result.stdout.fnmatch_lines(["*a123/test_hello123.py*PASS*"])
 | 
			
		||||
        assert " <- " not in result.stdout.str()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -196,6 +196,12 @@ class TestNumberedDir(object):
 | 
			
		|||
            assert d.name.startswith(self.PREFIX)
 | 
			
		||||
            assert d.name.endswith(str(i))
 | 
			
		||||
 | 
			
		||||
        symlink = tmp_path.joinpath(self.PREFIX + "current")
 | 
			
		||||
        if symlink.exists():
 | 
			
		||||
            # unix
 | 
			
		||||
            assert symlink.is_symlink()
 | 
			
		||||
            assert symlink.resolve() == d.resolve()
 | 
			
		||||
 | 
			
		||||
    def test_cleanup_lock_create(self, tmp_path):
 | 
			
		||||
        d = tmp_path.joinpath("test")
 | 
			
		||||
        d.mkdir()
 | 
			
		||||
| 
						 | 
				
			
			@ -244,7 +250,7 @@ class TestNumberedDir(object):
 | 
			
		|||
 | 
			
		||||
    def test_cleanup_keep(self, tmp_path):
 | 
			
		||||
        self._do_cleanup(tmp_path)
 | 
			
		||||
        a, b = tmp_path.iterdir()
 | 
			
		||||
        a, b = (x for x in tmp_path.iterdir() if not x.is_symlink())
 | 
			
		||||
        print(a, b)
 | 
			
		||||
 | 
			
		||||
    def test_cleanup_locked(self, tmp_path):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										27
									
								
								tox.ini
								
								
								
								
							
							
						
						
									
										27
									
								
								tox.ini
								
								
								
								
							| 
						 | 
				
			
			@ -18,10 +18,10 @@ envlist =
 | 
			
		|||
 | 
			
		||||
[testenv]
 | 
			
		||||
commands =
 | 
			
		||||
    {env:_PYTEST_TOX_COVERAGE_RUN:} pytest --lsof -ra {posargs:testing}
 | 
			
		||||
    {env:_PYTEST_TOX_COVERAGE_RUN:} pytest --lsof
 | 
			
		||||
    coverage: coverage combine
 | 
			
		||||
    coverage: coverage report
 | 
			
		||||
passenv = USER USERNAME
 | 
			
		||||
passenv = USER USERNAME COVERAGE_* TRAVIS
 | 
			
		||||
setenv =
 | 
			
		||||
    # configuration if a user runs tox with a "coverage" factor, for example "tox -e py36-coverage"
 | 
			
		||||
    coverage: _PYTEST_TOX_COVERAGE_RUN=coverage run -m
 | 
			
		||||
| 
						 | 
				
			
			@ -36,14 +36,12 @@ deps =
 | 
			
		|||
    {env:_PYTEST_TOX_EXTRA_DEP:}
 | 
			
		||||
 | 
			
		||||
[testenv:py27-subprocess]
 | 
			
		||||
changedir = .
 | 
			
		||||
deps =
 | 
			
		||||
    pytest-xdist>=1.13
 | 
			
		||||
    py27: mock
 | 
			
		||||
    nose
 | 
			
		||||
passenv = USER USERNAME TRAVIS
 | 
			
		||||
commands =
 | 
			
		||||
    pytest -n auto -ra --runpytest=subprocess {posargs:testing}
 | 
			
		||||
    pytest -n auto --runpytest=subprocess
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[testenv:linting]
 | 
			
		||||
| 
						 | 
				
			
			@ -59,9 +57,8 @@ deps =
 | 
			
		|||
    nose
 | 
			
		||||
    hypothesis>=3.56
 | 
			
		||||
    {env:_PYTEST_TOX_EXTRA_DEP:}
 | 
			
		||||
passenv = USER USERNAME TRAVIS
 | 
			
		||||
commands =
 | 
			
		||||
    {env:_PYTEST_TOX_COVERAGE_RUN:} pytest -n auto -ra {posargs:testing}
 | 
			
		||||
    {env:_PYTEST_TOX_COVERAGE_RUN:} pytest -n auto
 | 
			
		||||
 | 
			
		||||
[testenv:py36-xdist]
 | 
			
		||||
# NOTE: copied from above due to https://github.com/tox-dev/tox/issues/706.
 | 
			
		||||
| 
						 | 
				
			
			@ -74,16 +71,14 @@ deps =
 | 
			
		|||
commands = {[testenv:py27-xdist]commands}
 | 
			
		||||
 | 
			
		||||
[testenv:py27-pexpect]
 | 
			
		||||
changedir = testing
 | 
			
		||||
platform = linux|darwin
 | 
			
		||||
deps =
 | 
			
		||||
    pexpect
 | 
			
		||||
    {env:_PYTEST_TOX_EXTRA_DEP:}
 | 
			
		||||
commands =
 | 
			
		||||
    {env:_PYTEST_TOX_COVERAGE_RUN:} pytest -ra test_pdb.py test_terminal.py test_unittest.py
 | 
			
		||||
    {env:_PYTEST_TOX_COVERAGE_RUN:} pytest testing/test_pdb.py testing/test_terminal.py testing/test_unittest.py {posargs}
 | 
			
		||||
 | 
			
		||||
[testenv:py36-pexpect]
 | 
			
		||||
changedir = {[testenv:py27-pexpect]changedir}
 | 
			
		||||
platform = {[testenv:py27-pexpect]platform}
 | 
			
		||||
deps = {[testenv:py27-pexpect]deps}
 | 
			
		||||
commands = {[testenv:py27-pexpect]commands}
 | 
			
		||||
| 
						 | 
				
			
			@ -95,20 +90,18 @@ deps =
 | 
			
		|||
    py27: mock
 | 
			
		||||
    {env:_PYTEST_TOX_EXTRA_DEP:}
 | 
			
		||||
distribute = true
 | 
			
		||||
changedir=testing
 | 
			
		||||
setenv =
 | 
			
		||||
    {[testenv]setenv}
 | 
			
		||||
    PYTHONDONTWRITEBYTECODE=1
 | 
			
		||||
passenv = USER USERNAME TRAVIS
 | 
			
		||||
commands =
 | 
			
		||||
    {env:_PYTEST_TOX_COVERAGE_RUN:} pytest -n auto -ra {posargs:.}
 | 
			
		||||
    {env:_PYTEST_TOX_COVERAGE_RUN:} pytest -n auto {posargs}
 | 
			
		||||
 | 
			
		||||
[testenv:py27-trial]
 | 
			
		||||
deps =
 | 
			
		||||
    twisted
 | 
			
		||||
    {env:_PYTEST_TOX_EXTRA_DEP:}
 | 
			
		||||
commands =
 | 
			
		||||
    {env:_PYTEST_TOX_COVERAGE_RUN:} pytest -ra {posargs:testing/test_unittest.py}
 | 
			
		||||
    {env:_PYTEST_TOX_COVERAGE_RUN:} pytest {posargs:testing/test_unittest.py}
 | 
			
		||||
 | 
			
		||||
[testenv:py36-trial]
 | 
			
		||||
deps = {[testenv:py27-trial]deps}
 | 
			
		||||
| 
						 | 
				
			
			@ -119,7 +112,7 @@ deps =
 | 
			
		|||
    numpy
 | 
			
		||||
    {env:_PYTEST_TOX_EXTRA_DEP:}
 | 
			
		||||
commands=
 | 
			
		||||
  {env:_PYTEST_TOX_COVERAGE_RUN:} pytest -ra {posargs:testing/python/approx.py}
 | 
			
		||||
  {env:_PYTEST_TOX_COVERAGE_RUN:} pytest {posargs:testing/python/approx.py}
 | 
			
		||||
 | 
			
		||||
[testenv:py36-numpy]
 | 
			
		||||
deps = {[testenv:py27-numpy]deps}
 | 
			
		||||
| 
						 | 
				
			
			@ -154,7 +147,7 @@ deps =
 | 
			
		|||
    PyYAML
 | 
			
		||||
    {env:_PYTEST_TOX_EXTRA_DEP:}
 | 
			
		||||
commands =
 | 
			
		||||
    {env:_PYTEST_TOX_COVERAGE_RUN:} pytest -ra doc/en
 | 
			
		||||
    {env:_PYTEST_TOX_COVERAGE_RUN:} pytest doc/en
 | 
			
		||||
    {env:_PYTEST_TOX_COVERAGE_RUN:} pytest --doctest-modules --pyargs _pytest
 | 
			
		||||
 | 
			
		||||
[testenv:regen]
 | 
			
		||||
| 
						 | 
				
			
			@ -175,7 +168,7 @@ commands =
 | 
			
		|||
[testenv:jython]
 | 
			
		||||
changedir = testing
 | 
			
		||||
commands =
 | 
			
		||||
    {envpython} {envbindir}/py.test-jython -ra {posargs}
 | 
			
		||||
    {envpython} {envbindir}/py.test-jython {posargs}
 | 
			
		||||
 | 
			
		||||
[testenv:py36-freeze]
 | 
			
		||||
changedir = testing/freeze
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue