New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
complex constructor doesn't accept string with nan and inf #46374
Comments
This is a reminder. The issue makes the complex(repr(...)) round-trip impossible when either |
Signed zeros cause difficulties with round-tripping, too: >>> z = complex(-0.0, -0.0); w = complex(repr(z))
>>> z
-0j
>>> w
-0j
>>> z.real
-0.0
>>> w.real
0.0 |
I started a patch against the trunk to handle nan/inf/infinite (I have The patch is a bit big, because I found the function quite difficult to Although I tested the function in a simple main under valgrind for |
Of course, I notice two bugs just after sending the patch... New patch |
-1 on this feature request. IMO, it adds no value to any real world |
I disagree the feature is not needed, for several reasons:
|
Nice-to-have but not a requirement that the entire input domain be
It made sense for floats because of prevalence of use cases and because
Mark, does Inf have a standard interpretation for complex numbers? Do Also, do you want to stick with the 754 interpretation of NaNs as the
That depends on whether handling of NaNs and Infs creeps into cmath. Mainly, I'm just questioning whether there exist compelling use cases |
Ok.
But why shouldn't this apply to complex numbers ? I am biased because I
Yes, it is difficult to handle nan and inf, there are a lot of corner
Hm, not sure what you mean here by standard interpretation, but
For any task where parsing complex makes sense. Since many numerical It this can make the review easier, I can split the patch in two: first |
Ok, I found out how to make tests, and I found some problems while using |
[Raymond]
Hmm. Have you looked at the cmath module recently? You may be in for a
Shrug. Mathematically, by far the most common and useful model is the It's never really been clear to me how useful it is to be able to (Though I can't help feeling that the repr of complex(nan, nan)
I've never much liked the use of NaN to represent missing values, and |
cdavid, in your application, how hard is it to work around the problem by E.g., <get real part and imaginary part from string> |
It is not really for an application, but for numpy. Of course, one can |
[Mark]
Having thought about this a bit more, I take this back. Some reasons are [David]
I disagree. *Why* do you think it should work? It fails for many other >>> 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), There *is* a general Python guideline that eval(repr(x)) == x should work >>> 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 >>> 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 "complex(%r, %r)" % (z.real, z.imag) but that's not possible before the mythical, compatibility-breaking, While we're daydreaming, another possibility is to follow C99's lead, and In the circumstances, repr does the best it can, which is to output a To summarize: it's a mess. I'd recommend that you and/or numpy don't use |
Christian, any comments? Is it okay to close this as a 'won't fix'? |
I don't understand the rationale: why not making something work better
Why ? I don't understand those examples: maybe I am missing your a = complex(0)
a *= float('inf') * 1j
-> a = nan+nanj Is really not desirable. That's actually a more serious bug than this |
Definitely! I don't see a reason the make the code more complex. David, we are against the patch because we have to keep the code |
As Christian says, it's about not increasing code complexity without a The addition of the '*1j' part of the expression bothers me particularly, I have a compromise proposal:
sign ::= '+' | '-' and float-string is any string currently accepted by float I think this would simplify the parsing, and remove need for special The above would allow double signs: e.g. '2+-1j', with the first sign The current 'nan*j' is certainly more attractive than 'nanj', but it's If you could come up with a patch that does something like this I'd take a By the way, "0 + inf*1j" giving nan + inf*j isn't really a bug; it's I think it's exactly to fix this sort of behaviour that C99 introduced its |
@ Mark Concerning float('inf') * 1j: you're right, my rambling did not make any I agree that adding complexity may be a good reason to warrant an Also, how should I proceed to share implementation between floatobject.c |
David, at this point, I recommend dropping this one. It has become a |
Mark, I'm somewhat uncomfortable with your proposal also. It changes |
Closing this one as won't fix. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: