Nobody <nob...@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)) -- http://mail.python.org/mailman/listinfo/python-list