bpo-32028: Fix suggestions for indented print statements (GH-4688)

The suggested replacement for print statements previously failed to account
for leading whitespace and hence could end up including unwanted text in
the proposed call to the print builtin.

Patch by Sanyam Khurana.
This commit is contained in:
Sanyam Khurana 2018-01-20 08:42:22 +05:30 committed by Nick Coghlan
parent 6690bb9f17
commit d57f26c753
3 changed files with 23 additions and 5 deletions

View File

@ -156,6 +156,15 @@ class TestPy2MigrationHint(unittest.TestCase):
self.assertIn('print("Hello World", end=" ")', str(context.exception)) self.assertIn('print("Hello World", end=" ")', str(context.exception))
def test_string_with_leading_whitespace(self):
python2_print_str = '''if 1:
print "Hello World"
'''
with self.assertRaises(SyntaxError) as context:
exec(python2_print_str)
self.assertIn('print("Hello World")', str(context.exception))
def test_stream_redirection_hint_for_py2_migration(self): def test_stream_redirection_hint_for_py2_migration(self):
# Test correct hint produced for Py2 redirection syntax # Test correct hint produced for Py2 redirection syntax
with self.assertRaises(TypeError) as context: with self.assertRaises(TypeError) as context:

View File

@ -0,0 +1,3 @@
Leading whitespace is now correctly ignored when generating suggestions
for converting Py2 print statements to Py3 builtin print function calls.
Patch by Sanyam Khurana.

View File

@ -2846,17 +2846,23 @@ _set_legacy_print_statement_msg(PySyntaxErrorObject *self, Py_ssize_t start)
// PRINT_OFFSET is to remove `print ` word from the data. // PRINT_OFFSET is to remove `print ` word from the data.
const int PRINT_OFFSET = 6; const int PRINT_OFFSET = 6;
Py_ssize_t text_len = PyUnicode_GET_LENGTH(self->text); const int STRIP_BOTH = 2;
PyObject *data = PyUnicode_Substring(self->text, PRINT_OFFSET, text_len); // Issue 32028: Handle case when whitespace is used with print call
PyObject *initial_data = _PyUnicode_XStrip(self->text, STRIP_BOTH, strip_sep_obj);
if (initial_data == NULL) {
Py_DECREF(strip_sep_obj);
return -1;
}
Py_ssize_t text_len = PyUnicode_GET_LENGTH(initial_data);
PyObject *data = PyUnicode_Substring(initial_data, PRINT_OFFSET, text_len);
Py_DECREF(initial_data);
if (data == NULL) { if (data == NULL) {
Py_DECREF(strip_sep_obj); Py_DECREF(strip_sep_obj);
return -1; return -1;
} }
PyObject *new_data = _PyUnicode_XStrip(data, 2, strip_sep_obj); PyObject *new_data = _PyUnicode_XStrip(data, STRIP_BOTH, strip_sep_obj);
Py_DECREF(data); Py_DECREF(data);
Py_DECREF(strip_sep_obj); Py_DECREF(strip_sep_obj);
if (new_data == NULL) { if (new_data == NULL) {
return -1; return -1;
} }