diff --git a/AUTHORS b/AUTHORS index 1311cc83c..75f66b0b9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -26,6 +26,7 @@ Dave Hunt David Mohr Eduardo Schettino Florian Bruhin +Edison Gustavo Muenz Floris Bruynooghe Graham Horler Grig Gheorghiu diff --git a/CHANGELOG b/CHANGELOG index 761fa7914..fd8ce8e4a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -68,6 +68,10 @@ 2.7.2 (compared to 2.7.1) ----------------------------- +- fix issue767: pytest.raises value attribute does not contain the exception + instance on Python 2.6. Thanks Eric Siegerman for providing the test + case and Bruno Oliveira for PR. + - Automatically create directory for junitxml and results log. Thanks Aron Curzon. @@ -83,6 +87,13 @@ - fix issue748: unittest.SkipTest reports to internal pytest unittest plugin. Thanks Thomas De Schampheleire for reporting and Bruno Oliveira for the PR. +- fix issue718: failed to create representation of sets containing unsortable + elements in python 2. Thanks Edison Gustavo Muenz + +- fix issue756, fix issue752 (and similar issues): depend on py-1.4.29 + which has a refined algorithm for traceback generation. + + 2.7.1 (compared to 2.7.0) ----------------------------- diff --git a/_pytest/assertion/util.py b/_pytest/assertion/util.py index 07389e781..fb5f9be0e 100644 --- a/_pytest/assertion/util.py +++ b/_pytest/assertion/util.py @@ -225,10 +225,18 @@ def _compare_eq_iterable(left, right, verbose=False): # 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)) + try: + left_formatting = pprint.pformat(left).splitlines() + right_formatting = pprint.pformat(right).splitlines() + explanation = [u('Full diff:')] + except Exception: + # hack: PrettyPrinter.pformat() in python 2 fails when formatting items that can't be sorted(), ie, calling + # sorted() on a list would raise. See issue #718. + # As a workaround, the full diff is generated by using the repr() string of each item of each container. + left_formatting = sorted(repr(x) for x in left) + right_formatting = sorted(repr(x) for x in right) + explanation = [u('Full diff (fallback to calling repr on each item):')] + explanation.extend(line.strip() for line in difflib.ndiff(left_formatting, right_formatting)) return explanation diff --git a/_pytest/python.py b/_pytest/python.py index 3acbf2eb2..b28baad2f 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1115,6 +1115,13 @@ class RaisesContext(object): __tracebackhide__ = True if tp[0] is None: pytest.fail("DID NOT RAISE") + if sys.version_info < (2, 7): + # py26: on __exit__() exc_value often does not contain the + # exception value. + # http://bugs.python.org/issue7853 + if not isinstance(tp[1], BaseException): + exc_type, value, traceback = tp + tp = exc_type, exc_type(value), traceback self.excinfo.__init__(tp) return issubclass(self.excinfo.type, self.ExpectedException) diff --git a/doc/en/announce/release-2.7.2.txt b/doc/en/announce/release-2.7.2.txt new file mode 100644 index 000000000..69130ad62 --- /dev/null +++ b/doc/en/announce/release-2.7.2.txt @@ -0,0 +1,58 @@ +pytest-2.7.2: bug fixes +======================= + +pytest is a mature Python testing tool with more than a 1100 tests +against itself, passing on many different interpreters and platforms. +This release is supposed to be drop-in compatible to 2.7.1. + +See below for the changes and see docs at: + + http://pytest.org + +As usual, you can upgrade from pypi via:: + + pip install -U pytest + +Thanks to all who contributed to this release, among them: + + Bruno Oliveira + Floris Bruynooghe + Punyashloka Biswal + Aron Curzon + Benjamin Peterson + Thomas De Schampheleire + Edison Gustavo Muenz + Holger Krekel + +Happy testing, +The py.test Development Team + + +2.7.2 (compared to 2.7.1) +----------------------------- + +- fix issue767: pytest.raises value attribute does not contain the exception + instance on Python 2.6. Thanks Eric Siegerman for providing the test + case and Bruno Oliveira for PR. + +- Automatically create directory for junitxml and results log. + Thanks Aron Curzon. + +- fix issue713: JUnit XML reports for doctest failures. + Thanks Punyashloka Biswal. + +- fix issue735: assertion failures on debug versions of Python 3.4+ + Thanks Benjamin Peterson. + +- fix issue114: skipif marker reports to internal skipping plugin; + Thanks Floris Bruynooghe for reporting and Bruno Oliveira for the PR. + +- fix issue748: unittest.SkipTest reports to internal pytest unittest plugin. + Thanks Thomas De Schampheleire for reporting and Bruno Oliveira for the PR. + +- fix issue718: failed to create representation of sets containing unsortable + elements in python 2. Thanks Edison Gustavo Muenz + +- fix issue756, fix issue752 (and similar issues): depend on py-1.4.29 + which has a refined algorithm for traceback generation. + diff --git a/doc/en/goodpractises.txt b/doc/en/goodpractises.txt index 9e2b0cd97..3ec36219d 100644 --- a/doc/en/goodpractises.txt +++ b/doc/en/goodpractises.txt @@ -1,7 +1,7 @@ .. highlightlang:: python .. _`goodpractises`: -Good Integration Practises +Good Integration Practices ================================================= Work with virtual environments diff --git a/setup.py b/setup.py index 7f15c5762..218c14da8 100644 --- a/setup.py +++ b/setup.py @@ -48,7 +48,7 @@ def has_environment_marker_support(): def main(): - install_requires = ['py>=1.4.27', 'pluggy>=0.3.0,<0.4.0'] + install_requires = ['py>=1.4.29', 'pluggy>=0.3.0,<0.4.0'] extras_require = {} if has_environment_marker_support(): extras_require[':python_version=="2.6" or python_version=="3.0" or python_version=="3.1"'] = ['argparse'] diff --git a/testing/python/raises.py b/testing/python/raises.py index 5caa810e2..5ba56bb71 100644 --- a/testing/python/raises.py +++ b/testing/python/raises.py @@ -46,6 +46,7 @@ class TestRaises: 1/0 print (excinfo) assert excinfo.type == ZeroDivisionError + assert isinstance(excinfo.value, ZeroDivisionError) def test_noraise(): with pytest.raises(pytest.raises.Exception): diff --git a/testing/test_assertion.py b/testing/test_assertion.py index a883ca8cb..492bc2f08 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -569,3 +569,39 @@ def test_AssertionError_message(testdir): *assert 0, (x,y)* *AssertionError: (1, 2)* """) + +@pytest.mark.skipif(PY3, reason='This bug does not exist on PY3') +def test_set_with_unsortable_elements(): + # issue #718 + class UnsortableKey(object): + def __init__(self, name): + self.name = name + + def __lt__(self, other): + raise RuntimeError() + + def __repr__(self): + return 'repr({0})'.format(self.name) + + def __eq__(self, other): + return self.name == other.name + + def __hash__(self): + return hash(self.name) + + left_set = set(UnsortableKey(str(i)) for i in range(1, 3)) + right_set = set(UnsortableKey(str(i)) for i in range(2, 4)) + expl = callequal(left_set, right_set, verbose=True) + # skip first line because it contains the "construction" of the set, which does not have a guaranteed order + expl = expl[1:] + dedent = textwrap.dedent(""" + Extra items in the left set: + repr(1) + Extra items in the right set: + repr(3) + Full diff (fallback to calling repr on each item): + - repr(1) + repr(2) + + repr(3) + """).strip() + assert '\n'.join(expl) == dedent diff --git a/testing/test_conftest.py b/testing/test_conftest.py index cc2c63ae0..4f967c915 100644 --- a/testing/test_conftest.py +++ b/testing/test_conftest.py @@ -160,6 +160,7 @@ def test_conftest_confcutdir(testdir): """)) result = testdir.runpytest("-h", "--confcutdir=%s" % x, x) result.stdout.fnmatch_lines(["*--xyz*"]) + assert 'warning: could not load initial' not in result.stdout.str() def test_conftest_existing_resultlog(testdir): x = testdir.mkdir("tests") diff --git a/tox.ini b/tox.ini index ffea634c3..3b307ba7d 100644 --- a/tox.ini +++ b/tox.ini @@ -1,10 +1,13 @@ [tox] +minversion=2.0 distshare={homedir}/.tox/distshare -envlist=flakes,py26,py27,py34,pypy,py27-pexpect,py33-pexpect,py27-nobyte,py33,py27-xdist,py33-xdist,{py27,py33}-trial,py27-subprocess,doctesting,py27-cxfreeze +envlist= + flakes,py26,py27,py33,py34,pypy, + {py27,py34}-{pexpect,xdist,trial}, + py27-nobyte,doctesting,py27-cxfreeze [testenv] -changedir=testing -commands= py.test --lsof -rfsxX --junitxml={envlogdir}/junit-{envname}.xml [] +commands= py.test --lsof -rfsxX {posargs:testing} deps= nose mock @@ -19,75 +22,59 @@ commands= py.test -n3 -rfsxX --runpytest=subprocess {posargs:testing} [testenv:genscript] -changedir=. commands= py.test --genscript=pytest1 [testenv:flakes] -changedir= deps = pytest-flakes>=0.2 commands = py.test --flakes -m flakes _pytest testing [testenv:py27-xdist] -changedir=. -basepython=python2.7 deps=pytest-xdist mock nose commands= - py.test -n1 -rfsxX \ - --junitxml={envlogdir}/junit-{envname}.xml {posargs:testing} + py.test -n1 -rfsxX {posargs:testing} -[testenv:py33-xdist] -changedir=. -basepython=python3.3 +[testenv:py34-xdist] deps={[testenv:py27-xdist]deps} commands= - py.test -n3 -rfsxX \ - --junitxml={envlogdir}/junit-{envname}.xml {posargs:testing} + py.test -n3 -rfsxX {posargs:testing} [testenv:py27-pexpect] changedir=testing -basepython=python2.7 +platform=linux|darwin deps=pexpect commands= py.test -rfsxX test_pdb.py test_terminal.py test_unittest.py -[testenv:py33-pexpect] +[testenv:py34-pexpect] changedir=testing -basepython=python3.3 +platform=linux|darwin deps={[testenv:py27-pexpect]deps} commands= py.test -rfsxX test_pdb.py test_terminal.py test_unittest.py [testenv:py27-nobyte] -changedir=. -basepython=python2.7 deps=pytest-xdist distribute=true setenv= PYTHONDONTWRITEBYTECODE=1 commands= - py.test -n3 -rfsxX \ - --junitxml={envlogdir}/junit-{envname}.xml {posargs:testing} + py.test -n3 -rfsxX {posargs:testing} [testenv:py27-trial] -changedir=. -basepython=python2.7 deps=twisted commands= - py.test -rsxf \ - --junitxml={envlogdir}/junit-{envname}.xml {posargs:testing/test_unittest.py} + py.test -rsxf {posargs:testing/test_unittest.py} -[testenv:py33-trial] -changedir=. -basepython=python3.3 +[testenv:py34-trial] +# py34-trial does not work +platform=linux|darwin deps={[testenv:py27-trial]deps} commands= - py.test -rsxf \ - --junitxml={envlogdir}/junit-{envname}.xml {posargs:testing/test_unittest.py} + py.test -rsxf {posargs:testing/test_unittest.py} [testenv:doctest] -changedir=. commands=py.test --doctest-modules _pytest deps= @@ -103,13 +90,11 @@ commands= make html [testenv:doctesting] -basepython=python3.3 changedir=doc/en deps=PyYAML -commands= py.test -rfsxX --junitxml={envlogdir}/junit-{envname}.xml [] +commands= py.test -rfsxX {posargs} [testenv:regen] -basepython=python3.4 changedir=doc/en deps=sphinx PyYAML @@ -118,34 +103,25 @@ commands= #pip install pytest==2.3.4 make regen -[testenv:py31] -deps=nose>=1.0 - -[testenv:py31-xdist] -deps=pytest-xdist -commands= - py.test -n3 -rfsxX \ - --junitxml={envlogdir}/junit-{envname}.xml [] - [testenv:jython] changedir=testing commands= - {envpython} {envbindir}/py.test-jython \ - -rfsxX --junitxml={envlogdir}/junit-{envname}2.xml [] + {envpython} {envbindir}/py.test-jython -rfsxX {posargs} [testenv:py27-cxfreeze] changedir=testing/cx_freeze -basepython=python2.7 +platform=linux|darwin commands= {envpython} install_cx_freeze.py {envpython} runtests_setup.py build --build-exe build {envpython} tox_run.py + [testenv:coveralls] passenv = TRAVIS TRAVIS_JOB_ID TRAVIS_BRANCH -changedir= usedevelop=True basepython=python3.4 +changedir=testing deps = {[testenv]deps} coveralls @@ -164,4 +140,4 @@ python_files=test_*.py *_test.py testing/*/*.py python_classes=Test Acceptance python_functions=test pep8ignore = E401 E225 E261 E128 E124 E302 -norecursedirs = .tox ja .hg +norecursedirs = .tox ja .hg cx_freeze_source