@@ -1475,9 +1475,6 @@ ComplexExtendsException(PyExc_Exception, AttributeError,
1475
1475
* SyntaxError extends Exception
1476
1476
*/
1477
1477
1478
- /* Helper function to customize error message for some syntax errors */
1479
- static int _report_missing_parentheses (PySyntaxErrorObject * self );
1480
-
1481
1478
static int
1482
1479
SyntaxError_init (PySyntaxErrorObject * self , PyObject * args , PyObject * kwds )
1483
1480
{
@@ -1520,18 +1517,6 @@ SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
1520
1517
PyErr_SetString (PyExc_TypeError , "end_offset must be provided when end_lineno is provided" );
1521
1518
return -1 ;
1522
1519
}
1523
-
1524
- /*
1525
- * Issue #21669: Custom error for 'print' & 'exec' as statements
1526
- *
1527
- * Only applies to SyntaxError instances, not to subclasses such
1528
- * as TabError or IndentationError (see issue #31161)
1529
- */
1530
- if (Py_IS_TYPE (self , (PyTypeObject * )PyExc_SyntaxError ) &&
1531
- self -> text && PyUnicode_Check (self -> text ) &&
1532
- _report_missing_parentheses (self ) < 0 ) {
1533
- return -1 ;
1534
- }
1535
1520
}
1536
1521
return 0 ;
1537
1522
}
@@ -3033,189 +3018,3 @@ _PyErr_TrySetFromCause(const char *format, ...)
3033
3018
PyErr_Restore (new_exc , new_val , new_tb );
3034
3019
return new_val ;
3035
3020
}
3036
-
3037
-
3038
- /* To help with migration from Python 2, SyntaxError.__init__ applies some
3039
- * heuristics to try to report a more meaningful exception when print and
3040
- * exec are used like statements.
3041
- *
3042
- * The heuristics are currently expected to detect the following cases:
3043
- * - top level statement
3044
- * - statement in a nested suite
3045
- * - trailing section of a one line complex statement
3046
- *
3047
- * They're currently known not to trigger:
3048
- * - after a semi-colon
3049
- *
3050
- * The error message can be a bit odd in cases where the "arguments" are
3051
- * completely illegal syntactically, but that isn't worth the hassle of
3052
- * fixing.
3053
- *
3054
- * We also can't do anything about cases that are legal Python 3 syntax
3055
- * but mean something entirely different from what they did in Python 2
3056
- * (omitting the arguments entirely, printing items preceded by a unary plus
3057
- * or minus, using the stream redirection syntax).
3058
- */
3059
-
3060
-
3061
- // Static helper for setting legacy print error message
3062
- static int
3063
- _set_legacy_print_statement_msg (PySyntaxErrorObject * self , Py_ssize_t start )
3064
- {
3065
- // PRINT_OFFSET is to remove the `print ` prefix from the data.
3066
- const int PRINT_OFFSET = 6 ;
3067
- const int STRIP_BOTH = 2 ;
3068
- Py_ssize_t start_pos = start + PRINT_OFFSET ;
3069
- Py_ssize_t text_len = PyUnicode_GET_LENGTH (self -> text );
3070
- Py_UCS4 semicolon = ';' ;
3071
- Py_ssize_t end_pos = PyUnicode_FindChar (self -> text , semicolon ,
3072
- start_pos , text_len , 1 );
3073
- if (end_pos < -1 ) {
3074
- return -1 ;
3075
- } else if (end_pos == -1 ) {
3076
- end_pos = text_len ;
3077
- }
3078
-
3079
- PyObject * data = PyUnicode_Substring (self -> text , start_pos , end_pos );
3080
- if (data == NULL ) {
3081
- return -1 ;
3082
- }
3083
-
3084
- PyObject * strip_sep_obj = PyUnicode_FromString (" \t\r\n" );
3085
- if (strip_sep_obj == NULL ) {
3086
- Py_DECREF (data );
3087
- return -1 ;
3088
- }
3089
-
3090
- PyObject * new_data = _PyUnicode_XStrip (data , STRIP_BOTH , strip_sep_obj );
3091
- Py_DECREF (data );
3092
- Py_DECREF (strip_sep_obj );
3093
- if (new_data == NULL ) {
3094
- return -1 ;
3095
- }
3096
- // gets the modified text_len after stripping `print `
3097
- text_len = PyUnicode_GET_LENGTH (new_data );
3098
- const char * maybe_end_arg = "" ;
3099
- if (text_len > 0 && PyUnicode_READ_CHAR (new_data , text_len - 1 ) == ',' ) {
3100
- maybe_end_arg = " end=\" \"" ;
3101
- }
3102
- PyObject * error_msg = PyUnicode_FromFormat (
3103
- "Missing parentheses in call to 'print'. Did you mean print(%U%s)?" ,
3104
- new_data , maybe_end_arg
3105
- );
3106
- Py_DECREF (new_data );
3107
- if (error_msg == NULL )
3108
- return -1 ;
3109
-
3110
- Py_XSETREF (self -> msg , error_msg );
3111
- return 1 ;
3112
- }
3113
-
3114
- static int
3115
- _check_for_legacy_statements (PySyntaxErrorObject * self , Py_ssize_t start )
3116
- {
3117
- /* Return values:
3118
- * -1: an error occurred
3119
- * 0: nothing happened
3120
- * 1: the check triggered & the error message was changed
3121
- */
3122
- static PyObject * print_prefix = NULL ;
3123
- static PyObject * exec_prefix = NULL ;
3124
- Py_ssize_t text_len = PyUnicode_GET_LENGTH (self -> text ), match ;
3125
- int kind = PyUnicode_KIND (self -> text );
3126
- const void * data = PyUnicode_DATA (self -> text );
3127
-
3128
- /* Ignore leading whitespace */
3129
- while (start < text_len ) {
3130
- Py_UCS4 ch = PyUnicode_READ (kind , data , start );
3131
- if (!Py_UNICODE_ISSPACE (ch ))
3132
- break ;
3133
- start ++ ;
3134
- }
3135
- /* Checking against an empty or whitespace-only part of the string */
3136
- if (start == text_len ) {
3137
- return 0 ;
3138
- }
3139
-
3140
- /* Check for legacy print statements */
3141
- if (print_prefix == NULL ) {
3142
- print_prefix = PyUnicode_InternFromString ("print " );
3143
- if (print_prefix == NULL ) {
3144
- return -1 ;
3145
- }
3146
- }
3147
- match = PyUnicode_Tailmatch (self -> text , print_prefix ,
3148
- start , text_len , -1 );
3149
- if (match == -1 ) {
3150
- return -1 ;
3151
- }
3152
- if (match ) {
3153
- return _set_legacy_print_statement_msg (self , start );
3154
- }
3155
-
3156
- /* Check for legacy exec statements */
3157
- if (exec_prefix == NULL ) {
3158
- exec_prefix = PyUnicode_InternFromString ("exec " );
3159
- if (exec_prefix == NULL ) {
3160
- return -1 ;
3161
- }
3162
- }
3163
- match = PyUnicode_Tailmatch (self -> text , exec_prefix , start , text_len , -1 );
3164
- if (match == -1 ) {
3165
- return -1 ;
3166
- }
3167
- if (match ) {
3168
- PyObject * msg = PyUnicode_FromString ("Missing parentheses in call "
3169
- "to 'exec'" );
3170
- if (msg == NULL ) {
3171
- return -1 ;
3172
- }
3173
- Py_XSETREF (self -> msg , msg );
3174
- return 1 ;
3175
- }
3176
- /* Fall back to the default error message */
3177
- return 0 ;
3178
- }
3179
-
3180
- static int
3181
- _report_missing_parentheses (PySyntaxErrorObject * self )
3182
- {
3183
- Py_UCS4 left_paren = 40 ;
3184
- Py_ssize_t left_paren_index ;
3185
- Py_ssize_t text_len = PyUnicode_GET_LENGTH (self -> text );
3186
- int legacy_check_result = 0 ;
3187
-
3188
- /* Skip entirely if there is an opening parenthesis */
3189
- left_paren_index = PyUnicode_FindChar (self -> text , left_paren ,
3190
- 0 , text_len , 1 );
3191
- if (left_paren_index < -1 ) {
3192
- return -1 ;
3193
- }
3194
- if (left_paren_index != -1 ) {
3195
- /* Use default error message for any line with an opening paren */
3196
- return 0 ;
3197
- }
3198
- /* Handle the simple statement case */
3199
- legacy_check_result = _check_for_legacy_statements (self , 0 );
3200
- if (legacy_check_result < 0 ) {
3201
- return -1 ;
3202
-
3203
- }
3204
- if (legacy_check_result == 0 ) {
3205
- /* Handle the one-line complex statement case */
3206
- Py_UCS4 colon = 58 ;
3207
- Py_ssize_t colon_index ;
3208
- colon_index = PyUnicode_FindChar (self -> text , colon ,
3209
- 0 , text_len , 1 );
3210
- if (colon_index < -1 ) {
3211
- return -1 ;
3212
- }
3213
- if (colon_index >= 0 && colon_index < text_len ) {
3214
- /* Check again, starting from just after the colon */
3215
- if (_check_for_legacy_statements (self , colon_index + 1 ) < 0 ) {
3216
- return -1 ;
3217
- }
3218
- }
3219
- }
3220
- return 0 ;
3221
- }
0 commit comments