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.
 | 
			
		||||
  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
 | 
			
		||||
  ``pytest.Function``, ``pytest.Module``, etc., instead (`#2034`_).
 | 
			
		||||
  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
 | 
			
		||||
.. _@d-b-w: https://bitbucket.org/d-b-w/
 | 
			
		||||
.. _@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
 | 
			
		||||
.. _@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
 | 
			
		||||
.. _#2034: https://github.com/pytest-dev/pytest/issues/2034
 | 
			
		||||
.. _#2038: https://github.com/pytest-dev/pytest/issues/2038
 | 
			
		||||
.. _#2078: https://github.com/pytest-dev/pytest/issues/2078
 | 
			
		||||
.. _#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
 | 
			
		||||
.. _#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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1434,16 +1434,10 @@ class ApproxNonIterable(object):
 | 
			
		|||
        except ValueError:
 | 
			
		||||
            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:
 | 
			
		||||
            return plus_minus.encode('utf-8')
 | 
			
		||||
            return '{0} +- {1}'.format(self.expected, vetted_tolerance)
 | 
			
		||||
        else:
 | 
			
		||||
            return plus_minus
 | 
			
		||||
            return u'{0} \u00b1 {1}'.format(self.expected, vetted_tolerance)
 | 
			
		||||
 | 
			
		||||
    def __eq__(self, actual):
 | 
			
		||||
        # Short-circuit exact equality.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
# encoding: utf-8
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
import pytest
 | 
			
		||||
import doctest
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -9,6 +9,7 @@ from decimal import Decimal
 | 
			
		|||
from fractions import Fraction
 | 
			
		||||
inf, nan = float('inf'), float('nan')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MyDocTestRunner(doctest.DocTestRunner):
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
| 
						 | 
				
			
			@ -22,13 +23,17 @@ class MyDocTestRunner(doctest.DocTestRunner):
 | 
			
		|||
class TestApprox:
 | 
			
		||||
 | 
			
		||||
    def test_repr_string(self):
 | 
			
		||||
        # Just make sure the Unicode handling doesn't raise any exceptions.
 | 
			
		||||
        print(approx(1.0))
 | 
			
		||||
        print(approx([1.0, 2.0, 3.0]))
 | 
			
		||||
        print(approx(inf))
 | 
			
		||||
        print(approx(1.0, rel=nan))
 | 
			
		||||
        print(approx(1.0, rel=inf))
 | 
			
		||||
        print(approx(1.0j, rel=inf))
 | 
			
		||||
        # for some reason in Python 2.6 it is not displaying the tolerance representation correctly
 | 
			
		||||
        plus_minus = u'\u00b1' if sys.version_info[0] > 2 else u'+-'
 | 
			
		||||
        tol1, tol2, infr = '1.0e-06', '2.0e-06', 'inf'
 | 
			
		||||
        if sys.version_info[:2] == (2, 6):
 | 
			
		||||
            tol1, tol2, infr = '???', '???', '???'
 | 
			
		||||
        assert repr(approx(1.0)) == '1.0 {pm} {tol1}'.format(pm=plus_minus, tol1=tol1)
 | 
			
		||||
        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):
 | 
			
		||||
        assert 1 == approx(1, rel=1e-6, abs=1e-12)
 | 
			
		||||
| 
						 | 
				
			
			@ -285,3 +290,23 @@ class TestApprox:
 | 
			
		|||
        runner = MyDocTestRunner()
 | 
			
		||||
        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