Skip to content

Commit 112ec38

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

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

Lib/test/test_complex.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,29 @@ def __complex__(self):
387387
self.assertAlmostEqual(complex(complex1(1j)), 2j)
388388
self.assertRaises(TypeError, complex, complex2(1j))
389389

390+
@support.requires_IEEE_754
391+
def test_constructor_special_numbers(self):
392+
class complex2(complex):
393+
pass
394+
for x in 0.0, -0.0, INF, -INF, NAN:
395+
for y in 0.0, -0.0, INF, -INF, NAN:
396+
with self.subTest(x=x, y=y):
397+
z = complex(x, y)
398+
self.assertFloatsAreIdentical(z.real, x)
399+
self.assertFloatsAreIdentical(z.imag, y)
400+
z = complex2(x, y)
401+
self.assertIs(type(z), complex2)
402+
self.assertFloatsAreIdentical(z.real, x)
403+
self.assertFloatsAreIdentical(z.imag, y)
404+
z = complex(complex2(x, y))
405+
self.assertIs(type(z), complex)
406+
self.assertFloatsAreIdentical(z.real, x)
407+
self.assertFloatsAreIdentical(z.imag, y)
408+
z = complex2(complex(x, y))
409+
self.assertIs(type(z), complex2)
410+
self.assertFloatsAreIdentical(z.real, x)
411+
self.assertFloatsAreIdentical(z.imag, y)
412+
390413
def test_underscores(self):
391414
# check underscores
392415
for lit in VALID_UNDERSCORE_LITERALS:

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ What's New in Python 3.7.0 alpha 1?
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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,11 +1025,11 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
10251025
return NULL;
10261026
}
10271027
cr.real = PyFloat_AsDouble(tmp);
1028-
cr.imag = 0.0; /* Shut up compiler warning */
1028+
cr.imag = 0.0;
10291029
Py_DECREF(tmp);
10301030
}
10311031
if (i == NULL) {
1032-
ci.real = 0.0;
1032+
ci.real = cr.imag;
10331033
}
10341034
else if (PyComplex_Check(i)) {
10351035
ci = ((PyComplexObject*)i)->cval;
@@ -1051,7 +1051,7 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
10511051
if (ci_is_complex) {
10521052
cr.real -= ci.imag;
10531053
}
1054-
if (cr_is_complex) {
1054+
if (cr_is_complex && i != NULL) {
10551055
ci.real += cr.imag;
10561056
}
10571057
return complex_subtype_from_doubles(type, cr.real, ci.real);

0 commit comments

Comments
 (0)