bpo-30682: Removed a too-strict assertion that failed for certain f-strings. (#2232)

This caused a segfault on eval("f'\\\n'") and eval("f'\\\r'") in debug build.
This commit is contained in:
ericvsmith 2017-06-16 06:19:32 -04:00 committed by Serhiy Storchaka
parent a49c935cfd
commit 11e97f2f80
3 changed files with 11 additions and 2 deletions

View file

@ -780,5 +780,11 @@ f'{a * x()}'"""
self.assertEqual(f'{d["foo"]}', 'bar') self.assertEqual(f'{d["foo"]}', 'bar')
self.assertEqual(f"{d['foo']}", 'bar') self.assertEqual(f"{d['foo']}", 'bar')
def test_backslash_char(self):
# Check eval of a backslash followed by a control char.
# See bpo-30682: this used to raise an assert in pydebug mode.
self.assertEqual(eval('f"\\\n"'), '')
self.assertEqual(eval('f"\\\r"'), '')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View file

@ -10,6 +10,9 @@ What's New in Python 3.7.0 alpha 1?
Core and Builtins Core and Builtins
----------------- -----------------
- bpo-30682: Removed a too-strict assertion that failed for certain f-strings,
such as eval("f'\\\n'") and eval("f'\\\r'").
- bpo-30501: The compiler now produces more optimal code for complex condition - bpo-30501: The compiler now produces more optimal code for complex condition
expressions in the "if", "while" and "assert" statement, the "if" expression, expressions in the "if", "while" and "assert" statement, the "if" expression,
and generator expressions and comprehensions. and generator expressions and comprehensions.

View file

@ -4914,6 +4914,8 @@ FstringParser_ConcatFstring(FstringParser *state, const char **str,
/* Do nothing. Just leave last_str alone (and possibly /* Do nothing. Just leave last_str alone (and possibly
NULL). */ NULL). */
} else if (!state->last_str) { } else if (!state->last_str) {
/* Note that the literal can be zero length, if the
input string is "\\\n" or "\\\r", among others. */
state->last_str = literal; state->last_str = literal;
literal = NULL; literal = NULL;
} else { } else {
@ -4923,8 +4925,6 @@ FstringParser_ConcatFstring(FstringParser *state, const char **str,
return -1; return -1;
literal = NULL; literal = NULL;
} }
assert(!state->last_str ||
PyUnicode_GET_LENGTH(state->last_str) != 0);
/* We've dealt with the literal now. It can't be leaked on further /* We've dealt with the literal now. It can't be leaked on further
errors. */ errors. */