This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author mark.dickinson
Recipients cdavid, christian.heimes, mark.dickinson, rhettinger
Date 2009-01-06.11:56:26
SpamBayes Score 0.056470875
Marked as misclassified No
Message-id <1231242989.58.0.473834395822.issue2121@psf.upfronthosting.co.za>
In-reply-to
Content
[Mark]
> inputs with a special real or imaginary component.  On balance, I'd 
> support making complex('nan + nan*j') do the right thing.

Having thought about this a bit more, I take this back.  Some reasons are 
given below.

[David]
> - complex(repr(..)) roundtrip should work, whatever the value of complex 
is

I disagree. *Why* do you think it should work?  It fails for many other 
types:

>>> def roundtrip(x): return type(x)(repr(x))
... 
>>> roundtrip("abc")
"'abc'"
>>> roundtrip([1,2,3])
['[', '1', ',', ' ', '2', ',', ' ', '3', ']']
>>> roundtrip((1,))
('(', '1', ',', ')')
>>> roundtrip(Fraction(1, 2))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in roundtrip
  File "/Users/dickinsm/python_source/trunk/Lib/fractions.py", line 73, in 
__new__
    raise ValueError('Invalid literal for Fraction: %r' % input)
ValueError: Invalid literal for Fraction: 'Fraction(1, 2)'
>>> roundtrip(Decimal(1))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in roundtrip
  File "/Users/dickinsm/python_source/trunk/Lib/decimal.py", line 545, in 
__new__
    "Invalid literal for Decimal: %r" % value)
  File "/Users/dickinsm/python_source/trunk/Lib/decimal.py", line 3721, in 
_raise_error
    raise error(explanation)
decimal.InvalidOperation: Invalid literal for Decimal: "Decimal('1')"


In general, type(repr(x)) == x only works for simple types (ints, floats), 
not compound types like lists, strings, tuples, ...  I think it's 
reasonable to regard complex as such a compound type.

There *is* a general Python guideline that eval(repr(x)) == x should work 
where possible.  Note that this fails even for floats:

>>> eval(repr(float('nan')))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'nan' is not defined


The *real* problem here is that repr(complex) is a mess when it comes to 
niceties like signed zeros, infinities and nans:

>>> complex(-0., 0.)  # throws away sign of 0 on real part
0j
>>> eval(repr(complex(2., -0.)))  # throws away sign on imag. part
(2+0j)
>>> nan = float('nan')
>>> complex(0, nan)
nan*j
>>> nan*j  # can't even eval this...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'j' is not defined
>>> nan*1j # not much better: real part should be 0, not nan
(nan+nan*j)
>>> inf = float('inf')
>>> inf*1j  # ouch: nan in real part!
(nan+inf*j)


I think the *right* solution is to define repr of a complex number
z to be:

"complex(%r, %r)" % (z.real, z.imag)

but that's not possible before the mythical, compatibility-breaking, 
Python 4.0.  And even then your desired complex(repr(z)) roundtripping 
wouldn't work, though eval(repr(z)) would.

While we're daydreaming, another possibility is to follow C99's lead, and 
introduce a type of 'imaginary' numbers, and make 1j be an imaginary 
literal rather than a complex literal.  That solves some of the above 
eval(repr(.)) problems.  Again, I don't see how this could happen before 
4.0, and I'm not even sure that it's desirable.

In the circumstances, repr does the best it can, which is to output a 
whole expression which more-or-less describes the given complex number, 
and will usually eval back to the right thing.  I think it's not the 
business of the complex() constructor to parse such expressions.

To summarize:  it's a mess.  I'd recommend that you and/or numpy don't use 
repr for roundtrip-capable conversions to string.  Instead, output the 
real and imaginary parts separately, and use float-from-string and the 
complex-from-pair-of-floats constructors to reconstruct.
History
Date User Action Args
2009-01-06 11:56:29mark.dickinsonsetrecipients: + mark.dickinson, rhettinger, christian.heimes, cdavid
2009-01-06 11:56:29mark.dickinsonsetmessageid: <1231242989.58.0.473834395822.issue2121@psf.upfronthosting.co.za>
2009-01-06 11:56:28mark.dickinsonlinkissue2121 messages
2009-01-06 11:56:26mark.dickinsoncreate