summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_capi.py21
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2020-06-20-17-16-25.bpo-35975.UDHCHp.rst3
-rw-r--r--Modules/_testcapimodule.c4
-rw-r--r--Parser/pegen/pegen.c5
-rw-r--r--Python/ast.c3
-rw-r--r--Python/pythonrun.c2
6 files changed, 33 insertions, 5 deletions
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
index a9e051d..4efecfd 100644
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -626,6 +626,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
diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-20-17-16-25.bpo-35975.UDHCHp.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-20-17-16-25.bpo-35975.UDHCHp.rst
new file mode 100644
index 0000000..73f4a6d
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-20-17-16-25.bpo-35975.UDHCHp.rst
@@ -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.
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 8e1ee85..de14408 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -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);
diff --git a/Parser/pegen/pegen.c b/Parser/pegen/pegen.c
index ef48ade..895677b 100644
--- a/Parser/pegen/pegen.c
+++ b/Parser/pegen/pegen.c
@@ -1041,7 +1041,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;
@@ -1214,7 +1214,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) {
diff --git a/Python/ast.c b/Python/ast.c
index 3278586..c7ba4d9 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -777,7 +777,8 @@ PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags,
/* borrowed reference */
c.c_filename = filename;
c.c_normalize = NULL;
- c.c_feature_version = flags ? flags->cf_feature_version : PY_MINOR_VERSION;
+ c.c_feature_version = flags && (flags->cf_flags & PyCF_ONLY_AST) ?
+ flags->cf_feature_version : PY_MINOR_VERSION;
if (TYPE(n) == encoding_decl)
n = CHILD(n, 0);
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index cb0e3b0..70748dc 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -1402,7 +1402,7 @@ PyParser_ASTFromStringObject(const char *s, PyObject *filename, int start,
PyCompilerFlags localflags = _PyCompilerFlags_INIT;
perrdetail err;
int iflags = PARSER_FLAGS(flags);
- if (flags && flags->cf_feature_version < 7)
+ if (flags && (flags->cf_flags & PyCF_ONLY_AST) && flags->cf_feature_version < 7)
iflags |= PyPARSE_ASYNC_HACKS;
node *n = PyParser_ParseStringObject(s, filename,