How is correct use of eval()
Hrvoje Niksic
hniksic at xemacs.org
Tue Oct 12 12:28:09 EDT 2010
Nobody <nobody at nowhere.com> writes:
> Oh, look what's "new in version 2.6":
>
> > ast.literal_eval("7")
> 7
> > ast.literal_eval("7") == 7
> True
Note that it doesn't work for some reasonable inputs involving unary and
binary plus, such as "[-2, +1]" or "2+3j". This has been fixed in the
development (3.2) sources.
An interesting aspect of ast.literal_eval is that it merely uses the
public API to access the AST provided by the compiler. One is therefore
free to "fix" literal_eval in 2.6 or 2.7 by defining their own similar
function with the desired flavor. For example:
import ast
from itertools import imap, izip
def my_literal_eval(s):
node = ast.parse(s, mode='eval').body
return _convert(node)
_safe_names = {'None': None, 'True': True, 'False': False}
_safe_operands = (ast.Num, ast.UnaryOp, ast.BinOp)
_safe_unops = (ast.UAdd, ast.USub)
_safe_binops = (ast.Add, ast.Sub)
def _convert(node):
if isinstance(node, ast.Str):
return node.s
elif isinstance(node, ast.Num):
return node.n
elif isinstance(node, ast.Tuple):
return tuple(imap(_convert, node.elts))
elif isinstance(node, ast.List):
return list(imap(_convert, node.elts))
elif isinstance(node, ast.Dict):
return dict((_convert(k), _convert(v)) for k, v
in izip(node.keys, node.values))
elif isinstance(node, ast.Name) and node.id in _safe_names:
return _safe_names[node.id]
elif isinstance(node, ast.UnaryOp) and \
isinstance(node.op, _safe_unops) and \
isinstance(node.operand, _safe_operands):
operand = _convert(node.operand)
if isinstance(node.op, ast.UAdd):
return + operand
else:
return - operand
elif isinstance(node, ast.BinOp) and isinstance(node.op, _safe_binops) \
and isinstance(node.right, _safe_operands) \
and isinstance(node.left, _safe_operands):
left = _convert(node.left)
right = _convert(node.right)
if isinstance(node.op, ast.Add):
return left + right
else:
return left - right
raise ValueError('malformed expression: ' + repr(node))
More information about the Python-list
mailing list