Skip to content

Commit 0936a00

Browse files
authored
bpo-29602: fix signed zero handling in complex constructor. (#203) (#205)
* Fix incorrect handling of signed zeros for complex-related classes. * Add Misc/NEWS entry. (cherry picked from commit 112ec38)
1 parent 66fa9d4 commit 0936a00

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

Lib/test/test_complex.py

+23
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,29 @@ def __complex__(self):
385385
self.assertAlmostEqual(complex(complex1(1j)), 2j)
386386
self.assertRaises(TypeError, complex, complex2(1j))
387387

388+
@support.requires_IEEE_754
389+
def test_constructor_special_numbers(self):
390+
class complex2(complex):
391+
pass
392+
for x in 0.0, -0.0, INF, -INF, NAN:
393+
for y in 0.0, -0.0, INF, -INF, NAN:
394+
with self.subTest(x=x, y=y):
395+
z = complex(x, y)
396+
self.assertFloatsAreIdentical(z.real, x)
397+
self.assertFloatsAreIdentical(z.imag, y)
398+
z = complex2(x, y)
399+
self.assertIs(type(z), complex2)
400+
self.assertFloatsAreIdentical(z.real, x)
401+
self.assertFloatsAreIdentical(z.imag, y)
402+
z = complex(complex2(x, y))
403+
self.assertIs(type(z), complex)
404+
self.assertFloatsAreIdentical(z.real, x)
405+
self.assertFloatsAreIdentical(z.imag, y)
406+
z = complex2(complex(x, y))
407+
self.assertIs(type(z), complex2)
408+
self.assertFloatsAreIdentical(z.real, x)
409+
self.assertFloatsAreIdentical(z.imag, y)
410+
388411
def test_hash(self):
389412
for x in range(-30, 30):
390413
self.assertEqual(hash(x), hash(complex(x, 0)))

Misc/NEWS

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ Release date: XXXX-XX-XX
1010
Core and Builtins
1111
-----------------
1212

13+
- bpo-29602: Fix incorrect handling of signed zeros in complex constructor for
14+
complex subclasses and for inputs having a __complex__ method. Patch
15+
by Serhiy Storchaka.
16+
1317
- bpo-29347: Fixed possibly dereferencing undefined pointers
1418
when creating weakref objects.
1519

Objects/complexobject.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -1014,11 +1014,11 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
10141014
return NULL;
10151015
}
10161016
cr.real = PyFloat_AsDouble(tmp);
1017-
cr.imag = 0.0; /* Shut up compiler warning */
1017+
cr.imag = 0.0;
10181018
Py_DECREF(tmp);
10191019
}
10201020
if (i == NULL) {
1021-
ci.real = 0.0;
1021+
ci.real = cr.imag;
10221022
}
10231023
else if (PyComplex_Check(i)) {
10241024
ci = ((PyComplexObject*)i)->cval;
@@ -1040,7 +1040,7 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
10401040
if (ci_is_complex) {
10411041
cr.real -= ci.imag;
10421042
}
1043-
if (cr_is_complex) {
1043+
if (cr_is_complex && i != NULL) {
10441044
ci.real += cr.imag;
10451045
}
10461046
return complex_subtype_from_doubles(type, cr.real, ci.real);

0 commit comments

Comments
 (0)