Merge pull request #4645 from blueyed/merge-master-into-features
Merge master into features
This commit is contained in:
commit
4947eb85c0
|
@ -0,0 +1,2 @@
|
||||||
|
rtd:
|
||||||
|
project: pytest
|
2
AUTHORS
2
AUTHORS
|
@ -24,6 +24,7 @@ Andy Freeland
|
||||||
Anthon van der Neut
|
Anthon van der Neut
|
||||||
Anthony Shaw
|
Anthony Shaw
|
||||||
Anthony Sottile
|
Anthony Sottile
|
||||||
|
Anton Lodder
|
||||||
Antony Lee
|
Antony Lee
|
||||||
Armin Rigo
|
Armin Rigo
|
||||||
Aron Coyle
|
Aron Coyle
|
||||||
|
@ -176,6 +177,7 @@ Oliver Bestwalter
|
||||||
Omar Kohl
|
Omar Kohl
|
||||||
Omer Hadari
|
Omer Hadari
|
||||||
Ondřej Súkup
|
Ondřej Súkup
|
||||||
|
Oscar Benjamin
|
||||||
Patrick Hayes
|
Patrick Hayes
|
||||||
Paweł Adamczak
|
Paweł Adamczak
|
||||||
Pedro Algarvio
|
Pedro Algarvio
|
||||||
|
|
|
@ -18,6 +18,38 @@ with advance notice in the **Deprecations** section of releases.
|
||||||
|
|
||||||
.. towncrier release notes start
|
.. towncrier release notes start
|
||||||
|
|
||||||
|
pytest 4.1.1 (2019-01-12)
|
||||||
|
=========================
|
||||||
|
|
||||||
|
Bug Fixes
|
||||||
|
---------
|
||||||
|
|
||||||
|
- `#2256 <https://github.com/pytest-dev/pytest/issues/2256>`_: Show full repr with ``assert a==b`` and ``-vv``.
|
||||||
|
|
||||||
|
|
||||||
|
- `#3456 <https://github.com/pytest-dev/pytest/issues/3456>`_: Extend Doctest-modules to ignore mock objects.
|
||||||
|
|
||||||
|
|
||||||
|
- `#4617 <https://github.com/pytest-dev/pytest/issues/4617>`_: Fixed ``pytest.warns`` bug when context manager is reused (e.g. multiple parametrization).
|
||||||
|
|
||||||
|
|
||||||
|
- `#4631 <https://github.com/pytest-dev/pytest/issues/4631>`_: Don't rewrite assertion when ``__getattr__`` is broken
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Improved Documentation
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
- `#3375 <https://github.com/pytest-dev/pytest/issues/3375>`_: Document that using ``setup.cfg`` may crash other tools or cause hard to track down problems because it uses a different parser than ``pytest.ini`` or ``tox.ini`` files.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Trivial/Internal Changes
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
- `#4602 <https://github.com/pytest-dev/pytest/issues/4602>`_: Uninstall ``hypothesis`` in regen tox env.
|
||||||
|
|
||||||
|
|
||||||
pytest 4.1.0 (2019-01-05)
|
pytest 4.1.0 (2019-01-05)
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Uninstall ``hypothesis`` in regen tox env.
|
|
|
@ -1 +0,0 @@
|
||||||
Fixed ``pytest.warns`` bug when context manager is reused (e.g. multiple parametrization).
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Use ``a.item()`` instead of the deprecated ``np.asscalar(a)`` in ``pytest.approx``.
|
||||||
|
|
||||||
|
``np.asscalar`` has been `deprecated <https://github.com/numpy/numpy/blob/master/doc/release/1.16.0-notes.rst#new-deprecations>`__ in ``numpy 1.16.``.
|
|
@ -6,6 +6,7 @@ Release announcements
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
|
|
||||||
|
release-4.1.1
|
||||||
release-4.1.0
|
release-4.1.0
|
||||||
release-4.0.2
|
release-4.0.2
|
||||||
release-4.0.1
|
release-4.0.1
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
pytest-4.1.1
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
pytest 4.1.1 has just been released to PyPI.
|
||||||
|
|
||||||
|
This is a bug-fix release, being a drop-in replacement. To upgrade::
|
||||||
|
|
||||||
|
pip install --upgrade pytest
|
||||||
|
|
||||||
|
The full changelog is available at https://docs.pytest.org/en/latest/changelog.html.
|
||||||
|
|
||||||
|
Thanks to all who contributed to this release, among them:
|
||||||
|
|
||||||
|
* Anthony Sottile
|
||||||
|
* Anton Lodder
|
||||||
|
* Bruno Oliveira
|
||||||
|
* Daniel Hahler
|
||||||
|
* David Vo
|
||||||
|
* Oscar Benjamin
|
||||||
|
* Ronny Pfannschmidt
|
||||||
|
* Victor Maryama
|
||||||
|
* Yoav Caspi
|
||||||
|
* dmitry.dygalo
|
||||||
|
|
||||||
|
|
||||||
|
Happy testing,
|
||||||
|
The pytest Development Team
|
|
@ -214,6 +214,8 @@ If you run this command for the first time, you can see the print statement:
|
||||||
def test_function(mydata):
|
def test_function(mydata):
|
||||||
> assert mydata == 23
|
> assert mydata == 23
|
||||||
E assert 42 == 23
|
E assert 42 == 23
|
||||||
|
E -42
|
||||||
|
E +23
|
||||||
|
|
||||||
test_caching.py:17: AssertionError
|
test_caching.py:17: AssertionError
|
||||||
-------------------------- Captured stdout setup ---------------------------
|
-------------------------- Captured stdout setup ---------------------------
|
||||||
|
@ -235,6 +237,8 @@ the cache and nothing will be printed:
|
||||||
def test_function(mydata):
|
def test_function(mydata):
|
||||||
> assert mydata == 23
|
> assert mydata == 23
|
||||||
E assert 42 == 23
|
E assert 42 == 23
|
||||||
|
E -42
|
||||||
|
E +23
|
||||||
|
|
||||||
test_caching.py:17: AssertionError
|
test_caching.py:17: AssertionError
|
||||||
1 failed in 0.12 seconds
|
1 failed in 0.12 seconds
|
||||||
|
|
|
@ -42,10 +42,11 @@ todo_include_todos = 1
|
||||||
extensions = [
|
extensions = [
|
||||||
"pygments_pytest",
|
"pygments_pytest",
|
||||||
"sphinx.ext.autodoc",
|
"sphinx.ext.autodoc",
|
||||||
"sphinx.ext.todo",
|
|
||||||
"sphinx.ext.autosummary",
|
"sphinx.ext.autosummary",
|
||||||
"sphinx.ext.intersphinx",
|
"sphinx.ext.intersphinx",
|
||||||
|
"sphinx.ext.todo",
|
||||||
"sphinx.ext.viewcode",
|
"sphinx.ext.viewcode",
|
||||||
|
"sphinx_removed_in",
|
||||||
"sphinxcontrib_trio",
|
"sphinxcontrib_trio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ an appropriate period of deprecation has passed.
|
||||||
Using ``Class`` in custom Collectors
|
Using ``Class`` in custom Collectors
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
*Removed in version 4.0.*
|
.. versionremoved:: 4.0
|
||||||
|
|
||||||
Using objects named ``"Class"`` as a way to customize the type of nodes that are collected in ``Collector``
|
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_pycollect_makeitem`` to customize node types during
|
subclasses has been deprecated. Users instead should use ``pytest_pycollect_makeitem`` to customize node types during
|
||||||
|
@ -114,7 +114,7 @@ message please contact the authors so they can change the code.
|
||||||
marks in ``pytest.mark.parametrize``
|
marks in ``pytest.mark.parametrize``
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
*Removed in version 4.0.*
|
.. versionremoved:: 4.0
|
||||||
|
|
||||||
Applying marks to values of a ``pytest.mark.parametrize`` call is now deprecated. For example:
|
Applying marks to values of a ``pytest.mark.parametrize`` call is now deprecated. For example:
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ To update the code, use ``pytest.param``:
|
||||||
``pytest_funcarg__`` prefix
|
``pytest_funcarg__`` prefix
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
*Removed in version 4.0.*
|
.. versionremoved:: 4.0
|
||||||
|
|
||||||
In very early pytest versions fixtures could be defined using the ``pytest_funcarg__`` prefix:
|
In very early pytest versions fixtures could be defined using the ``pytest_funcarg__`` prefix:
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ Switch over to the ``@pytest.fixture`` decorator:
|
||||||
[pytest] section in setup.cfg files
|
[pytest] section in setup.cfg files
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
*Removed in version 4.0.*
|
.. versionremoved:: 4.0
|
||||||
|
|
||||||
``[pytest]`` sections in ``setup.cfg`` files should now be named ``[tool:pytest]``
|
``[pytest]`` sections in ``setup.cfg`` files should now be named ``[tool:pytest]``
|
||||||
to avoid conflicts with other distutils commands.
|
to avoid conflicts with other distutils commands.
|
||||||
|
@ -193,7 +193,7 @@ to avoid conflicts with other distutils commands.
|
||||||
Metafunc.addcall
|
Metafunc.addcall
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
*Removed in version 4.0.*
|
.. versionremoved:: 4.0
|
||||||
|
|
||||||
:meth:`_pytest.python.Metafunc.addcall` was a precursor to the current parametrized mechanism. Users should use
|
:meth:`_pytest.python.Metafunc.addcall` was a precursor to the current parametrized mechanism. Users should use
|
||||||
:meth:`_pytest.python.Metafunc.parametrize` instead.
|
:meth:`_pytest.python.Metafunc.parametrize` instead.
|
||||||
|
@ -217,7 +217,7 @@ Becomes:
|
||||||
``cached_setup``
|
``cached_setup``
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
*Removed in version 4.0.*
|
.. versionremoved:: 4.0
|
||||||
|
|
||||||
``request.cached_setup`` was the precursor of the setup/teardown mechanism available to fixtures.
|
``request.cached_setup`` was the precursor of the setup/teardown mechanism available to fixtures.
|
||||||
|
|
||||||
|
@ -249,7 +249,7 @@ more information.
|
||||||
pytest_plugins in non-top-level conftest files
|
pytest_plugins in non-top-level conftest files
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
*Removed in version 4.0.*
|
.. versionremoved:: 4.0
|
||||||
|
|
||||||
Defining ``pytest_plugins`` is now deprecated in non-top-level conftest.py
|
Defining ``pytest_plugins`` is now deprecated in non-top-level conftest.py
|
||||||
files because they will activate referenced plugins *globally*, which is surprising because for all other pytest
|
files because they will activate referenced plugins *globally*, which is surprising because for all other pytest
|
||||||
|
@ -259,7 +259,7 @@ features ``conftest.py`` files are only *active* for tests at or below it.
|
||||||
``Config.warn`` and ``Node.warn``
|
``Config.warn`` and ``Node.warn``
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
*Removed in version 4.0.*
|
.. versionremoved:: 4.0
|
||||||
|
|
||||||
Those methods were part of the internal pytest warnings system, but since ``3.8`` pytest is using the builtin warning
|
Those methods were part of the internal pytest warnings system, but since ``3.8`` pytest is using the builtin warning
|
||||||
system for its own warnings, so those two functions are now deprecated.
|
system for its own warnings, so those two functions are now deprecated.
|
||||||
|
@ -286,7 +286,7 @@ Becomes:
|
||||||
record_xml_property
|
record_xml_property
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
*Removed in version 4.0.*
|
.. versionremoved:: 4.0
|
||||||
|
|
||||||
The ``record_xml_property`` fixture is now deprecated in favor of the more generic ``record_property``, which
|
The ``record_xml_property`` fixture is now deprecated in favor of the more generic ``record_property``, which
|
||||||
can be used by other consumers (for example ``pytest-html``) to obtain custom information about the test run.
|
can be used by other consumers (for example ``pytest-html``) to obtain custom information about the test run.
|
||||||
|
@ -309,7 +309,7 @@ Change to:
|
||||||
Passing command-line string to ``pytest.main()``
|
Passing command-line string to ``pytest.main()``
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
*Removed in version 4.0.*
|
.. versionremoved:: 4.0
|
||||||
|
|
||||||
Passing a command-line string to ``pytest.main()`` is deprecated:
|
Passing a command-line string to ``pytest.main()`` is deprecated:
|
||||||
|
|
||||||
|
@ -331,7 +331,7 @@ on (for example ``bash`` or ``Powershell``), but this is very hard/impossible to
|
||||||
Calling fixtures directly
|
Calling fixtures directly
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
*Removed in version 4.0.*
|
.. versionremoved:: 4.0
|
||||||
|
|
||||||
Calling a fixture function directly, as opposed to request them in a test function, is deprecated.
|
Calling a fixture function directly, as opposed to request them in a test function, is deprecated.
|
||||||
|
|
||||||
|
@ -384,7 +384,7 @@ with the ``name`` parameter:
|
||||||
``yield`` tests
|
``yield`` tests
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
*Removed in version 4.0.*
|
.. versionremoved:: 4.0
|
||||||
|
|
||||||
pytest supported ``yield``-style tests, where a test function actually ``yield`` functions and values
|
pytest supported ``yield``-style tests, where a test function actually ``yield`` functions and values
|
||||||
that are then turned into proper test methods. Example:
|
that are then turned into proper test methods. Example:
|
||||||
|
@ -412,7 +412,7 @@ This form of test function doesn't support fixtures properly, and users should s
|
||||||
Internal classes accessed through ``Node``
|
Internal classes accessed through ``Node``
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
*Removed in version 4.0.*
|
.. versionremoved:: 4.0
|
||||||
|
|
||||||
Access of ``Module``, ``Function``, ``Class``, ``Instance``, ``File`` and ``Item`` through ``Node`` instances now issue
|
Access of ``Module``, ``Function``, ``Class``, ``Instance``, ``File`` and ``Item`` through ``Node`` instances now issue
|
||||||
this warning::
|
this warning::
|
||||||
|
@ -423,10 +423,28 @@ Users should just ``import pytest`` and access those objects using the ``pytest`
|
||||||
|
|
||||||
This has been documented as deprecated for years, but only now we are actually emitting deprecation warnings.
|
This has been documented as deprecated for years, but only now we are actually emitting deprecation warnings.
|
||||||
|
|
||||||
|
``Node.get_marker``
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. versionremoved:: 4.0
|
||||||
|
|
||||||
|
As part of a large :ref:`marker-revamp`, :meth:`_pytest.nodes.Node.get_marker` is deprecated. See
|
||||||
|
:ref:`the documentation <update marker code>` on tips on how to update your code.
|
||||||
|
|
||||||
|
|
||||||
|
``somefunction.markname``
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. versionremoved:: 4.0
|
||||||
|
|
||||||
|
As part of a large :ref:`marker-revamp` we already deprecated using ``MarkInfo``
|
||||||
|
the only correct way to get markers of an element is via ``node.iter_markers(name)``.
|
||||||
|
|
||||||
|
|
||||||
``pytest_namespace``
|
``pytest_namespace``
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
*Removed in version 4.0.*
|
.. versionremoved:: 4.0
|
||||||
|
|
||||||
This hook is deprecated because it greatly complicates the pytest internals regarding configuration and initialization, making some
|
This hook is deprecated because it greatly complicates the pytest internals regarding configuration and initialization, making some
|
||||||
bug fixes and refactorings impossible.
|
bug fixes and refactorings impossible.
|
||||||
|
@ -461,7 +479,7 @@ As a stopgap measure, plugin authors may still inject their names into pytest's
|
||||||
Reinterpretation mode (``--assert=reinterp``)
|
Reinterpretation mode (``--assert=reinterp``)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
*Removed in version 3.0.*
|
.. versionremoved:: 3.0
|
||||||
|
|
||||||
Reinterpretation mode has now been removed and only plain and rewrite
|
Reinterpretation mode has now been removed and only plain and rewrite
|
||||||
mode are available, consequently the ``--assert=reinterp`` option is
|
mode are available, consequently the ``--assert=reinterp`` option is
|
||||||
|
@ -473,7 +491,7 @@ explicitly turn on assertion rewriting for those files.
|
||||||
Removed command-line options
|
Removed command-line options
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
*Removed in version 3.0.*
|
.. versionremoved:: 3.0
|
||||||
|
|
||||||
The following deprecated commandline options were removed:
|
The following deprecated commandline options were removed:
|
||||||
|
|
||||||
|
@ -485,27 +503,9 @@ The following deprecated commandline options were removed:
|
||||||
py.test-X* entry points
|
py.test-X* entry points
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
*Removed in version 3.0.*
|
.. versionremoved:: 3.0
|
||||||
|
|
||||||
Removed all ``py.test-X*`` entry points. The versioned, suffixed entry points
|
Removed all ``py.test-X*`` entry points. The versioned, suffixed entry points
|
||||||
were never documented and a leftover from a pre-virtualenv era. These entry
|
were never documented and a leftover from a pre-virtualenv era. These entry
|
||||||
points also created broken entry points in wheels, so removing them also
|
points also created broken entry points in wheels, so removing them also
|
||||||
removes a source of confusion for users.
|
removes a source of confusion for users.
|
||||||
|
|
||||||
|
|
||||||
``Node.get_marker``
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
*Removed in version 4.0*
|
|
||||||
|
|
||||||
As part of a large :ref:`marker-revamp`, :meth:`_pytest.nodes.Node.get_marker` is deprecated. See
|
|
||||||
:ref:`the documentation <update marker code>` on tips on how to update your code.
|
|
||||||
|
|
||||||
|
|
||||||
``somefunction.markname``
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
*Removed in version 4.0*
|
|
||||||
|
|
||||||
As part of a large :ref:`marker-revamp` we already deprecated using ``MarkInfo``
|
|
||||||
the only correct way to get markers of an element is via ``node.iter_markers(name)``.
|
|
||||||
|
|
|
@ -406,6 +406,8 @@ argument sets to use for each test function. Let's run it:
|
||||||
def test_equals(self, a, b):
|
def test_equals(self, a, b):
|
||||||
> assert a == b
|
> assert a == b
|
||||||
E assert 1 == 2
|
E assert 1 == 2
|
||||||
|
E -1
|
||||||
|
E +2
|
||||||
|
|
||||||
test_parametrize.py:18: AssertionError
|
test_parametrize.py:18: AssertionError
|
||||||
1 failed, 2 passed in 0.12 seconds
|
1 failed, 2 passed in 0.12 seconds
|
||||||
|
|
|
@ -72,8 +72,18 @@ to keep tests separate from actual application code (often a good idea)::
|
||||||
test_view.py
|
test_view.py
|
||||||
...
|
...
|
||||||
|
|
||||||
This way your tests can run easily against an installed version
|
This has the following benefits:
|
||||||
of ``mypkg``.
|
|
||||||
|
* Your tests can run against an installed version after executing ``pip install .``.
|
||||||
|
* Your tests can run against the local copy with an editable install after executing ``pip install --editable .``.
|
||||||
|
* If you don't have a ``setup.py`` file and are relying on the fact that Python by default puts the current
|
||||||
|
directory in ``sys.path`` to import your package, you can execute ``python -m pytest`` to execute the tests against the
|
||||||
|
local copy directly, without using ``pip``.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
See :ref:`pythonpath` for more information about the difference between calling ``pytest`` and
|
||||||
|
``python -m pytest``.
|
||||||
|
|
||||||
Note that using this scheme your test files must have **unique names**, because
|
Note that using this scheme your test files must have **unique names**, because
|
||||||
``pytest`` will import them as *top-level* modules since there are no packages
|
``pytest`` will import them as *top-level* modules since there are no packages
|
||||||
|
|
|
@ -889,6 +889,12 @@ Here is a list of builtin configuration options that may be written in a ``pytes
|
||||||
file, usually located at the root of your repository. All options must be under a ``[pytest]`` section
|
file, usually located at the root of your repository. All options must be under a ``[pytest]`` section
|
||||||
(``[tool:pytest]`` for ``setup.cfg`` files).
|
(``[tool:pytest]`` for ``setup.cfg`` files).
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
Usage of ``setup.cfg`` is not recommended unless for very simple use cases. ``.cfg``
|
||||||
|
files use a different parser than ``pytest.ini`` and ``tox.ini`` which might cause hard to track
|
||||||
|
down problems.
|
||||||
|
When possible, it is recommended to use the latter files to hold your pytest configuration.
|
||||||
|
|
||||||
Configuration file options may be overwritten in the command-line by using ``-o/--override``, which can also be
|
Configuration file options may be overwritten in the command-line by using ``-o/--override``, which can also be
|
||||||
passed multiple times. The expected format is ``name=value``. For example::
|
passed multiple times. The expected format is ``name=value``. For example::
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
pygments-pytest>=1.1.0
|
pygments-pytest>=1.1.0
|
||||||
sphinx>=1.8.2
|
sphinx>=1.8.2
|
||||||
sphinxcontrib-trio
|
sphinxcontrib-trio
|
||||||
|
sphinx-removed-in>=0.1.3
|
||||||
|
|
|
@ -512,7 +512,13 @@ def _format_assertmsg(obj):
|
||||||
|
|
||||||
|
|
||||||
def _should_repr_global_name(obj):
|
def _should_repr_global_name(obj):
|
||||||
return not hasattr(obj, "__name__") and not callable(obj)
|
if callable(obj):
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
return not hasattr(obj, "__name__")
|
||||||
|
except Exception:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _format_boolop(explanations, is_or):
|
def _format_boolop(explanations, is_or):
|
||||||
|
|
|
@ -151,6 +151,8 @@ def assertrepr_compare(config, op, left, right):
|
||||||
elif type(left) == type(right) and (isdatacls(left) or isattrs(left)):
|
elif type(left) == type(right) and (isdatacls(left) or isattrs(left)):
|
||||||
type_fn = (isdatacls, isattrs)
|
type_fn = (isdatacls, isattrs)
|
||||||
explanation = _compare_eq_cls(left, right, verbose, type_fn)
|
explanation = _compare_eq_cls(left, right, verbose, type_fn)
|
||||||
|
elif verbose:
|
||||||
|
explanation = _compare_eq_verbose(left, right)
|
||||||
if isiterable(left) and isiterable(right):
|
if isiterable(left) and isiterable(right):
|
||||||
expl = _compare_eq_iterable(left, right, verbose)
|
expl = _compare_eq_iterable(left, right, verbose)
|
||||||
if explanation is not None:
|
if explanation is not None:
|
||||||
|
@ -236,6 +238,18 @@ def _diff_text(left, right, verbose=False):
|
||||||
return explanation
|
return explanation
|
||||||
|
|
||||||
|
|
||||||
|
def _compare_eq_verbose(left, right):
|
||||||
|
keepends = True
|
||||||
|
left_lines = repr(left).splitlines(keepends)
|
||||||
|
right_lines = repr(right).splitlines(keepends)
|
||||||
|
|
||||||
|
explanation = []
|
||||||
|
explanation += [u"-" + line for line in left_lines]
|
||||||
|
explanation += [u"+" + line for line in right_lines]
|
||||||
|
|
||||||
|
return explanation
|
||||||
|
|
||||||
|
|
||||||
def _compare_eq_iterable(left, right, verbose=False):
|
def _compare_eq_iterable(left, right, verbose=False):
|
||||||
if not verbose:
|
if not verbose:
|
||||||
return [u"Use -v to get the full diff"]
|
return [u"Use -v to get the full diff"]
|
||||||
|
|
|
@ -3,17 +3,19 @@ from __future__ import absolute_import
|
||||||
from __future__ import division
|
from __future__ import division
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import inspect
|
||||||
import platform
|
import platform
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
from contextlib import contextmanager
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest._code.code import ExceptionInfo
|
from _pytest._code.code import ExceptionInfo
|
||||||
from _pytest._code.code import ReprFileLocation
|
from _pytest._code.code import ReprFileLocation
|
||||||
from _pytest._code.code import TerminalRepr
|
from _pytest._code.code import TerminalRepr
|
||||||
|
from _pytest.compat import safe_getattr
|
||||||
from _pytest.fixtures import FixtureRequest
|
from _pytest.fixtures import FixtureRequest
|
||||||
|
|
||||||
|
|
||||||
DOCTEST_REPORT_CHOICE_NONE = "none"
|
DOCTEST_REPORT_CHOICE_NONE = "none"
|
||||||
DOCTEST_REPORT_CHOICE_CDIFF = "cdiff"
|
DOCTEST_REPORT_CHOICE_CDIFF = "cdiff"
|
||||||
DOCTEST_REPORT_CHOICE_NDIFF = "ndiff"
|
DOCTEST_REPORT_CHOICE_NDIFF = "ndiff"
|
||||||
|
@ -346,10 +348,61 @@ def _check_all_skipped(test):
|
||||||
pytest.skip("all tests skipped by +SKIP option")
|
pytest.skip("all tests skipped by +SKIP option")
|
||||||
|
|
||||||
|
|
||||||
|
def _is_mocked(obj):
|
||||||
|
"""
|
||||||
|
returns if a object is possibly a mock object by checking the existence of a highly improbable attribute
|
||||||
|
"""
|
||||||
|
return (
|
||||||
|
safe_getattr(obj, "pytest_mock_example_attribute_that_shouldnt_exist", None)
|
||||||
|
is not None
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def _patch_unwrap_mock_aware():
|
||||||
|
"""
|
||||||
|
contextmanager which replaces ``inspect.unwrap`` with a version
|
||||||
|
that's aware of mock objects and doesn't recurse on them
|
||||||
|
"""
|
||||||
|
real_unwrap = getattr(inspect, "unwrap", None)
|
||||||
|
if real_unwrap is None:
|
||||||
|
yield
|
||||||
|
else:
|
||||||
|
|
||||||
|
def _mock_aware_unwrap(obj, stop=None):
|
||||||
|
if stop is None:
|
||||||
|
return real_unwrap(obj, stop=_is_mocked)
|
||||||
|
else:
|
||||||
|
return real_unwrap(obj, stop=lambda obj: _is_mocked(obj) or stop(obj))
|
||||||
|
|
||||||
|
inspect.unwrap = _mock_aware_unwrap
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
inspect.unwrap = real_unwrap
|
||||||
|
|
||||||
|
|
||||||
class DoctestModule(pytest.Module):
|
class DoctestModule(pytest.Module):
|
||||||
def collect(self):
|
def collect(self):
|
||||||
import doctest
|
import doctest
|
||||||
|
|
||||||
|
class MockAwareDocTestFinder(doctest.DocTestFinder):
|
||||||
|
"""
|
||||||
|
a hackish doctest finder that overrides stdlib internals to fix a stdlib bug
|
||||||
|
|
||||||
|
https://github.com/pytest-dev/pytest/issues/3456
|
||||||
|
https://bugs.python.org/issue25532
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _find(self, tests, obj, name, module, source_lines, globs, seen):
|
||||||
|
if _is_mocked(obj):
|
||||||
|
return
|
||||||
|
with _patch_unwrap_mock_aware():
|
||||||
|
|
||||||
|
doctest.DocTestFinder._find(
|
||||||
|
self, tests, obj, name, module, source_lines, globs, seen
|
||||||
|
)
|
||||||
|
|
||||||
if self.fspath.basename == "conftest.py":
|
if self.fspath.basename == "conftest.py":
|
||||||
module = self.config.pluginmanager._importconftest(self.fspath)
|
module = self.config.pluginmanager._importconftest(self.fspath)
|
||||||
else:
|
else:
|
||||||
|
@ -361,7 +414,7 @@ class DoctestModule(pytest.Module):
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
# uses internal doctest module parsing mechanism
|
# uses internal doctest module parsing mechanism
|
||||||
finder = doctest.DocTestFinder()
|
finder = MockAwareDocTestFinder()
|
||||||
optionflags = get_optionflags(self)
|
optionflags = get_optionflags(self)
|
||||||
runner = _get_runner(
|
runner = _get_runner(
|
||||||
verbose=0,
|
verbose=0,
|
||||||
|
|
|
@ -150,10 +150,10 @@ class ApproxNumpy(ApproxBase):
|
||||||
|
|
||||||
if np.isscalar(actual):
|
if np.isscalar(actual):
|
||||||
for i in np.ndindex(self.expected.shape):
|
for i in np.ndindex(self.expected.shape):
|
||||||
yield actual, np.asscalar(self.expected[i])
|
yield actual, self.expected[i].item()
|
||||||
else:
|
else:
|
||||||
for i in np.ndindex(self.expected.shape):
|
for i in np.ndindex(self.expected.shape):
|
||||||
yield np.asscalar(actual[i]), np.asscalar(self.expected[i])
|
yield actual[i].item(), self.expected[i].item()
|
||||||
|
|
||||||
|
|
||||||
class ApproxMapping(ApproxBase):
|
class ApproxMapping(ApproxBase):
|
||||||
|
|
|
@ -488,6 +488,30 @@ class TestAssert_reprcompare(object):
|
||||||
expl = callequal([(1, 2)], [])
|
expl = callequal([(1, 2)], [])
|
||||||
assert len(expl) > 1
|
assert len(expl) > 1
|
||||||
|
|
||||||
|
def test_repr_verbose(self):
|
||||||
|
class Nums:
|
||||||
|
def __init__(self, nums):
|
||||||
|
self.nums = nums
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return str(self.nums)
|
||||||
|
|
||||||
|
list_x = list(range(5000))
|
||||||
|
list_y = list(range(5000))
|
||||||
|
list_y[len(list_y) // 2] = 3
|
||||||
|
nums_x = Nums(list_x)
|
||||||
|
nums_y = Nums(list_y)
|
||||||
|
|
||||||
|
assert callequal(nums_x, nums_y) is None
|
||||||
|
|
||||||
|
expl = callequal(nums_x, nums_y, verbose=1)
|
||||||
|
assert "-" + repr(nums_x) in expl
|
||||||
|
assert "+" + repr(nums_y) in expl
|
||||||
|
|
||||||
|
expl = callequal(nums_x, nums_y, verbose=2)
|
||||||
|
assert "-" + repr(nums_x) in expl
|
||||||
|
assert "+" + repr(nums_y) in expl
|
||||||
|
|
||||||
def test_list_bad_repr(self):
|
def test_list_bad_repr(self):
|
||||||
class A(object):
|
class A(object):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|
|
@ -180,6 +180,27 @@ class TestAssertionRewrite(object):
|
||||||
|
|
||||||
assert getmsg(f, {"cls": X}) == "assert cls == 42"
|
assert getmsg(f, {"cls": X}) == "assert cls == 42"
|
||||||
|
|
||||||
|
def test_dont_rewrite_if_hasattr_fails(self):
|
||||||
|
class Y(object):
|
||||||
|
""" A class whos getattr fails, but not with `AttributeError` """
|
||||||
|
|
||||||
|
def __getattr__(self, attribute_name):
|
||||||
|
raise KeyError()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "Y"
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.foo = 3
|
||||||
|
|
||||||
|
def f():
|
||||||
|
assert cls().foo == 2 # noqa
|
||||||
|
|
||||||
|
message = getmsg(f, {"cls": Y})
|
||||||
|
assert "assert 3 == 2" in message
|
||||||
|
assert "+ where 3 = Y.foo" in message
|
||||||
|
assert "+ where Y = cls()" in message
|
||||||
|
|
||||||
def test_assert_already_has_message(self):
|
def test_assert_already_has_message(self):
|
||||||
def f():
|
def f():
|
||||||
assert False, "something bad!"
|
assert False, "something bad!"
|
||||||
|
|
|
@ -1206,3 +1206,22 @@ class TestDoctestReportingOption(object):
|
||||||
"*error: argument --doctest-report: invalid choice: 'obviously_invalid_format' (choose from*"
|
"*error: argument --doctest-report: invalid choice: 'obviously_invalid_format' (choose from*"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("mock_module", ["mock", "unittest.mock"])
|
||||||
|
def test_doctest_mock_objects_dont_recurse_missbehaved(mock_module, testdir):
|
||||||
|
pytest.importorskip(mock_module)
|
||||||
|
testdir.makepyfile(
|
||||||
|
"""
|
||||||
|
from {mock_module} import call
|
||||||
|
class Example(object):
|
||||||
|
'''
|
||||||
|
>>> 1 + 1
|
||||||
|
2
|
||||||
|
'''
|
||||||
|
""".format(
|
||||||
|
mock_module=mock_module
|
||||||
|
)
|
||||||
|
)
|
||||||
|
result = testdir.runpytest("--doctest-modules")
|
||||||
|
result.stdout.fnmatch_lines(["* 1 passed *"])
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
import warnings
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
|
@ -685,25 +686,10 @@ class TestAssertionWarnings:
|
||||||
result.stdout.fnmatch_lines(["*1 failed in*"])
|
result.stdout.fnmatch_lines(["*1 failed in*"])
|
||||||
|
|
||||||
|
|
||||||
def test_warningschecker_twice(testdir):
|
def test_warnings_checker_twice():
|
||||||
"""Issue #4617"""
|
"""Issue #4617"""
|
||||||
|
expectation = pytest.warns(UserWarning)
|
||||||
testdir.makepyfile(
|
|
||||||
"""
|
|
||||||
import pytest
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("other", [1, 2])
|
|
||||||
@pytest.mark.parametrize("expectation", [
|
|
||||||
pytest.warns(DeprecationWarning,
|
|
||||||
match="Message A"),
|
|
||||||
pytest.warns(DeprecationWarning,
|
|
||||||
match="Message A"),
|
|
||||||
])
|
|
||||||
def test_parametrized_warnings(other, expectation):
|
|
||||||
with expectation:
|
with expectation:
|
||||||
warnings.warn("Message A", DeprecationWarning)
|
warnings.warn("Message A", UserWarning)
|
||||||
"""
|
with expectation:
|
||||||
)
|
warnings.warn("Message B", UserWarning)
|
||||||
result = testdir.runpytest()
|
|
||||||
result.stdout.fnmatch_lines(["* 4 passed in *"])
|
|
||||||
|
|
Loading…
Reference in New Issue