Skip to content

Commit e3aa9fd

Browse files
authored
[3.10] bpo-45822: Respect PEP 263's coding cookies in the parser even if flags are not provided (GH-29582) (GH-29586)
(cherry picked from commit da20d74) Co-authored-by: Pablo Galindo Salgado <Pablogsal@gmail.com>
1 parent 4ffde90 commit e3aa9fd

File tree

4 files changed

+25
-1
lines changed

4 files changed

+25
-1
lines changed

Lib/test/test_capi.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,6 +1013,14 @@ def test_state_access(self):
10131013
with self.assertRaises(TypeError):
10141014
increment_count(1, 2, 3)
10151015

1016+
def test_Py_CompileString(self):
1017+
# Check that Py_CompileString respects the coding cookie
1018+
_compile = _testcapi.Py_CompileString
1019+
code = b"# -*- coding: latin1 -*-\nprint('\xc2\xa4')\n"
1020+
result = _compile(code)
1021+
expected = compile(code, "<string>", "exec")
1022+
self.assertEqual(result.co_consts, expected.co_consts)
1023+
10161024

10171025
if __name__ == "__main__":
10181026
unittest.main()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed a bug in the parser that was causing it to not respect :pep:`263`
2+
coding cookies when no flags are provided. Patch by Pablo Galindo

Modules/_testcapimodule.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,19 @@ static PyTypeObject _HashInheritanceTester_Type = {
390390
PyType_GenericNew, /* tp_new */
391391
};
392392

393+
static PyObject*
394+
pycompilestring(PyObject* self, PyObject *obj) {
395+
if (PyBytes_CheckExact(obj) == 0) {
396+
PyErr_SetString(PyExc_ValueError, "Argument must be a bytes object");
397+
return NULL;
398+
}
399+
const char *the_string = PyBytes_AsString(obj);
400+
if (the_string == NULL) {
401+
return NULL;
402+
}
403+
return Py_CompileString(the_string, "blech", Py_file_input);
404+
}
405+
393406
static PyObject*
394407
test_lazy_hash_inheritance(PyObject* self, PyObject *Py_UNUSED(ignored))
395408
{
@@ -5826,6 +5839,7 @@ static PyMethodDef TestMethods[] = {
58265839
{"return_null_without_error", return_null_without_error, METH_NOARGS},
58275840
{"return_result_with_error", return_result_with_error, METH_NOARGS},
58285841
{"getitem_with_error", getitem_with_error, METH_VARARGS},
5842+
{"Py_CompileString", pycompilestring, METH_O},
58295843
{"PyTime_FromSeconds", test_pytime_fromseconds, METH_VARARGS},
58305844
{"PyTime_FromSecondsObject", test_pytime_fromsecondsobject, METH_VARARGS},
58315845
{"PyTime_AsSecondsDouble", test_pytime_assecondsdouble, METH_VARARGS},

Parser/pegen.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1434,7 +1434,7 @@ _PyPegen_run_parser_from_string(const char *str, int start_rule, PyObject *filen
14341434
int exec_input = start_rule == Py_file_input;
14351435

14361436
struct tok_state *tok;
1437-
if (flags == NULL || flags->cf_flags & PyCF_IGNORE_COOKIE) {
1437+
if (flags != NULL && flags->cf_flags & PyCF_IGNORE_COOKIE) {
14381438
tok = PyTokenizer_FromUTF8(str, exec_input);
14391439
} else {
14401440
tok = PyTokenizer_FromString(str, exec_input);

0 commit comments

Comments
 (0)