Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 43c0f1a

Browse files
nitishchncoghlan
authored andcommitted
bpo-32685: Improve suggestion for print statement (GH-5375)
Better account for single-line compound statements and semi-colon separated statements when suggesting Py3 replacements for Py2 print statements. Initial patch by Nitish Chandra.
1 parent 255f7a2 commit 43c0f1a

3 files changed

Lines changed: 39 additions & 14 deletions

File tree

Lib/test/test_print.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,23 @@ def test_string_with_leading_whitespace(self):
165165

166166
self.assertIn('print("Hello World")', str(context.exception))
167167

168+
# bpo-32685: Suggestions for print statement should be proper when
169+
# it is in the same line as the header of a compound statement
170+
# and/or followed by a semicolon
171+
def test_string_with_semicolon(self):
172+
python2_print_str = 'print p;'
173+
with self.assertRaises(SyntaxError) as context:
174+
exec(python2_print_str)
175+
176+
self.assertIn('print(p)', str(context.exception))
177+
178+
def test_string_in_loop_on_same_line(self):
179+
python2_print_str = 'for i in s: print i'
180+
with self.assertRaises(SyntaxError) as context:
181+
exec(python2_print_str)
182+
183+
self.assertIn('print(i)', str(context.exception))
184+
168185
def test_stream_redirection_hint_for_py2_migration(self):
169186
# Test correct hint produced for Py2 redirection syntax
170187
with self.assertRaises(TypeError) as context:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Improve suggestion when the Python 2 form of print statement is either
2+
present on the same line as the header of a compound statement or else
3+
terminated by a semi-colon instead of a newline. Patch by Nitish Chandra.

Objects/exceptions.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2840,26 +2840,31 @@ _PyErr_TrySetFromCause(const char *format, ...)
28402840
static int
28412841
_set_legacy_print_statement_msg(PySyntaxErrorObject *self, Py_ssize_t start)
28422842
{
2843-
PyObject *strip_sep_obj = PyUnicode_FromString(" \t\r\n");
2844-
if (strip_sep_obj == NULL)
2845-
return -1;
2846-
2847-
// PRINT_OFFSET is to remove `print ` word from the data.
2843+
// PRINT_OFFSET is to remove the `print ` prefix from the data.
28482844
const int PRINT_OFFSET = 6;
28492845
const int STRIP_BOTH = 2;
2850-
// Issue 32028: Handle case when whitespace is used with print call
2851-
PyObject *initial_data = _PyUnicode_XStrip(self->text, STRIP_BOTH, strip_sep_obj);
2852-
if (initial_data == NULL) {
2853-
Py_DECREF(strip_sep_obj);
2854-
return -1;
2846+
Py_ssize_t start_pos = start + PRINT_OFFSET;
2847+
Py_ssize_t text_len = PyUnicode_GET_LENGTH(self->text);
2848+
Py_UCS4 semicolon = ';';
2849+
Py_ssize_t end_pos = PyUnicode_FindChar(self->text, semicolon,
2850+
start_pos, text_len, 1);
2851+
if (end_pos < -1) {
2852+
return -1;
2853+
} else if (end_pos == -1) {
2854+
end_pos = text_len;
28552855
}
2856-
Py_ssize_t text_len = PyUnicode_GET_LENGTH(initial_data);
2857-
PyObject *data = PyUnicode_Substring(initial_data, PRINT_OFFSET, text_len);
2858-
Py_DECREF(initial_data);
2856+
2857+
PyObject *data = PyUnicode_Substring(self->text, start_pos, end_pos);
28592858
if (data == NULL) {
2860-
Py_DECREF(strip_sep_obj);
28612859
return -1;
28622860
}
2861+
2862+
PyObject *strip_sep_obj = PyUnicode_FromString(" \t\r\n");
2863+
if (strip_sep_obj == NULL) {
2864+
Py_DECREF(data);
2865+
return -1;
2866+
}
2867+
28632868
PyObject *new_data = _PyUnicode_XStrip(data, STRIP_BOTH, strip_sep_obj);
28642869
Py_DECREF(data);
28652870
Py_DECREF(strip_sep_obj);

0 commit comments

Comments
 (0)