bpo-30597: Show expected input in custom 'print' error message. (#2009) · python/cpython@3a7f035

@@ -2862,6 +2862,49 @@ _PyErr_TrySetFromCause(const char *format, ...)

28622862

* or minus, using the stream redirection syntax).

28632863

*/

286428642865+2866+

// Static helper for setting legacy print error message

2867+

static int

2868+

_set_legacy_print_statement_msg(PySyntaxErrorObject *self, Py_ssize_t start)

2869+

{

2870+

PyObject *strip_sep_obj = PyUnicode_FromString(" \t\r\n");

2871+

if (strip_sep_obj == NULL)

2872+

return -1;

2873+2874+

// PRINT_OFFSET is to remove `print ` word from the data.

2875+

const int PRINT_OFFSET = 6;

2876+

Py_ssize_t text_len = PyUnicode_GET_LENGTH(self->text);

2877+

PyObject *data = PyUnicode_Substring(self->text, PRINT_OFFSET, text_len);

2878+2879+

if (data == NULL) {

2880+

Py_DECREF(strip_sep_obj);

2881+

return -1;

2882+

}

2883+

PyObject *new_data = _PyUnicode_XStrip(data, 2, strip_sep_obj);

2884+

Py_DECREF(data);

2885+

Py_DECREF(strip_sep_obj);

2886+2887+

if (new_data == NULL) {

2888+

return -1;

2889+

}

2890+

// gets the modified text_len after stripping `print `

2891+

text_len = PyUnicode_GET_LENGTH(new_data);

2892+

const char *maybe_end_arg = "";

2893+

if (text_len > 0 && PyUnicode_READ_CHAR(new_data, text_len-1) == ',') {

2894+

maybe_end_arg = " end=\" \"";

2895+

}

2896+

PyObject *error_msg = PyUnicode_FromFormat(

2897+

"Missing parentheses in call to 'print'. Did you mean print(%U%s)?",

2898+

new_data, maybe_end_arg

2899+

);

2900+

Py_DECREF(new_data);

2901+

if (error_msg == NULL)

2902+

return -1;

2903+2904+

Py_XSETREF(self->msg, error_msg);

2905+

return 1;

2906+

}

2907+28652908

static int

28662909

_check_for_legacy_statements(PySyntaxErrorObject *self, Py_ssize_t start)

28672910

{

@@ -2897,9 +2940,8 @@ _check_for_legacy_statements(PySyntaxErrorObject *self, Py_ssize_t start)

28972940

}

28982941

if (PyUnicode_Tailmatch(self->text, print_prefix,

28992942

start, text_len, -1)) {

2900-

Py_XSETREF(self->msg,

2901-

PyUnicode_FromString("Missing parentheses in call to 'print'"));

2902-

return 1;

2943+2944+

return _set_legacy_print_statement_msg(self, start);

29032945

}

2904294629052947

/* Check for legacy exec statements */