[Pytest-commit] commit/pytest: 2 new changesets
commits-noreply at bitbucket.org
commits-noreply at bitbucket.org
Sat Sep 27 10:09:20 CEST 2014
2 new commits in pytest:
https://bitbucket.org/hpk42/pytest/commits/23a70aa66ddf/
Changeset: 23a70aa66ddf
Branch: better-diff-on-verbose-2
User: bubenkoff
Date: 2014-09-27 01:29:47+00:00
Summary: Improve assertion failure reporting on iterables, by using ndiff and pprint.
Affected #: 3 files
diff -r f829d42dd9f7a5deb4a4e497d8ca08c08fdeba9c -r 23a70aa66ddfe1c7d7f6ce9e431a31a4895443ab CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,8 @@
+Unreleased
+----------
+
+- Improve assertion failure reporting on iterables, by using ndiff and pprint.
+
2.6.3
-----------
@@ -80,7 +85,7 @@
- fix issue with detecting conftest files if the arguments contain
"::" node id specifications (copy pasted from "-v" output)
-- fix issue544 by only removing "@NUM" at the end of "::" separated parts
+- fix issue544 by only removing "@NUM" at the end of "::" separated parts
and if the part has an ".py" extension
- don't use py.std import helper, rather import things directly.
@@ -93,7 +98,7 @@
- fix issue537: Avoid importing old assertion reinterpretation code by default.
-- fix issue364: shorten and enhance tracebacks representation by default.
+- fix issue364: shorten and enhance tracebacks representation by default.
The new "--tb=auto" option (default) will only display long tracebacks
for the first and last entry. You can get the old behaviour of printing
all entries as long entries with "--tb=long". Also short entries by
@@ -119,14 +124,14 @@
- fix issue473: work around mock putting an unbound method into a class
dict when double-patching.
-- fix issue498: if a fixture finalizer fails, make sure that
+- fix issue498: if a fixture finalizer fails, make sure that
the fixture is still invalidated.
- fix issue453: the result of the pytest_assertrepr_compare hook now gets
it's newlines escaped so that format_exception does not blow up.
- internal new warning system: pytest will now produce warnings when
- it detects oddities in your test collection or execution.
+ it detects oddities in your test collection or execution.
Warnings are ultimately sent to a new pytest_logwarning hook which is
currently only implemented by the terminal plugin which displays
warnings in the summary line and shows more details when -rw (report on
@@ -170,7 +175,7 @@
- fix issue492: avoid leak in test_writeorg. Thanks Marc Abramowitz.
-- fix issue493: don't run tests in doc directory with ``python setup.py test``
+- fix issue493: don't run tests in doc directory with ``python setup.py test``
(use tox -e doctesting for that)
- fix issue486: better reporting and handling of early conftest loading failures
@@ -184,8 +189,8 @@
Groenholm.
- support nose-style ``__test__`` attribute on modules, classes and
- functions, including unittest-style Classes. If set to False, the
- test will not be collected.
+ functions, including unittest-style Classes. If set to False, the
+ test will not be collected.
- fix issue512: show "<notset>" for arguments which might not be set
in monkeypatch plugin. Improves output in documentation.
@@ -195,11 +200,11 @@
-----------------------------------
- fix issue409 -- better interoperate with cx_freeze by not
- trying to import from collections.abc which causes problems
+ trying to import from collections.abc which causes problems
for py27/cx_freeze. Thanks Wolfgang L. for reporting and tracking it down.
- fixed docs and code to use "pytest" instead of "py.test" almost everywhere.
- Thanks Jurko Gospodnetic for the complete PR.
+ Thanks Jurko Gospodnetic for the complete PR.
- fix issue425: mention at end of "py.test -h" that --markers
and --fixtures work according to specified test path (or current dir)
@@ -210,7 +215,7 @@
- copy, cleanup and integrate py.io capture
from pylib 1.4.20.dev2 (rev 13d9af95547e)
-
+
- address issue416: clarify docs as to conftest.py loading semantics
- fix issue429: comparing byte strings with non-ascii chars in assert
@@ -230,7 +235,7 @@
- Allow parameterized fixtures to specify the ID of the parameters by
adding an ids argument to pytest.fixture() and pytest.yield_fixture().
- Thanks Floris Bruynooghe.
+ Thanks Floris Bruynooghe.
- fix issue404 by always using the binary xml escape in the junitxml
plugin. Thanks Ronny Pfannschmidt.
diff -r f829d42dd9f7a5deb4a4e497d8ca08c08fdeba9c -r 23a70aa66ddfe1c7d7f6ce9e431a31a4895443ab _pytest/assertion/util.py
--- a/_pytest/assertion/util.py
+++ b/_pytest/assertion/util.py
@@ -135,18 +135,32 @@
isdict = lambda x: isinstance(x, dict)
isset = lambda x: isinstance(x, (set, frozenset))
+ def isiterable(obj):
+ try:
+ iter(obj)
+ return not istext(obj)
+ except TypeError:
+ return False
+
verbose = config.getoption('verbose')
explanation = None
try:
if op == '==':
if istext(left) and istext(right):
explanation = _diff_text(left, right, verbose)
- elif issequence(left) and issequence(right):
- explanation = _compare_eq_sequence(left, right, verbose)
- elif isset(left) and isset(right):
- explanation = _compare_eq_set(left, right, verbose)
- elif isdict(left) and isdict(right):
- explanation = _compare_eq_dict(left, right, verbose)
+ else:
+ if issequence(left) and issequence(right):
+ explanation = _compare_eq_sequence(left, right, verbose)
+ elif isset(left) and isset(right):
+ explanation = _compare_eq_set(left, right, verbose)
+ elif isdict(left) and isdict(right):
+ explanation = _compare_eq_dict(left, right, verbose)
+ if isiterable(left) and isiterable(right):
+ expl = _compare_eq_iterable(left, right, verbose)
+ if explanation is not None:
+ explanation.extend(expl)
+ else:
+ explanation = expl
elif op == 'not in':
if istext(left) and istext(right):
explanation = _notin_text(left, right, verbose)
@@ -203,6 +217,19 @@
return explanation
+def _compare_eq_iterable(left, right, verbose=False):
+ if not verbose:
+ return [u('Use -v to get the full diff')]
+ # dynamic import to speedup pytest
+ import difflib
+
+ left = pprint.pformat(left).splitlines()
+ right = pprint.pformat(right).splitlines()
+ explanation = [u('Full diff:')]
+ explanation.extend(line.strip() for line in difflib.ndiff(left, right))
+ return explanation
+
+
def _compare_eq_sequence(left, right, verbose=False):
explanation = []
for i in range(min(len(left), len(right))):
diff -r f829d42dd9f7a5deb4a4e497d8ca08c08fdeba9c -r 23a70aa66ddfe1c7d7f6ce9e431a31a4895443ab testing/test_assertion.py
--- a/testing/test_assertion.py
+++ b/testing/test_assertion.py
@@ -1,11 +1,14 @@
# -*- coding: utf-8 -*-
import sys
+import textwrap
import py, pytest
import _pytest.assertion as plugin
from _pytest.assertion import reinterpret
from _pytest.assertion import util
+
needsnewassert = pytest.mark.skipif("sys.version_info < (2,6)")
+PY3 = sys.version_info >= (3, 0)
@pytest.fixture
@@ -86,6 +89,48 @@
expl = callequal([0, 1], [0, 2])
assert len(expl) > 1
+ @pytest.mark.parametrize(
+ ['left', 'right', 'expected'], [
+ ([0, 1], [0, 2], """
+ Full diff:
+ - [0, 1]
+ ? ^
+ + [0, 2]
+ ? ^
+ """),
+ ({0: 1}, {0: 2}, """
+ Full diff:
+ - {0: 1}
+ ? ^
+ + {0: 2}
+ ? ^
+ """),
+ (set([0, 1]), set([0, 2]), """
+ Full diff:
+ - set([0, 1])
+ ? ^
+ + set([0, 2])
+ ? ^
+ """ if not PY3 else """
+ Full diff:
+ - {0, 1}
+ ? ^
+ + {0, 2}
+ ? ^
+ """)
+ ]
+ )
+ def test_iterable_full_diff(self, left, right, expected):
+ """Test the full diff assertion failure explanation.
+
+ When verbose is False, then just a -v notice to get the diff is rendered,
+ when verbose is True, then ndiff of the pprint is returned.
+ """
+ expl = callequal(left, right, verbose=False)
+ assert expl[-1] == 'Use -v to get the full diff'
+ expl = '\n'.join(callequal(left, right, verbose=True))
+ assert expl.endswith(textwrap.dedent(expected).strip())
+
def test_list_different_lenghts(self):
expl = callequal([0, 1], [0, 1, 2])
assert len(expl) > 1
https://bitbucket.org/hpk42/pytest/commits/4f8cc52f3fbd/
Changeset: 4f8cc52f3fbd
User: flub
Date: 2014-09-27 08:09:16+00:00
Summary: Merged in bubenkoff/pytest/better-diff-on-verbose-2 (pull request #213)
Improve assertion failure reporting on iterables, by using ndiff and pprint.
Affected #: 3 files
diff -r f829d42dd9f7a5deb4a4e497d8ca08c08fdeba9c -r 4f8cc52f3fbd64384a8e9ea2c0d7ff34bfb42629 CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,8 @@
+Unreleased
+----------
+
+- Improve assertion failure reporting on iterables, by using ndiff and pprint.
+
2.6.3
-----------
@@ -80,7 +85,7 @@
- fix issue with detecting conftest files if the arguments contain
"::" node id specifications (copy pasted from "-v" output)
-- fix issue544 by only removing "@NUM" at the end of "::" separated parts
+- fix issue544 by only removing "@NUM" at the end of "::" separated parts
and if the part has an ".py" extension
- don't use py.std import helper, rather import things directly.
@@ -93,7 +98,7 @@
- fix issue537: Avoid importing old assertion reinterpretation code by default.
-- fix issue364: shorten and enhance tracebacks representation by default.
+- fix issue364: shorten and enhance tracebacks representation by default.
The new "--tb=auto" option (default) will only display long tracebacks
for the first and last entry. You can get the old behaviour of printing
all entries as long entries with "--tb=long". Also short entries by
@@ -119,14 +124,14 @@
- fix issue473: work around mock putting an unbound method into a class
dict when double-patching.
-- fix issue498: if a fixture finalizer fails, make sure that
+- fix issue498: if a fixture finalizer fails, make sure that
the fixture is still invalidated.
- fix issue453: the result of the pytest_assertrepr_compare hook now gets
it's newlines escaped so that format_exception does not blow up.
- internal new warning system: pytest will now produce warnings when
- it detects oddities in your test collection or execution.
+ it detects oddities in your test collection or execution.
Warnings are ultimately sent to a new pytest_logwarning hook which is
currently only implemented by the terminal plugin which displays
warnings in the summary line and shows more details when -rw (report on
@@ -170,7 +175,7 @@
- fix issue492: avoid leak in test_writeorg. Thanks Marc Abramowitz.
-- fix issue493: don't run tests in doc directory with ``python setup.py test``
+- fix issue493: don't run tests in doc directory with ``python setup.py test``
(use tox -e doctesting for that)
- fix issue486: better reporting and handling of early conftest loading failures
@@ -184,8 +189,8 @@
Groenholm.
- support nose-style ``__test__`` attribute on modules, classes and
- functions, including unittest-style Classes. If set to False, the
- test will not be collected.
+ functions, including unittest-style Classes. If set to False, the
+ test will not be collected.
- fix issue512: show "<notset>" for arguments which might not be set
in monkeypatch plugin. Improves output in documentation.
@@ -195,11 +200,11 @@
-----------------------------------
- fix issue409 -- better interoperate with cx_freeze by not
- trying to import from collections.abc which causes problems
+ trying to import from collections.abc which causes problems
for py27/cx_freeze. Thanks Wolfgang L. for reporting and tracking it down.
- fixed docs and code to use "pytest" instead of "py.test" almost everywhere.
- Thanks Jurko Gospodnetic for the complete PR.
+ Thanks Jurko Gospodnetic for the complete PR.
- fix issue425: mention at end of "py.test -h" that --markers
and --fixtures work according to specified test path (or current dir)
@@ -210,7 +215,7 @@
- copy, cleanup and integrate py.io capture
from pylib 1.4.20.dev2 (rev 13d9af95547e)
-
+
- address issue416: clarify docs as to conftest.py loading semantics
- fix issue429: comparing byte strings with non-ascii chars in assert
@@ -230,7 +235,7 @@
- Allow parameterized fixtures to specify the ID of the parameters by
adding an ids argument to pytest.fixture() and pytest.yield_fixture().
- Thanks Floris Bruynooghe.
+ Thanks Floris Bruynooghe.
- fix issue404 by always using the binary xml escape in the junitxml
plugin. Thanks Ronny Pfannschmidt.
diff -r f829d42dd9f7a5deb4a4e497d8ca08c08fdeba9c -r 4f8cc52f3fbd64384a8e9ea2c0d7ff34bfb42629 _pytest/assertion/util.py
--- a/_pytest/assertion/util.py
+++ b/_pytest/assertion/util.py
@@ -135,18 +135,32 @@
isdict = lambda x: isinstance(x, dict)
isset = lambda x: isinstance(x, (set, frozenset))
+ def isiterable(obj):
+ try:
+ iter(obj)
+ return not istext(obj)
+ except TypeError:
+ return False
+
verbose = config.getoption('verbose')
explanation = None
try:
if op == '==':
if istext(left) and istext(right):
explanation = _diff_text(left, right, verbose)
- elif issequence(left) and issequence(right):
- explanation = _compare_eq_sequence(left, right, verbose)
- elif isset(left) and isset(right):
- explanation = _compare_eq_set(left, right, verbose)
- elif isdict(left) and isdict(right):
- explanation = _compare_eq_dict(left, right, verbose)
+ else:
+ if issequence(left) and issequence(right):
+ explanation = _compare_eq_sequence(left, right, verbose)
+ elif isset(left) and isset(right):
+ explanation = _compare_eq_set(left, right, verbose)
+ elif isdict(left) and isdict(right):
+ explanation = _compare_eq_dict(left, right, verbose)
+ if isiterable(left) and isiterable(right):
+ expl = _compare_eq_iterable(left, right, verbose)
+ if explanation is not None:
+ explanation.extend(expl)
+ else:
+ explanation = expl
elif op == 'not in':
if istext(left) and istext(right):
explanation = _notin_text(left, right, verbose)
@@ -203,6 +217,19 @@
return explanation
+def _compare_eq_iterable(left, right, verbose=False):
+ if not verbose:
+ return [u('Use -v to get the full diff')]
+ # dynamic import to speedup pytest
+ import difflib
+
+ left = pprint.pformat(left).splitlines()
+ right = pprint.pformat(right).splitlines()
+ explanation = [u('Full diff:')]
+ explanation.extend(line.strip() for line in difflib.ndiff(left, right))
+ return explanation
+
+
def _compare_eq_sequence(left, right, verbose=False):
explanation = []
for i in range(min(len(left), len(right))):
diff -r f829d42dd9f7a5deb4a4e497d8ca08c08fdeba9c -r 4f8cc52f3fbd64384a8e9ea2c0d7ff34bfb42629 testing/test_assertion.py
--- a/testing/test_assertion.py
+++ b/testing/test_assertion.py
@@ -1,11 +1,14 @@
# -*- coding: utf-8 -*-
import sys
+import textwrap
import py, pytest
import _pytest.assertion as plugin
from _pytest.assertion import reinterpret
from _pytest.assertion import util
+
needsnewassert = pytest.mark.skipif("sys.version_info < (2,6)")
+PY3 = sys.version_info >= (3, 0)
@pytest.fixture
@@ -86,6 +89,48 @@
expl = callequal([0, 1], [0, 2])
assert len(expl) > 1
+ @pytest.mark.parametrize(
+ ['left', 'right', 'expected'], [
+ ([0, 1], [0, 2], """
+ Full diff:
+ - [0, 1]
+ ? ^
+ + [0, 2]
+ ? ^
+ """),
+ ({0: 1}, {0: 2}, """
+ Full diff:
+ - {0: 1}
+ ? ^
+ + {0: 2}
+ ? ^
+ """),
+ (set([0, 1]), set([0, 2]), """
+ Full diff:
+ - set([0, 1])
+ ? ^
+ + set([0, 2])
+ ? ^
+ """ if not PY3 else """
+ Full diff:
+ - {0, 1}
+ ? ^
+ + {0, 2}
+ ? ^
+ """)
+ ]
+ )
+ def test_iterable_full_diff(self, left, right, expected):
+ """Test the full diff assertion failure explanation.
+
+ When verbose is False, then just a -v notice to get the diff is rendered,
+ when verbose is True, then ndiff of the pprint is returned.
+ """
+ expl = callequal(left, right, verbose=False)
+ assert expl[-1] == 'Use -v to get the full diff'
+ expl = '\n'.join(callequal(left, right, verbose=True))
+ assert expl.endswith(textwrap.dedent(expected).strip())
+
def test_list_different_lenghts(self):
expl = callequal([0, 1], [0, 1, 2])
assert len(expl) > 1
Repository URL: https://bitbucket.org/hpk42/pytest/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
More information about the pytest-commit
mailing list