[Python-checkins] cpython (3.6): Issue #28739: f-string expressions no longer accepted as docstrings and

serhiy.storchaka python-checkins at python.org
Sun Dec 11 12:39:53 EST 2016


https://hg.python.org/cpython/rev/30341d5c1423
changeset: 105590:30341d5c1423
branch: 3.6
parent: 105588:df59faf7fa59
user: Serhiy Storchaka <storchaka at gmail.com>
date: Sun Dec 11 19:37:19 2016 +0200
summary:
 Issue #28739: f-string expressions no longer accepted as docstrings and
by ast.literal_eval() even if they do not include subexpressions.
files:
 Lib/test/test_fstring.py | 20 ++++++++++----------
 Misc/NEWS | 3 +++
 Python/ast.c | 11 +++++------
 Python/compile.c | 3 ++-
 4 files changed, 20 insertions(+), 17 deletions(-)
diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py
--- a/Lib/test/test_fstring.py
+++ b/Lib/test/test_fstring.py
@@ -70,18 +70,18 @@
 # Make sure x was called.
 self.assertTrue(x.called)
 
+ def test_docstring(self):
+ def f():
+ f'''Not a docstring'''
+ self.assertIsNone(f.__doc__)
+ def g():
+ '''Not a docstring''' \
+ f''
+ self.assertIsNone(g.__doc__)
+
 def test_literal_eval(self):
- # With no expressions, an f-string is okay.
- self.assertEqual(ast.literal_eval("f'x'"), 'x')
- self.assertEqual(ast.literal_eval("f'x' 'y'"), 'xy')
-
- # But this should raise an error.
 with self.assertRaisesRegex(ValueError, 'malformed node or string'):
- ast.literal_eval("f'x{3}'")
-
- # As should this, which uses a different ast node
- with self.assertRaisesRegex(ValueError, 'malformed node or string'):
- ast.literal_eval("f'{3}'")
+ ast.literal_eval("f'x'")
 
 def test_ast_compile_time_concat(self):
 x = ['']
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@
 Core and Builtins
 -----------------
 
+- Issue #28739: f-string expressions no longer accepted as docstrings and
+ by ast.literal_eval() even if they do not include expressions.
+
 - Issue #28512: Fixed setting the offset attribute of SyntaxError by
 PyErr_SyntaxLocationEx() and PyErr_SyntaxLocationObject().
 
diff --git a/Python/ast.c b/Python/ast.c
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -4789,6 +4789,7 @@
 typedef struct {
 PyObject *last_str;
 ExprList expr_list;
+ int fmode;
 } FstringParser;
 
 #ifdef NDEBUG
@@ -4807,6 +4808,7 @@
 FstringParser_Init(FstringParser *state)
 {
 state->last_str = NULL;
+ state->fmode = 0;
 ExprList_Init(&state->expr_list);
 FstringParser_check_invariants(state);
 }
@@ -4869,6 +4871,7 @@
 struct compiling *c, const node *n)
 {
 FstringParser_check_invariants(state);
+ state->fmode = 1;
 
 /* Parse the f-string. */
 while (1) {
@@ -4960,7 +4963,8 @@
 
 /* If we're just a constant string with no expressions, return
 that. */
- if(state->expr_list.size == 0) {
+ if (!state->fmode) {
+ assert(!state->expr_list.size);
 if (!state->last_str) {
 /* Create a zero length string. */
 state->last_str = PyUnicode_FromStringAndSize(NULL, 0);
@@ -4984,11 +4988,6 @@
 if (!seq)
 goto error;
 
- /* If there's only one expression, return it. Otherwise, we need
- to join them together. */
- if (seq->size == 1)
- return seq->elements[0];
-
 return JoinedStr(seq, LINENO(n), n->n_col_offset, c->c_arena);
 
 error:
diff --git a/Python/compile.c b/Python/compile.c
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -3415,7 +3415,8 @@
 compiler_joined_str(struct compiler *c, expr_ty e)
 {
 VISIT_SEQ(c, expr, e->v.JoinedStr.values);
- ADDOP_I(c, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values));
+ if (asdl_seq_LEN(e->v.JoinedStr.values) != 1)
+ ADDOP_I(c, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values));
 return 1;
 }
 
-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /