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
|
||||
Anthony Shaw
|
||||
Anthony Sottile
|
||||
Anton Lodder
|
||||
Antony Lee
|
||||
Armin Rigo
|
||||
Aron Coyle
|
||||
|
@ -176,6 +177,7 @@ Oliver Bestwalter
|
|||
Omar Kohl
|
||||
Omer Hadari
|
||||
Ondřej Súkup
|
||||
Oscar Benjamin
|
||||
Patrick Hayes
|
||||
Paweł Adamczak
|
||||
Pedro Algarvio
|
||||
|
|
|
@ -18,6 +18,38 @@ with advance notice in the **Deprecations** section of releases.
|
|||
|
||||
.. 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)
|
||||
=========================
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
release-4.1.1
|
||||
release-4.1.0
|
||||
release-4.0.2
|
||||
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):
|
||||
> assert mydata == 23
|
||||
E assert 42 == 23
|
||||
E -42
|
||||
E +23
|
||||
|
||||
test_caching.py:17: AssertionError
|
||||
-------------------------- Captured stdout setup ---------------------------
|
||||
|
@ -235,6 +237,8 @@ the cache and nothing will be printed:
|
|||
def test_function(mydata):
|
||||
> assert mydata == 23
|
||||
E assert 42 == 23
|
||||
E -42
|
||||
E +23
|
||||
|
||||
test_caching.py:17: AssertionError
|
||||
1 failed in 0.12 seconds
|
||||
|
|
|
@ -42,10 +42,11 @@ todo_include_todos = 1
|
|||
extensions = [
|
||||
"pygments_pytest",
|
||||
"sphinx.ext.autodoc",
|
||||
"sphinx.ext.todo",
|
||||
"sphinx.ext.autosummary",
|
||||
"sphinx.ext.intersphinx",
|
||||
"sphinx.ext.todo",
|
||||
"sphinx.ext.viewcode",
|
||||
"sphinx_removed_in",
|
||||
"sphinxcontrib_trio",
|
||||
]
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ an appropriate period of deprecation has passed.
|
|||
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``
|
||||
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``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
*Removed in version 4.0.*
|
||||
.. versionremoved:: 4.0
|
||||
|
||||
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
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
*Removed in version 4.0.*
|
||||
.. versionremoved:: 4.0
|
||||
|
||||
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
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
*Removed in version 4.0.*
|
||||
.. versionremoved:: 4.0
|
||||
|
||||
``[pytest]`` sections in ``setup.cfg`` files should now be named ``[tool:pytest]``
|
||||
to avoid conflicts with other distutils commands.
|
||||
|
@ -193,7 +193,7 @@ to avoid conflicts with other distutils commands.
|
|||
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.parametrize` instead.
|
||||
|
@ -217,7 +217,7 @@ Becomes:
|
|||
``cached_setup``
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
*Removed in version 4.0.*
|
||||
.. versionremoved:: 4.0
|
||||
|
||||
``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
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
*Removed in version 4.0.*
|
||||
.. versionremoved:: 4.0
|
||||
|
||||
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
|
||||
|
@ -259,7 +259,7 @@ features ``conftest.py`` files are only *active* for tests at or below it.
|
|||
``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
|
||||
system for its own warnings, so those two functions are now deprecated.
|
||||
|
@ -286,7 +286,7 @@ Becomes:
|
|||
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
|
||||
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()``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
*Removed in version 4.0.*
|
||||
.. versionremoved:: 4.0
|
||||
|
||||
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
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
*Removed in version 4.0.*
|
||||
.. versionremoved:: 4.0
|
||||
|
||||
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
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
*Removed in version 4.0.*
|
||||
.. versionremoved:: 4.0
|
||||
|
||||
pytest supported ``yield``-style tests, where a test function actually ``yield`` functions and values
|
||||
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``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
*Removed in version 4.0.*
|
||||
.. versionremoved:: 4.0
|
||||
|
||||
Access of ``Module``, ``Function``, ``Class``, ``Instance``, ``File`` and ``Item`` through ``Node`` instances now issue
|
||||
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.
|
||||
|
||||
``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``
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
*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
|
||||
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``)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
*Removed in version 3.0.*
|
||||
.. versionremoved:: 3.0
|
||||
|
||||
Reinterpretation mode has now been removed and only plain and rewrite
|
||||
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 in version 3.0.*
|
||||
.. versionremoved:: 3.0
|
||||
|
||||
The following deprecated commandline options were removed:
|
||||
|
||||
|
@ -485,27 +503,9 @@ The following deprecated commandline options were removed:
|
|||
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
|
||||
were never documented and a leftover from a pre-virtualenv era. These entry
|
||||
points also created broken entry points in wheels, so removing them also
|
||||
removes a source of confusion for users.
|
||||
|
||||
|
||||
``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):
|
||||
> assert a == b
|
||||
E assert 1 == 2
|
||||
E -1
|
||||
E +2
|
||||
|
||||
test_parametrize.py:18: AssertionError
|
||||
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
|
||||
...
|
||||
|
||||
This way your tests can run easily against an installed version
|
||||
of ``mypkg``.
|
||||
This has the following benefits:
|
||||
|
||||
* 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
|
||||
``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
|
||||
(``[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
|
||||
passed multiple times. The expected format is ``name=value``. For example::
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
pygments-pytest>=1.1.0
|
||||
sphinx>=1.8.2
|
||||
sphinxcontrib-trio
|
||||
sphinx-removed-in>=0.1.3
|
||||
|
|
|
@ -512,7 +512,13 @@ def _format_assertmsg(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):
|
||||
|
|
|
@ -151,6 +151,8 @@ def assertrepr_compare(config, op, left, right):
|
|||
elif type(left) == type(right) and (isdatacls(left) or isattrs(left)):
|
||||
type_fn = (isdatacls, isattrs)
|
||||
explanation = _compare_eq_cls(left, right, verbose, type_fn)
|
||||
elif verbose:
|
||||
explanation = _compare_eq_verbose(left, right)
|
||||
if isiterable(left) and isiterable(right):
|
||||
expl = _compare_eq_iterable(left, right, verbose)
|
||||
if explanation is not None:
|
||||
|
@ -236,6 +238,18 @@ def _diff_text(left, right, verbose=False):
|
|||
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):
|
||||
if not verbose:
|
||||
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 print_function
|
||||
|
||||
import inspect
|
||||
import platform
|
||||
import sys
|
||||
import traceback
|
||||
from contextlib import contextmanager
|
||||
|
||||
import pytest
|
||||
from _pytest._code.code import ExceptionInfo
|
||||
from _pytest._code.code import ReprFileLocation
|
||||
from _pytest._code.code import TerminalRepr
|
||||
from _pytest.compat import safe_getattr
|
||||
from _pytest.fixtures import FixtureRequest
|
||||
|
||||
|
||||
DOCTEST_REPORT_CHOICE_NONE = "none"
|
||||
DOCTEST_REPORT_CHOICE_CDIFF = "cdiff"
|
||||
DOCTEST_REPORT_CHOICE_NDIFF = "ndiff"
|
||||
|
@ -346,10 +348,61 @@ def _check_all_skipped(test):
|
|||
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):
|
||||
def collect(self):
|
||||
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":
|
||||
module = self.config.pluginmanager._importconftest(self.fspath)
|
||||
else:
|
||||
|
@ -361,7 +414,7 @@ class DoctestModule(pytest.Module):
|
|||
else:
|
||||
raise
|
||||
# uses internal doctest module parsing mechanism
|
||||
finder = doctest.DocTestFinder()
|
||||
finder = MockAwareDocTestFinder()
|
||||
optionflags = get_optionflags(self)
|
||||
runner = _get_runner(
|
||||
verbose=0,
|
||||
|
|
|
@ -150,10 +150,10 @@ class ApproxNumpy(ApproxBase):
|
|||
|
||||
if np.isscalar(actual):
|
||||
for i in np.ndindex(self.expected.shape):
|
||||
yield actual, np.asscalar(self.expected[i])
|
||||
yield actual, self.expected[i].item()
|
||||
else:
|
||||
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):
|
||||
|
|
|
@ -488,6 +488,30 @@ class TestAssert_reprcompare(object):
|
|||
expl = callequal([(1, 2)], [])
|
||||
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):
|
||||
class A(object):
|
||||
def __repr__(self):
|
||||
|
|
|
@ -180,6 +180,27 @@ class TestAssertionRewrite(object):
|
|||
|
||||
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 f():
|
||||
assert False, "something bad!"
|
||||
|
|
|
@ -1206,3 +1206,22 @@ class TestDoctestReportingOption(object):
|
|||
"*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
|
||||
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
import six
|
||||
|
||||
|
@ -685,25 +686,10 @@ class TestAssertionWarnings:
|
|||
result.stdout.fnmatch_lines(["*1 failed in*"])
|
||||
|
||||
|
||||
def test_warningschecker_twice(testdir):
|
||||
def test_warnings_checker_twice():
|
||||
"""Issue #4617"""
|
||||
|
||||
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):
|
||||
expectation = pytest.warns(UserWarning)
|
||||
with expectation:
|
||||
warnings.warn("Message A", DeprecationWarning)
|
||||
"""
|
||||
)
|
||||
result = testdir.runpytest()
|
||||
result.stdout.fnmatch_lines(["* 4 passed in *"])
|
||||
warnings.warn("Message A", UserWarning)
|
||||
with expectation:
|
||||
warnings.warn("Message B", UserWarning)
|
||||
|
|
Loading…
Reference in New Issue