Browse Source
bpo-35975: Only use cf_feature_version if PyCF_ONLY_AST in cf_flags (#21021)
pull/21197/head
Guido van Rossum
6 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with
30 additions and
3 deletions
-
Lib/test/test_capi.py
-
Misc/NEWS.d/next/Core and Builtins/2020-06-20-17-00-44.bpo-35975.UDHCHp.rst
-
Modules/_testcapimodule.c
-
Parser/pegen.c
|
|
|
@ -627,6 +627,27 @@ class SubinterpreterTest(unittest.TestCase): |
|
|
|
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 |
|
|
|
|
|
|
|
@ -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. |
|
|
|
@ -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)) |
|
|
|
@ -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); |
|
|
|
|
|
|
|
@ -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; |
|
|
|
@ -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) { |
|
|
|
|