Skip to content

Commit dee456e

Browse files
Propagate error in parser
1 parent 7990313 commit dee456e

File tree

3 files changed

+27
-0
lines changed

3 files changed

+27
-0
lines changed

Lib/test/test_type_comments.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import ast
22
import sys
33
import unittest
4+
from test.support import import_helper
45

56

67
funcdef = """\
@@ -391,6 +392,13 @@ def check_both_ways(source):
391392
check_both_ways("pass # type: ignorewhatever\n")
392393
check_both_ways("pass # type: ignoreé\n")
393394

395+
def test_non_utf8_type_comment_with_ignore_cookie(self):
396+
_testcapi = import_helper.import_module('_testcapi')
397+
flags = 0x0800 | 0x1000 # PyCF_IGNORE_COOKIE | PyCF_TYPE_COMMENTS
398+
with self.assertRaises(UnicodeDecodeError):
399+
_testcapi.Py_CompileStringExFlags(
400+
b"a=1 # type: \x80", "<test>", 256, flags)
401+
394402
def test_func_type_input(self):
395403

396404
def parse_func_type_input(source):

Modules/_testcapimodule.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,18 @@ pycompilestring(PyObject* self, PyObject *obj) {
226226
return Py_CompileString(the_string, "<string>", Py_file_input);
227227
}
228228

229+
static PyObject*
230+
pycompilestringexflags(PyObject *self, PyObject *args) {
231+
const char *the_string, *filename;
232+
int start, flags;
233+
if (!PyArg_ParseTuple(args, "ysii", &the_string, &filename, &start, &flags)) {
234+
return NULL;
235+
}
236+
PyCompilerFlags cf = _PyCompilerFlags_INIT;
237+
cf.cf_flags = flags;
238+
return Py_CompileStringExFlags(the_string, filename, start, &cf, -1);
239+
}
240+
229241
static PyObject*
230242
test_lazy_hash_inheritance(PyObject* self, PyObject *Py_UNUSED(ignored))
231243
{
@@ -2659,6 +2671,7 @@ static PyMethodDef TestMethods[] = {
26592671
{"return_result_with_error", return_result_with_error, METH_NOARGS},
26602672
{"getitem_with_error", getitem_with_error, METH_VARARGS},
26612673
{"Py_CompileString", pycompilestring, METH_O},
2674+
{"Py_CompileStringExFlags", pycompilestringexflags, METH_VARARGS},
26622675
{"raise_SIGINT_then_send_None", raise_SIGINT_then_send_None, METH_VARARGS},
26632676
{"stack_pointer", stack_pointer, METH_NOARGS},
26642677
#ifdef W_STOPCODE

Parser/pegen.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,12 @@ _PyPegen_run_parser(Parser *p)
966966
return NULL;
967967
}
968968

969+
// If parsing succeeded but error_indicator was set the error was not propagated.
970+
// Avoids hitting assert(!PyErr_Occurred()) in _PyAST_Validate.
971+
if (p->error_indicator && PyErr_Occurred()) {
972+
return NULL;
973+
}
974+
969975
if (p->start_rule == Py_single_input && bad_single_statement(p)) {
970976
p->tok->done = E_BADSINGLE; // This is not necessary for now, but might be in the future
971977
return RAISE_SYNTAX_ERROR("multiple statements found while compiling a single statement");

0 commit comments

Comments
 (0)