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