bpo-41887: omit leading spaces/tabs on ast.literal_eval (#22469)
Also document that eval() does this (the same way).
diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst
index 755c60f..62138ef 100644
--- a/Doc/library/ast.rst
+++ b/Doc/library/ast.rst
@@ -1586,6 +1586,9 @@
.. 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 @@
`Parso <https://parso.readthedocs.io>`_ 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 c49bb0c..263c52a 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -506,6 +506,9 @@
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 d860917..d8bd337 100644
--- a/Lib/ast.py
+++ b/Lib/ast.py
@@ -59,7 +59,7 @@
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 5f57ce8..be4b0f7 100644
--- a/Lib/test/test_ast.py
+++ b/Lib/test/test_ast.py
@@ -1005,6 +1005,12 @@
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 0000000..2a43ab3
--- /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`.