Use a simple ``+-`` ASCII string in the string representation of pytest.approx In Python 2
Fix #2111
This commit is contained in:
parent
5365f7c9ca
commit
57c4489916
|
@ -15,6 +15,11 @@
|
||||||
* Provide ``:ref:`` targets for ``recwarn.rst`` so we can use intersphinx referencing.
|
* Provide ``:ref:`` targets for ``recwarn.rst`` so we can use intersphinx referencing.
|
||||||
Thanks to `@dupuy`_ for the report and `@lwm`_ for the PR.
|
Thanks to `@dupuy`_ for the report and `@lwm`_ for the PR.
|
||||||
|
|
||||||
|
* In Python 2, use a simple ``+-`` ASCII string in the string representation of ``pytest.approx`` (for example ``"4 +- 4.0e-06"``)
|
||||||
|
because it is brittle to handle that in different contexts and representations internally in pytest
|
||||||
|
which can result in bugs such as `#2111`_. In Python 3, the representation still uses ``±`` (for example ``4 ± 4.0e-06``).
|
||||||
|
Thanks `@kerrick-lyft`_ for the report and `@nicoddemus`_ for the PR.
|
||||||
|
|
||||||
* Using ``item.Function``, ``item.Module``, etc., is now issuing deprecation warnings, prefer
|
* Using ``item.Function``, ``item.Module``, etc., is now issuing deprecation warnings, prefer
|
||||||
``pytest.Function``, ``pytest.Module``, etc., instead (`#2034`_).
|
``pytest.Function``, ``pytest.Module``, etc., instead (`#2034`_).
|
||||||
Thanks `@nmundar`_ for the PR.
|
Thanks `@nmundar`_ for the PR.
|
||||||
|
@ -42,25 +47,27 @@
|
||||||
|
|
||||||
*
|
*
|
||||||
|
|
||||||
.. _@mbukatov: https://github.com/mbukatov
|
|
||||||
.. _@dupuy: https://bitbucket.org/dupuy/
|
|
||||||
.. _@d-b-w: https://bitbucket.org/d-b-w/
|
|
||||||
.. _@lwm: https://github.com/lwm
|
|
||||||
.. _@adler-j: https://github.com/adler-j
|
.. _@adler-j: https://github.com/adler-j
|
||||||
|
.. _@d-b-w: https://bitbucket.org/d-b-w/
|
||||||
.. _@DuncanBetts: https://github.com/DuncanBetts
|
.. _@DuncanBetts: https://github.com/DuncanBetts
|
||||||
|
.. _@dupuy: https://bitbucket.org/dupuy/
|
||||||
|
.. _@kerrick-lyft: https://github.com/kerrick-lyft
|
||||||
|
.. _@lwm: https://github.com/lwm
|
||||||
|
.. _@mbukatov: https://github.com/mbukatov
|
||||||
.. _@nedbat: https://github.com/nedbat
|
.. _@nedbat: https://github.com/nedbat
|
||||||
.. _@nmundar: https://github.com/nmundar
|
.. _@nmundar: https://github.com/nmundar
|
||||||
|
|
||||||
.. _#2089: https://github.com/pytest-dev/pytest/issues/2089
|
|
||||||
.. _#478: https://github.com/pytest-dev/pytest/issues/478
|
|
||||||
.. _#687: https://github.com/pytest-dev/pytest/issues/687
|
|
||||||
.. _#2016: https://github.com/pytest-dev/pytest/issues/2016
|
.. _#2016: https://github.com/pytest-dev/pytest/issues/2016
|
||||||
.. _#2034: https://github.com/pytest-dev/pytest/issues/2034
|
.. _#2034: https://github.com/pytest-dev/pytest/issues/2034
|
||||||
.. _#2038: https://github.com/pytest-dev/pytest/issues/2038
|
.. _#2038: https://github.com/pytest-dev/pytest/issues/2038
|
||||||
.. _#2078: https://github.com/pytest-dev/pytest/issues/2078
|
.. _#2078: https://github.com/pytest-dev/pytest/issues/2078
|
||||||
.. _#2082: https://github.com/pytest-dev/pytest/issues/2082
|
.. _#2082: https://github.com/pytest-dev/pytest/issues/2082
|
||||||
|
.. _#2089: https://github.com/pytest-dev/pytest/issues/2089
|
||||||
.. _#2103: https://github.com/pytest-dev/pytest/issues/2103
|
.. _#2103: https://github.com/pytest-dev/pytest/issues/2103
|
||||||
.. _#2105: https://github.com/pytest-dev/pytest/issues/2105
|
.. _#2105: https://github.com/pytest-dev/pytest/issues/2105
|
||||||
|
.. _#2111: https://github.com/pytest-dev/pytest/issues/2111
|
||||||
|
.. _#478: https://github.com/pytest-dev/pytest/issues/478
|
||||||
|
.. _#687: https://github.com/pytest-dev/pytest/issues/687
|
||||||
|
|
||||||
|
|
||||||
3.0.4
|
3.0.4
|
||||||
|
|
|
@ -1434,16 +1434,10 @@ class ApproxNonIterable(object):
|
||||||
except ValueError:
|
except ValueError:
|
||||||
vetted_tolerance = '???'
|
vetted_tolerance = '???'
|
||||||
|
|
||||||
plus_minus = u'{0} \u00b1 {1}'.format(self.expected, vetted_tolerance)
|
|
||||||
|
|
||||||
# In python2, __repr__() must return a string (i.e. not a unicode
|
|
||||||
# object). In python3, __repr__() must return a unicode object
|
|
||||||
# (although now strings are unicode objects and bytes are what
|
|
||||||
# strings were).
|
|
||||||
if sys.version_info[0] == 2:
|
if sys.version_info[0] == 2:
|
||||||
return plus_minus.encode('utf-8')
|
return '{0} +- {1}'.format(self.expected, vetted_tolerance)
|
||||||
else:
|
else:
|
||||||
return plus_minus
|
return u'{0} \u00b1 {1}'.format(self.expected, vetted_tolerance)
|
||||||
|
|
||||||
def __eq__(self, actual):
|
def __eq__(self, actual):
|
||||||
# Short-circuit exact equality.
|
# Short-circuit exact equality.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
import sys
|
||||||
import pytest
|
import pytest
|
||||||
import doctest
|
import doctest
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ from decimal import Decimal
|
||||||
from fractions import Fraction
|
from fractions import Fraction
|
||||||
inf, nan = float('inf'), float('nan')
|
inf, nan = float('inf'), float('nan')
|
||||||
|
|
||||||
|
|
||||||
class MyDocTestRunner(doctest.DocTestRunner):
|
class MyDocTestRunner(doctest.DocTestRunner):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -22,13 +23,17 @@ class MyDocTestRunner(doctest.DocTestRunner):
|
||||||
class TestApprox:
|
class TestApprox:
|
||||||
|
|
||||||
def test_repr_string(self):
|
def test_repr_string(self):
|
||||||
# Just make sure the Unicode handling doesn't raise any exceptions.
|
# for some reason in Python 2.6 it is not displaying the tolerance representation correctly
|
||||||
print(approx(1.0))
|
plus_minus = u'\u00b1' if sys.version_info[0] > 2 else u'+-'
|
||||||
print(approx([1.0, 2.0, 3.0]))
|
tol1, tol2, infr = '1.0e-06', '2.0e-06', 'inf'
|
||||||
print(approx(inf))
|
if sys.version_info[:2] == (2, 6):
|
||||||
print(approx(1.0, rel=nan))
|
tol1, tol2, infr = '???', '???', '???'
|
||||||
print(approx(1.0, rel=inf))
|
assert repr(approx(1.0)) == '1.0 {pm} {tol1}'.format(pm=plus_minus, tol1=tol1)
|
||||||
print(approx(1.0j, rel=inf))
|
assert repr(approx([1.0, 2.0])) == '1.0 {pm} {tol1}, 2.0 {pm} {tol2}'.format(pm=plus_minus, tol1=tol1, tol2=tol2)
|
||||||
|
assert repr(approx(inf)) == 'inf'
|
||||||
|
assert repr(approx(1.0, rel=nan)) == '1.0 {pm} ???'.format(pm=plus_minus)
|
||||||
|
assert repr(approx(1.0, rel=inf)) == '1.0 {pm} {infr}'.format(pm=plus_minus, infr=infr)
|
||||||
|
assert repr(approx(1.0j, rel=inf)) == '1j'
|
||||||
|
|
||||||
def test_operator_overloading(self):
|
def test_operator_overloading(self):
|
||||||
assert 1 == approx(1, rel=1e-6, abs=1e-12)
|
assert 1 == approx(1, rel=1e-6, abs=1e-12)
|
||||||
|
@ -285,3 +290,23 @@ class TestApprox:
|
||||||
runner = MyDocTestRunner()
|
runner = MyDocTestRunner()
|
||||||
runner.run(test)
|
runner.run(test)
|
||||||
|
|
||||||
|
def test_unicode_plus_minus(self, testdir):
|
||||||
|
"""
|
||||||
|
Comparing approx instances inside lists should not produce an error in the detailed diff.
|
||||||
|
Integration test for issue #2111.
|
||||||
|
"""
|
||||||
|
testdir.makepyfile("""
|
||||||
|
import pytest
|
||||||
|
def test_foo():
|
||||||
|
assert [3] == [pytest.approx(4)]
|
||||||
|
""")
|
||||||
|
expected = '4.0e-06'
|
||||||
|
# for some reason in Python 2.6 it is not displaying the tolerance representation correctly
|
||||||
|
if sys.version_info[:2] == (2, 6):
|
||||||
|
expected = '???'
|
||||||
|
result = testdir.runpytest()
|
||||||
|
result.stdout.fnmatch_lines([
|
||||||
|
'*At index 0 diff: 3 != 4 * {0}'.format(expected),
|
||||||
|
'=* 1 failed in *=',
|
||||||
|
])
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue