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.

classification
Title: ast.literal_eval fails to parse numbers with leading "+"
Type: behavior Stage: resolved
Components: Versions: Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: Scott Turner, mark.dickinson, r.david.murray, terry.reedy
Priority: normal Keywords:

Created on 2015-10-07 15:25 by Scott Turner, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (5)
msg252476 - (view) Author: Scott Turner (Scott Turner) Date: 2015-10-07 15:25
import ast
  ast.literal_eval("+3")
  Traceback (most recent call last):
  [...]
  ValueError: malformed string
msg252477 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-10-07 16:08
This works in python3.  I'm not sure why the two pythons are different, there's no obvious issue about this being changed in python3, so perhaps it was something that "just happened" while changing other things.  

literal_eval is *not* a general expression evaluator, so I'm actually surprised this works in python3...apparently support for + and - is required for evaling complex numbers, but there must be something different about the parse trees generated in python2 vs python3, since python2 literal_eval handles complex numbers fine.

I'm not sure this is a bug, but *if* we decide it is something we'd should make work the same in python2 and python3, someone will probably have to invest the time in figuring out what the difference between the two is.
msg252481 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2015-10-07 18:03
Digging into the history, it looks as though changeset 884c71cd8dc6 is responsible for the difference between Python 2 and Python 3.

More background: in Python 2, there was the oddity that an expression like `-34` is parsed as a single AST node: in a sense.  In Python 3, it's parsed as an unary minus applied to a literal.  (So in a sense, Python 2 sorta kinda has negative literals, but Python 3 doesn't.) So the old `ast.literal_eval` stopped working for those negative literals in Python 3.  It looks as though Raymond fixed that regression and added support for unary plus at the same time.

I'd agree that this isn't a bug in Python 2.7.
msg252643 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2015-10-09 19:56
I am pretty sure the 2.x anomaly is tied up with having short ints plus the anomaly of having one more negative than positive int.

>>> 2147483648
2147483648L
>>> -(2147483648)
-2147483648L
>>> -2147483648
-2147483648

I believe the last result was once the same as the middle result because I remember reading or even writing the explanation that -2147483648 is (was) parsed as -(2147483648) (or something like this).

Raymond' also made more liberal in other ways: literal_eval('(+1)+(-1)') in now 0 instead of ValueError: malformed string. The 3.x doc was not changed to match, though.
msg253125 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2015-10-17 11:32
> I am pretty sure the 2.x anomaly is tied up with having short ints plus the anomaly of having one more negative than positive int.

Yes, that was the rationale for folding in the minus operation. It had some odd side-effects, though:

>>> -1j
-1j
>>> -(1j)
(-0-1j)

See issue 9011 for more discussion.
History
Date User Action Args
2022-04-11 14:58:22adminsetgithub: 69522
2015-10-17 11:32:01mark.dickinsonsetmessages: + msg253125
2015-10-09 19:56:53terry.reedysetstatus: open -> closed

nosy: + terry.reedy
messages: + msg252643

resolution: not a bug
stage: resolved
2015-10-07 18:03:55mark.dickinsonsetnosy: + mark.dickinson
messages: + msg252481
2015-10-07 16:08:47r.david.murraysetnosy: + r.david.murray
messages: + msg252477
2015-10-07 15:25:19Scott Turnercreate