gh-109218: Deprecate weird cases in the complex() constructor (GH-119… · python/cpython@ef01e95 · GitHub
Skip to content

Commit ef01e95

Browse files
gh-109218: Deprecate weird cases in the complex() constructor (GH-119620)
* Passing a string as the "real" keyword argument is now an error; it should only be passed as a single positional argument. * Passing a complex number as the "real" or "imag" argument is now deprecated; it should only be passed as a single positional argument.
1 parent deda857 commit ef01e95

6 files changed

Lines changed: 164 additions & 61 deletions

File tree

Doc/library/functions.rst

Lines changed: 4 additions & 0 deletions

Doc/whatsnew/3.14.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ Optimizations
103103
Deprecated
104104
==========
105105

106+
* Passing a complex number as the *real* or *imag* argument in the
107+
:func:`complex` constructor is now deprecated; it should only be passed
108+
as a single positional argument.
109+
(Contributed by Serhiy Storchaka in :gh:`109218`.)
106110

107111

108112
Removed

Lib/test/test_complex.py

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -382,25 +382,53 @@ def check(z, x, y):
382382
check(complex(1.0, 10.0), 1.0, 10.0)
383383
check(complex(4.25, 0.5), 4.25, 0.5)
384384

385-
check(complex(4.25+0j, 0), 4.25, 0.0)
386-
check(complex(ComplexSubclass(4.25+0j), 0), 4.25, 0.0)
387-
check(complex(WithComplex(4.25+0j), 0), 4.25, 0.0)
388-
check(complex(4.25j, 0), 0.0, 4.25)
389-
check(complex(0j, 4.25), 0.0, 4.25)
390-
check(complex(0, 4.25+0j), 0.0, 4.25)
391-
check(complex(0, ComplexSubclass(4.25+0j)), 0.0, 4.25)
385+
with self.assertWarnsRegex(DeprecationWarning,
386+
"argument 'real' must be a real number, not complex"):
387+
check(complex(4.25+0j, 0), 4.25, 0.0)
388+
with self.assertWarnsRegex(DeprecationWarning,
389+
"argument 'real' must be a real number, not .*ComplexSubclass"):
390+
check(complex(ComplexSubclass(4.25+0j), 0), 4.25, 0.0)
391+
with self.assertWarnsRegex(DeprecationWarning,
392+
"argument 'real' must be a real number, not .*WithComplex"):
393+
check(complex(WithComplex(4.25+0j), 0), 4.25, 0.0)
394+
with self.assertWarnsRegex(DeprecationWarning,
395+
"argument 'real' must be a real number, not complex"):
396+
check(complex(4.25j, 0), 0.0, 4.25)
397+
with self.assertWarnsRegex(DeprecationWarning,
398+
"argument 'real' must be a real number, not complex"):
399+
check(complex(0j, 4.25), 0.0, 4.25)
400+
with self.assertWarnsRegex(DeprecationWarning,
401+
"argument 'imag' must be a real number, not complex"):
402+
check(complex(0, 4.25+0j), 0.0, 4.25)
403+
with self.assertWarnsRegex(DeprecationWarning,
404+
"argument 'imag' must be a real number, not .*ComplexSubclass"):
405+
check(complex(0, ComplexSubclass(4.25+0j)), 0.0, 4.25)
392406
with self.assertRaisesRegex(TypeError,
393-
"second argument must be a number, not 'WithComplex'"):
407+
"argument 'imag' must be a real number, not .*WithComplex"):
394408
complex(0, WithComplex(4.25+0j))
395-
check(complex(0.0, 4.25j), -4.25, 0.0)
396-
check(complex(4.25+0j, 0j), 4.25, 0.0)
397-
check(complex(4.25j, 0j), 0.0, 4.25)
398-
check(complex(0j, 4.25+0j), 0.0, 4.25)
399-
check(complex(0j, 4.25j), -4.25, 0.0)
409+
with self.assertWarnsRegex(DeprecationWarning,
410+
"argument 'imag' must be a real number, not complex"):
411+
check(complex(0.0, 4.25j), -4.25, 0.0)
412+
with self.assertWarnsRegex(DeprecationWarning,
413+
"argument 'real' must be a real number, not complex"):
414+
check(complex(4.25+0j, 0j), 4.25, 0.0)
415+
with self.assertWarnsRegex(DeprecationWarning,
416+
"argument 'real' must be a real number, not complex"):
417+
check(complex(4.25j, 0j), 0.0, 4.25)
418+
with self.assertWarnsRegex(DeprecationWarning,
419+
"argument 'real' must be a real number, not complex"):
420+
check(complex(0j, 4.25+0j), 0.0, 4.25)
421+
with self.assertWarnsRegex(DeprecationWarning,
422+
"argument 'real' must be a real number, not complex"):
423+
check(complex(0j, 4.25j), -4.25, 0.0)
400424

401425
check(complex(real=4.25), 4.25, 0.0)
402-
check(complex(real=4.25+0j), 4.25, 0.0)
403-
check(complex(real=4.25+1.5j), 4.25, 1.5)
426+
with self.assertWarnsRegex(DeprecationWarning,
427+
"argument 'real' must be a real number, not complex"):
428+
check(complex(real=4.25+0j), 4.25, 0.0)
429+
with self.assertWarnsRegex(DeprecationWarning,
430+
"argument 'real' must be a real number, not complex"):
431+
check(complex(real=4.25+1.5j), 4.25, 1.5)
404432
check(complex(imag=1.5), 0.0, 1.5)
405433
check(complex(real=4.25, imag=1.5), 4.25, 1.5)
406434
check(complex(4.25, imag=1.5), 4.25, 1.5)
@@ -420,22 +448,22 @@ def check(z, x, y):
420448
del c, c2
421449

422450
self.assertRaisesRegex(TypeError,
423-
"first argument must be a string or a number, not 'dict'",
451+
"argument must be a string or a number, not dict",
424452
complex, {})
425453
self.assertRaisesRegex(TypeError,
426-
"first argument must be a string or a number, not 'NoneType'",
454+
"argument must be a string or a number, not NoneType",
427455
complex, None)
428456
self.assertRaisesRegex(TypeError,
429-
"first argument must be a string or a number, not 'dict'",
457+
"argument 'real' must be a real number, not dict",
430458
complex, {1:2}, 0)
431459
self.assertRaisesRegex(TypeError,
432-
"can't take second arg if first is a string",
460+
"argument 'real' must be a real number, not str",
433461
complex, '1', 0)
434462
self.assertRaisesRegex(TypeError,
435-
"second argument must be a number, not 'dict'",
463+
"argument 'imag' must be a real number, not dict",
436464
complex, 0, {1:2})
437465
self.assertRaisesRegex(TypeError,
438-
"second arg can't be a string",
466+
"argument 'imag' must be a real number, not str",
439467
complex, 0, '1')
440468

441469
self.assertRaises(TypeError, complex, WithComplex(1.5))

Lib/test/test_fractions.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,10 @@ def testMixedMultiplication(self):
806806
self.assertTypedEquals(F(3, 2) * Polar(4, 2), Polar(F(6, 1), 2))
807807
self.assertTypedEquals(F(3, 2) * Polar(4.0, 2), Polar(6.0, 2))
808808
self.assertTypedEquals(F(3, 2) * Rect(4, 3), Rect(F(6, 1), F(9, 2)))
809-
self.assertTypedEquals(F(3, 2) * RectComplex(4, 3), RectComplex(6.0+0j, 4.5+0j))
809+
with self.assertWarnsRegex(DeprecationWarning,
810+
"argument 'real' must be a real number, not complex"):
811+
self.assertTypedEquals(F(3, 2) * RectComplex(4, 3),
812+
RectComplex(6.0+0j, 4.5+0j))
810813
self.assertRaises(TypeError, operator.mul, Polar(4, 2), F(3, 2))
811814
self.assertTypedEquals(Rect(4, 3) * F(3, 2), 6.0 + 4.5j)
812815
self.assertEqual(F(3, 2) * SymbolicComplex('X'), SymbolicComplex('3/2 * X'))
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:func:`complex` accepts now a string only as a positional argument. Passing
2+
a complex number as the "real" or "imag" argument is deprecated; it should
3+
only be passed as a single positional argument.

Objects/complexobject.c

Lines changed: 100 additions & 39 deletions

0 commit comments

Comments
 (0)