Skip to content

Commit

Permalink
bpo-35975: Only use cf_feature_version if PyCF_ONLY_AST in cf_flags (p…
Browse files Browse the repository at this point in the history
  • Loading branch information
gvanrossum authored Jun 28, 2020
1 parent 1f0f4ab commit 9d197c7
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 3 deletions.
21 changes: 21 additions & 0 deletions Lib/test/test_capi.py
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,27 @@ def test_subinterps(self):
self.assertNotEqual(pickle.load(f), id(sys.modules))
self.assertNotEqual(pickle.load(f), id(builtins))

def test_subinterps_recent_language_features(self):
r, w = os.pipe()
code = """if 1:
import pickle
with open({:d}, "wb") as f:
@(lambda x:x) # Py 3.9
def noop(x): return x
a = (b := f'1{{2}}3') + noop('x') # Py 3.8 (:=) / 3.6 (f'')
async def foo(arg): return await arg # Py 3.5
pickle.dump(dict(a=a, b=b), f)
""".format(w)

with open(r, "rb") as f:
ret = support.run_in_subinterp(code)
self.assertEqual(ret, 0)
self.assertEqual(pickle.load(f), {'a': '123x', 'b': '123'})

def test_mutate_exception(self):
"""
Exceptions saved in global module state get shared between
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Stefan Behnel reported that cf_feature_version is used even when
PyCF_ONLY_AST is not set. This is against the intention and against the
documented behavior, so it's been fixed.
4 changes: 3 additions & 1 deletion Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -3468,6 +3468,8 @@ run_in_subinterp(PyObject *self, PyObject *args)
const char *code;
int r;
PyThreadState *substate, *mainstate;
/* only initialise 'cflags.cf_flags' to test backwards compatibility */
PyCompilerFlags cflags = {0};

if (!PyArg_ParseTuple(args, "s:run_in_subinterp",
&code))
Expand All @@ -3486,7 +3488,7 @@ run_in_subinterp(PyObject *self, PyObject *args)
PyErr_SetString(PyExc_RuntimeError, "sub-interpreter creation failed");
return NULL;
}
r = PyRun_SimpleString(code);
r = PyRun_SimpleStringFlags(code, &cflags);
Py_EndInterpreter(substate);

PyThreadState_Swap(mainstate);
Expand Down
5 changes: 3 additions & 2 deletions Parser/pegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,7 @@ compute_parser_flags(PyCompilerFlags *flags)
if (flags->cf_flags & PyCF_TYPE_COMMENTS) {
parser_flags |= PyPARSE_TYPE_COMMENTS;
}
if (flags->cf_feature_version < 7) {
if ((flags->cf_flags & PyCF_ONLY_AST) && flags->cf_feature_version < 7) {
parser_flags |= PyPARSE_ASYNC_HACKS;
}
return parser_flags;
Expand Down Expand Up @@ -1215,7 +1215,8 @@ _PyPegen_run_parser_from_string(const char *str, int start_rule, PyObject *filen
mod_ty result = NULL;

int parser_flags = compute_parser_flags(flags);
int feature_version = flags ? flags->cf_feature_version : PY_MINOR_VERSION;
int feature_version = flags && (flags->cf_flags & PyCF_ONLY_AST) ?
flags->cf_feature_version : PY_MINOR_VERSION;
Parser *p = _PyPegen_Parser_New(tok, start_rule, parser_flags, feature_version,
NULL, arena);
if (p == NULL) {
Expand Down

0 comments on commit 9d197c7

Please sign in to comment.