From 749faa105445c47b67e5aaea5a5987e2aa833850 Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Wed, 30 Sep 2020 23:51:49 +0300 Subject: [PATCH 1/5] bpo-41887: omit leading whitespaces on ast.literal_eval --- Doc/library/ast.rst | 2 ++ Doc/library/functions.rst | 2 ++ Lib/ast.py | 3 ++- Lib/test/test_ast.py | 5 +++++ .../next/Library/2020-09-30-23-49-42.bpo-41887.-ee2S-.rst | 1 + 5 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-30-23-49-42.bpo-41887.-ee2S-.rst diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index 755c60fba64115a..9d3704cd51b244c 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -1586,6 +1586,8 @@ and classes for traversing abstract syntax trees: .. versionchanged:: 3.9 Now supports creating empty sets with ``'set()'``. + .. versionchanged:: 3.10 + Now allows leading whitespaces .. function:: get_docstring(node, clean=True) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 7543fc4b10d4666..e292d7afb3ebc6b 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -506,6 +506,8 @@ 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`. + The leading whitespaces would be omitted. + 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 d860917f4d03ae3..e9bbffc7c530678 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -59,7 +59,8 @@ 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') + # bpo-41887: Allow leading whitespace + node_or_string = parse(node_or_string.strip(" \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 5f57ce8724482af..3362a13932c556f 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -1005,6 +1005,11 @@ def test_literal_eval_malformed_dict_nodes(self): 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.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 000000000000000..e173349cf3fcf04 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-30-23-49-42.bpo-41887.-ee2S-.rst @@ -0,0 +1 @@ +Omit leading whitespaces on :func:`ast.literal_eval`. From 4b6663bd951fd6faf5397f0e3532ba556029d5b0 Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Wed, 30 Sep 2020 23:57:22 +0300 Subject: [PATCH 2/5] Explicitly mention the omitting only happens on the string source --- Doc/library/ast.rst | 1 + Doc/library/functions.rst | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index 9d3704cd51b244c..cd21ab740edd92a 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -1589,6 +1589,7 @@ and classes for traversing abstract syntax trees: .. versionchanged:: 3.10 Now allows leading whitespaces + .. function:: get_docstring(node, clean=True) Return the docstring of the given *node* (which must be a diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index e292d7afb3ebc6b..df8e3ff5b5b887a 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -506,7 +506,8 @@ 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`. - The leading whitespaces would be omitted. + If the given source is a string, then the leading whitespace will be + omitted. See :func:`ast.literal_eval` for a function that can safely evaluate strings with expressions containing only literals. From 35d3a9d83c522224eff611d79300a773ac4bb06f Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Thu, 1 Oct 2020 21:38:06 +0300 Subject: [PATCH 3/5] apply suggestions --- Doc/library/ast.rst | 3 ++- Doc/library/functions.rst | 4 ++-- Lib/ast.py | 3 +-- .../next/Library/2020-09-30-23-49-42.bpo-41887.-ee2S-.rst | 3 ++- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index cd21ab740edd92a..c6bf402fcd4e8f6 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -1587,7 +1587,8 @@ and classes for traversing abstract syntax trees: Now supports creating empty sets with ``'set()'``. .. versionchanged:: 3.10 - Now allows leading whitespaces + For string inputs, leading whitespace is now stripped (as + trailing whitespace already was). .. function:: get_docstring(node, clean=True) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index df8e3ff5b5b887a..84752a314f65e21 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -506,8 +506,8 @@ 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 the leading whitespace will be - omitted. + If the given source is a string, then then leading and trailing whitespace + is 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 e9bbffc7c530678..d8bd3373701dec6 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -59,8 +59,7 @@ def literal_eval(node_or_string): sets, booleans, and None. """ if isinstance(node_or_string, str): - # bpo-41887: Allow leading whitespace - node_or_string = parse(node_or_string.strip(" \t"), 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/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 index e173349cf3fcf04..394286e5a4e84c6 100644 --- 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 @@ -1 +1,2 @@ -Omit leading whitespaces on :func:`ast.literal_eval`. +Strip leading whitespace on :func:`ast.literal_eval`. Also document +stripping of whitespace for :func:`eval`. From 63187dc8ccc90065418842f4d2d4e6a01c672b60 Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Sat, 3 Oct 2020 03:44:25 +0300 Subject: [PATCH 4/5] apply suggestions --- Doc/library/ast.rst | 4 ++-- Doc/library/functions.rst | 4 ++-- Lib/test/test_ast.py | 1 + .../next/Library/2020-09-30-23-49-42.bpo-41887.-ee2S-.rst | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index c6bf402fcd4e8f6..f54fd51bb6c49a1 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -1587,8 +1587,8 @@ and classes for traversing abstract syntax trees: Now supports creating empty sets with ``'set()'``. .. versionchanged:: 3.10 - For string inputs, leading whitespace is now stripped (as - trailing whitespace already was). + For string inputs, leading spaces and tabs is now stripped (as + the trailing ones already was). .. function:: get_docstring(node, clean=True) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 84752a314f65e21..8080446c0bc28eb 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -506,8 +506,8 @@ 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 then leading and trailing whitespace - is stripped. + 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/test/test_ast.py b/Lib/test/test_ast.py index 3362a13932c556f..be4b0f78ce9053e 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -1008,6 +1008,7 @@ def test_literal_eval_malformed_dict_nodes(self): 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): 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 index 394286e5a4e84c6..2a43ab3f2890c78 100644 --- 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 @@ -1,2 +1,2 @@ -Strip leading whitespace on :func:`ast.literal_eval`. Also document -stripping of whitespace for :func:`eval`. +Strip leading spaces and tabs on :func:`ast.literal_eval`. Also document +stripping of spaces and tabs for :func:`eval`. From 950f1e079cd6872177ede7eddd14597460f2ebc5 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sat, 3 Oct 2020 16:59:42 -0700 Subject: [PATCH 5/5] Tweak wording in docs --- Doc/library/ast.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index f54fd51bb6c49a1..62138efcce9110c 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -1587,8 +1587,7 @@ and classes for traversing abstract syntax trees: Now supports creating empty sets with ``'set()'``. .. versionchanged:: 3.10 - For string inputs, leading spaces and tabs is now stripped (as - the trailing ones already was). + For string inputs, leading spaces and tabs are now stripped. .. function:: get_docstring(node, clean=True) @@ -1824,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.