diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index 755c60fba64..62138efcce9 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -1586,6 +1586,9 @@ and classes for traversing abstract syntax trees: .. versionchanged:: 3.9 Now supports creating empty sets with ``'set()'``. + .. versionchanged:: 3.10 + For string inputs, leading spaces and tabs are now stripped. + .. function:: get_docstring(node, clean=True) @@ -1820,4 +1823,4 @@ to stdout. Otherwise, the content is read from stdin. `Parso `_ is a Python parser that supports error recovery and round-trip parsing for different Python versions (in multiple Python versions). Parso is also able to list multiple syntax errors - in your python file. \ No newline at end of file + in your python file. diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index c49bb0c9de7..263c52a63de 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -506,6 +506,9 @@ are always available. They are listed here in alphabetical order. returns the current global and local dictionary, respectively, which may be useful to pass around for use by :func:`eval` or :func:`exec`. + If the given source is a string, then leading and trailing spaces and tabs + are stripped. + See :func:`ast.literal_eval` for a function that can safely evaluate strings with expressions containing only literals. diff --git a/Lib/ast.py b/Lib/ast.py index d860917f4d0..d8bd3373701 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -59,7 +59,7 @@ def literal_eval(node_or_string): sets, booleans, and None. """ if isinstance(node_or_string, str): - node_or_string = parse(node_or_string, mode='eval') + node_or_string = parse(node_or_string.lstrip(" \t"), mode='eval') if isinstance(node_or_string, Expression): node_or_string = node_or_string.body def _raise_malformed_node(node): diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 5f57ce87244..be4b0f78ce9 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -1005,6 +1005,12 @@ Module( malformed = ast.Dict(keys=[ast.Constant(1)], values=[ast.Constant(2), ast.Constant(3)]) self.assertRaises(ValueError, ast.literal_eval, malformed) + def test_literal_eval_trailing_ws(self): + self.assertEqual(ast.literal_eval(" -1"), -1) + self.assertEqual(ast.literal_eval("\t\t-1"), -1) + self.assertEqual(ast.literal_eval(" \t -1"), -1) + self.assertRaises(IndentationError, ast.literal_eval, "\n -1") + def test_bad_integer(self): # issue13436: Bad error message with invalid numeric values body = [ast.ImportFrom(module='time', diff --git a/Misc/NEWS.d/next/Library/2020-09-30-23-49-42.bpo-41887.-ee2S-.rst b/Misc/NEWS.d/next/Library/2020-09-30-23-49-42.bpo-41887.-ee2S-.rst new file mode 100644 index 00000000000..2a43ab3f289 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-30-23-49-42.bpo-41887.-ee2S-.rst @@ -0,0 +1,2 @@ +Strip leading spaces and tabs on :func:`ast.literal_eval`. Also document +stripping of spaces and tabs for :func:`eval`.