Issue 15245: ast.literal_eval fails on some literals (original) (raw)

Created on 2012-07-03 20:11 by JBernardo, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
ast.py.diff JBernardo,2012-07-05 21:00 Added support to `...` and a mapping for safe names as second argument. review
ast.py_with_tests.diff JBernardo,2012-07-06 00:02 Changed docstring and added tests. review
ast.py_tests_doc.diff JBernardo,2012-07-06 00:47 Now with doc update. review
Messages (14)
msg164621 - (view) Author: João Bernardo (JBernardo) * Date: 2012-07-03 20:11
`ast.literal_eval` is very strict on names, so it seems to lack some "literals" that may be result of `repr` on built-in objects. -> Obvious cases: ast.literal_eval('...') ast.literal_eval('Ellipsis') both result on ValueError. -> Not so obvious: nan_name = repr(float('nan')) ast.literal_eval(nan_name) # ValueError inf_name = repr(float('inf')) ast.literal_eval(inf_name) # ValueError ast.literal_eval("2e308") # == inf `nan` and `inf` are not literals (at least "inf" should be, but that's another problem), but their representations are not possible to be evaluated unlike any other float numbers with maybe precision loss. I think `literal_eval` should include these 3 names the same way it accepts True, False and None. Another case, that I personally don't care, but seems plausible would be `NotImplemented`.
msg164651 - (view) Author: Daniel Urban (daniel.urban) * (Python triager) Date: 2012-07-04 16:22
eval(repr(float('nan'))) doesn't work either, so I'm not sure ast.literal_eval should. The same with float('inf').
msg164658 - (view) Author: João Bernardo (JBernardo) * Date: 2012-07-04 18:44
That's what I said by `nan` and `inf` are not literals, but their representations look like they should be. One solution could be to add another argument to allow some extra names. Maybe a mapping, as `eval`.
msg164666 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2012-07-05 01:54
I don't think literal_eval should handle anything which is not syntax.
msg164679 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2012-07-05 12:05
> I don't think literal_eval should handle anything which is not syntax. +1 -1 on supporting 'inf' and 'nan' -0 on supporting 'Ellipsis' or '...'; seems harmless, but I don't really see the point.
msg164684 - (view) Author: João Bernardo (JBernardo) * Date: 2012-07-05 15:48
Of course `nan` and `inf` are part of the syntax! The `ast.parse` function recognize them as `Name`. So that works: >>> ast.dump(ast.parse('True')) "Module(body=[Expr(value=Name(id='True', ctx=Load()))])" >>> ast.dump(ast.parse('inf')) "Module(body=[Expr(value=Name(id='inf', ctx=Load()))])" >>> inf = float('inf') >>> eval('inf') inf I've run into some literals with `Ellipsis` and `inf` and couldn't load them with literal_eval. That's why I'm proposing that. The thing about `nan` and `inf` is because they are the *only* representations of float numbers produced by the interpreter that cannot be loaded. Something like that could solve the problem keeping `literal_eval` safe and allowing other names: ast.literal_eval('[1.0, 2.0, inf]', {'inf': float('inf')})
msg164698 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2012-07-05 22:10
I like the 'safe_names' idea, but is this patch supposed to work? >>> isinstance(None, Ellipsis) TypeError: isinstance() arg 2 must be a type or tuple of types
msg164699 - (view) Author: João Bernardo (JBernardo) * Date: 2012-07-05 22:12
Ellipsis in this context is `_ast.Ellipsis`, not the original one... There's no TypeError there as `_ast.Ellipsis` is a class.
msg164700 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2012-07-05 22:19
Ah right, that's confusing indeed... Unit tests and doc updates are needed though.
msg164707 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2012-07-06 00:21
Thanks for the patch. It looks good to me, but I think that adding support for Ellipsis and adding a new parameter to allow extra names are two different requests, but someone more knowledgeable than me about AST may judge differently. My rationale is that supporting Ellipsis literals is a no-brainer addition, whereas adding an argument to support things that are not actual Python literals may be rejected. You don’t have to split your patch in two anyway, it’s easy to do if the dev who will commit wants to. Each change would also need a doc update.
msg164708 - (view) Author: João Bernardo (JBernardo) * Date: 2012-07-06 00:29
Just to be sure: What's a doc update? The `.rst` files are updated automatically with the doc strings? The adding another argument should require a: "Changed in version 3.x: Accepts a second argument ..." ?
msg164709 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2012-07-06 00:32
No, the rst documentation is maintained manually. Look for versionchanged in the doc source files or the documentation about writing documentation to see how to document the new argument (and new supported Ellipsis literal).
msg329284 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-11-05 07:55
ast.literal_eval('...') works in 3.8. The question is should we make it working in older versions?
msg330040 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2018-11-18 10:05
> The question is should we make it working in older versions? That seems like an easy question: it would be a new feature in a bugfix branch, so no, we shouldn't make it work in older versions. Looks to me as though this issue can be closed.
History
Date User Action Args
2022-04-11 14:57:32 admin set github: 59450
2018-11-21 07:51:19 serhiy.storchaka set status: open -> closedresolution: out of datestage: patch review -> resolved
2018-11-18 10:05:40 mark.dickinson set messages: +
2018-11-05 07:55:19 serhiy.storchaka set nosy: + serhiy.storchakamessages: +
2012-07-06 17:29:31 ezio.melotti set nosy: + ezio.melotti
2012-07-06 00:47:59 JBernardo set files: + ast.py_tests_doc.diff
2012-07-06 00:32:14 eric.araujo set messages: +
2012-07-06 00:29:40 JBernardo set messages: +
2012-07-06 00:21:05 eric.araujo set messages: + stage: test needed -> patch review
2012-07-06 00:02:59 JBernardo set files: + ast.py_with_tests.diff
2012-07-05 22:19:11 amaury.forgeotdarc set messages: +
2012-07-05 22:12:40 JBernardo set messages: +
2012-07-05 22:10:49 amaury.forgeotdarc set nosy: + amaury.forgeotdarcmessages: +
2012-07-05 21:02:32 eric.araujo set keywords: + needs reviewstage: test needed
2012-07-05 21:00:35 JBernardo set files: + ast.py.diffkeywords: + patch
2012-07-05 16:37:59 eric.araujo set nosy: + georg.brandl, eric.araujo
2012-07-05 15:48:05 JBernardo set messages: +
2012-07-05 12:05:41 mark.dickinson set messages: +
2012-07-05 01:54:31 benjamin.peterson set messages: +
2012-07-04 18:44:31 JBernardo set messages: +
2012-07-04 16:22:02 daniel.urban set nosy: + daniel.urbanmessages: +
2012-07-04 14:47:08 mark.dickinson set nosy: + mark.dickinson
2012-07-03 20:54:32 pitrou set nosy: + benjamin.petersontitle: ast.literal_eval on some literals -> ast.literal_eval fails on some literalsversions: + Python 3.4, - Python 3.3
2012-07-03 20:11:26 JBernardo create