diff -r 1186d68715cc Lib/ast.py --- a/Lib/ast.py Wed Jul 04 19:33:45 2012 -0700 +++ b/Lib/ast.py Thu Jul 05 20:58:13 2012 -0300 @@ -35,14 +35,18 @@ return compile(source, filename, mode, PyCF_ONLY_AST) -def literal_eval(node_or_string): +def literal_eval(node_or_string, safe_names=None): """ Safely evaluate an expression node or a string containing a Python expression. The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, - sets, booleans, and None. + sets, booleans, None and Ellipsis. + A mapping may be provided as the second argument to allow identifiers to + be loaded. """ - _safe_names = {'None': None, 'True': True, 'False': False} + _safe_names = {'None': None, 'True': True, 'False': False, 'Ellipsis': ...} + if safe_names: + _safe_names.update(safe_names) if isinstance(node_or_string, str): node_or_string = parse(node_or_string, mode='eval') if isinstance(node_or_string, Expression): @@ -52,6 +56,8 @@ return node.s elif isinstance(node, Num): return node.n + elif isinstance(node, Ellipsis): + return ... elif isinstance(node, Tuple): return tuple(map(_convert, node.elts)) elif isinstance(node, List): diff -r 1186d68715cc Lib/test/test_ast.py --- a/Lib/test/test_ast.py Wed Jul 04 19:33:45 2012 -0700 +++ b/Lib/test/test_ast.py Thu Jul 05 20:58:13 2012 -0300 @@ -488,6 +488,12 @@ self.assertEqual(ast.literal_eval('-6'), -6) self.assertEqual(ast.literal_eval('-6j+3'), 3-6j) self.assertEqual(ast.literal_eval('3.25'), 3.25) + self.assertEqual(ast.literal_eval('...'), Ellipsis) + self.assertEqual(ast.literal_eval('Ellipsis'), Ellipsis) + inf = float('inf') + self.assertEqual(ast.literal_eval('inf', {'inf': inf}), inf) + self.assertEqual(ast.literal_eval('[some, names]', + {'some': 1, 'names': 2}), [1, 2]) def test_literal_eval_issue4907(self): self.assertEqual(ast.literal_eval('2j'), 2j)