From 4ddd89780fdb823f427c743ea7326a3c958a2f4b Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Mon, 20 Feb 2017 20:28:15 +0000 Subject: [PATCH 1/2] bpo-29602: fix signed zero handling in complex constructor --- Lib/test/test_complex.py | 29 +++++++++++++++++++++++++++++ Misc/NEWS | 4 ++++ Objects/complexobject.c | 6 +++--- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py index c0383b27e66c03..6a82e06e12e283 100644 --- a/Lib/test/test_complex.py +++ b/Lib/test/test_complex.py @@ -8,6 +8,12 @@ NAN = float("nan") # These tests ensure that complex math does the right thing +# decorator for skipping tests on non-IEEE 754 platforms +requires_IEEE_754 = unittest.skipUnless(have_getformat and + float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + + class ComplexTest(unittest.TestCase): def assertAlmostEqual(self, a, b): @@ -441,6 +447,29 @@ def __rmod__(self,other): b = 'y %s x' % op self.assertTrue(type(eval(a)) is type(eval(b)) is xcomplex) + @requires_IEEE_754 + def test_constructor_special_numbers(self): + class complex2(complex): + pass + for x in 0.0, -0.0, INF, -INF, NAN: + for y in 0.0, -0.0, INF, -INF, NAN: + with self.subTest(x=x, y=y): + z = complex(x, y) + self.assertFloatsAreIdentical(z.real, x) + self.assertFloatsAreIdentical(z.imag, y) + z = complex2(x, y) + self.assertIs(type(z), complex2) + self.assertFloatsAreIdentical(z.real, x) + self.assertFloatsAreIdentical(z.imag, y) + z = complex(complex2(x, y)) + self.assertIs(type(z), complex) + self.assertFloatsAreIdentical(z.real, x) + self.assertFloatsAreIdentical(z.imag, y) + z = complex2(complex(x, y)) + self.assertIs(type(z), complex2) + self.assertFloatsAreIdentical(z.real, x) + self.assertFloatsAreIdentical(z.imag, y) + def test_hash(self): for x in xrange(-30, 30): self.assertEqual(hash(x), hash(complex(x, 0))) diff --git a/Misc/NEWS b/Misc/NEWS index 8726996a4bc18c..6551a6d34133c0 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,10 @@ What's New in Python 2.7.14? Core and Builtins ----------------- +- bpo-29602: Fix incorrect handling of signed zeros in complex constructor for + complex subclasses and for inputs having a __complex__ method. Patch + by Serhiy Storchaka. + - bpo-29347: Fixed possibly dereferencing undefined pointers when creating weakref objects. diff --git a/Objects/complexobject.c b/Objects/complexobject.c index ef18e3fea200e5..aaefa2dcda8a41 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -1232,11 +1232,11 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } cr.real = PyFloat_AsDouble(tmp); - cr.imag = 0.0; /* Shut up compiler warning */ + cr.imag = 0.0; Py_DECREF(tmp); } if (i == NULL) { - ci.real = 0.0; + ci.real = cr.imag; } else if (PyComplex_Check(i)) { ci = ((PyComplexObject*)i)->cval; @@ -1258,7 +1258,7 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (ci_is_complex) { cr.real -= ci.imag; } - if (cr_is_complex) { + if (cr_is_complex && i != NULL) { ci.real += cr.imag; } return complex_subtype_from_doubles(type, cr.real, ci.real); From 23e14d6763cec97c2fd6384df0820dfa2f4e461a Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Mon, 20 Feb 2017 20:53:12 +0000 Subject: [PATCH 2/2] Add missing have_getformat definition; remove use of unittest subtests. --- Lib/test/test_complex.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py index 6a82e06e12e283..02b292f4bbfe3f 100644 --- a/Lib/test/test_complex.py +++ b/Lib/test/test_complex.py @@ -9,6 +9,7 @@ # These tests ensure that complex math does the right thing # decorator for skipping tests on non-IEEE 754 platforms +have_getformat = hasattr(float, "__getformat__") requires_IEEE_754 = unittest.skipUnless(have_getformat and float.__getformat__("double").startswith("IEEE"), "test requires IEEE 754 doubles") @@ -453,22 +454,21 @@ class complex2(complex): pass for x in 0.0, -0.0, INF, -INF, NAN: for y in 0.0, -0.0, INF, -INF, NAN: - with self.subTest(x=x, y=y): - z = complex(x, y) - self.assertFloatsAreIdentical(z.real, x) - self.assertFloatsAreIdentical(z.imag, y) - z = complex2(x, y) - self.assertIs(type(z), complex2) - self.assertFloatsAreIdentical(z.real, x) - self.assertFloatsAreIdentical(z.imag, y) - z = complex(complex2(x, y)) - self.assertIs(type(z), complex) - self.assertFloatsAreIdentical(z.real, x) - self.assertFloatsAreIdentical(z.imag, y) - z = complex2(complex(x, y)) - self.assertIs(type(z), complex2) - self.assertFloatsAreIdentical(z.real, x) - self.assertFloatsAreIdentical(z.imag, y) + z = complex(x, y) + self.assertFloatsAreIdentical(z.real, x) + self.assertFloatsAreIdentical(z.imag, y) + z = complex2(x, y) + self.assertIs(type(z), complex2) + self.assertFloatsAreIdentical(z.real, x) + self.assertFloatsAreIdentical(z.imag, y) + z = complex(complex2(x, y)) + self.assertIs(type(z), complex) + self.assertFloatsAreIdentical(z.real, x) + self.assertFloatsAreIdentical(z.imag, y) + z = complex2(complex(x, y)) + self.assertIs(type(z), complex2) + self.assertFloatsAreIdentical(z.real, x) + self.assertFloatsAreIdentical(z.imag, y) def test_hash(self): for x in xrange(-30, 30): pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy