Skip to content

Commit e799aa8

Browse files
authored
bpo-41887: omit leading spaces/tabs on ast.literal_eval (#22469)
Also document that eval() does this (the same way).
1 parent 7f54e56 commit e799aa8

File tree

5 files changed

+16
-2
lines changed

5 files changed

+16
-2
lines changed

Doc/library/ast.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1586,6 +1586,9 @@ and classes for traversing abstract syntax trees:
15861586
.. versionchanged:: 3.9
15871587
Now supports creating empty sets with ``'set()'``.
15881588

1589+
.. versionchanged:: 3.10
1590+
For string inputs, leading spaces and tabs are now stripped.
1591+
15891592

15901593
.. function:: get_docstring(node, clean=True)
15911594

@@ -1820,4 +1823,4 @@ to stdout. Otherwise, the content is read from stdin.
18201823
`Parso <https://parso.readthedocs.io>`_ is a Python parser that supports
18211824
error recovery and round-trip parsing for different Python versions (in
18221825
multiple Python versions). Parso is also able to list multiple syntax errors
1823-
in your python file.
1826+
in your python file.

Doc/library/functions.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,9 @@ are always available. They are listed here in alphabetical order.
506506
returns the current global and local dictionary, respectively, which may be
507507
useful to pass around for use by :func:`eval` or :func:`exec`.
508508

509+
If the given source is a string, then leading and trailing spaces and tabs
510+
are stripped.
511+
509512
See :func:`ast.literal_eval` for a function that can safely evaluate strings
510513
with expressions containing only literals.
511514

Lib/ast.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def literal_eval(node_or_string):
5959
sets, booleans, and None.
6060
"""
6161
if isinstance(node_or_string, str):
62-
node_or_string = parse(node_or_string, mode='eval')
62+
node_or_string = parse(node_or_string.lstrip(" \t"), mode='eval')
6363
if isinstance(node_or_string, Expression):
6464
node_or_string = node_or_string.body
6565
def _raise_malformed_node(node):

Lib/test/test_ast.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,12 @@ def test_literal_eval_malformed_dict_nodes(self):
10051005
malformed = ast.Dict(keys=[ast.Constant(1)], values=[ast.Constant(2), ast.Constant(3)])
10061006
self.assertRaises(ValueError, ast.literal_eval, malformed)
10071007

1008+
def test_literal_eval_trailing_ws(self):
1009+
self.assertEqual(ast.literal_eval(" -1"), -1)
1010+
self.assertEqual(ast.literal_eval("\t\t-1"), -1)
1011+
self.assertEqual(ast.literal_eval(" \t -1"), -1)
1012+
self.assertRaises(IndentationError, ast.literal_eval, "\n -1")
1013+
10081014
def test_bad_integer(self):
10091015
# issue13436: Bad error message with invalid numeric values
10101016
body = [ast.ImportFrom(module='time',
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Strip leading spaces and tabs on :func:`ast.literal_eval`. Also document
2+
stripping of spaces and tabs for :func:`eval`.

0 commit comments

Comments
 (0)