From 05e8a550e14912fe2152862d97876f362c6b1bb9 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sat, 20 Jun 2020 17:10:25 -0700 Subject: [PATCH 1/5] [3.8] bpo-35975: Only use cf_feature_version if PyCF_ONLY_AST in cf_flags --- Python/ast.c | 3 ++- Python/pythonrun.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Python/ast.c b/Python/ast.c index 0a999fcca43a8e..52ff0a3a53d89c 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -808,7 +808,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 a7da143077a7a7..6cdd8ea7a6ab19 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1337,7 +1337,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, From 2235257bf3dd7640ef4e5ccea16ed8f70a80052b Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sat, 20 Jun 2020 17:23:22 -0700 Subject: [PATCH 2/5] Add blurb --- .../Core and Builtins/2020-06-20-17-21-07.bpo-35975.UDHCHp.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-20-17-21-07.bpo-35975.UDHCHp.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-20-17-21-07.bpo-35975.UDHCHp.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-20-17-21-07.bpo-35975.UDHCHp.rst new file mode 100644 index 00000000000000..f44a90e783f15b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-20-17-21-07.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 I fixed it. From 1311ec742103b002fa45df974086da3110afc6e3 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sun, 21 Jun 2020 10:14:44 -0700 Subject: [PATCH 3/5] Add test by Stefan Behnel --- Lib/test/test_capi.py | 21 +++++++++++++++++++++ Modules/_testcapimodule.c | 4 +++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 584c1046450311..1028587a200555 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -584,6 +584,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 diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index da3579c2cc6fdc..f74756163f8633 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3345,6 +3345,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)) @@ -3363,7 +3365,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); From 4d7dabd958359f26068bb4c0282b3af5897930a7 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sun, 21 Jun 2020 10:23:51 -0700 Subject: [PATCH 4/5] Remove 3.9 feature from test --- Lib/test/test_capi.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 1028587a200555..d1506bc17732f0 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -590,7 +590,6 @@ def test_subinterps_recent_language_features(self): 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'') From 858dc88ce4cdfb581df8ebb50b5f20f4101761cd Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sun, 21 Jun 2020 18:00:54 -0700 Subject: [PATCH 5/5] Tweak blurb per Victor's request --- .../Core and Builtins/2020-06-20-17-21-07.bpo-35975.UDHCHp.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-20-17-21-07.bpo-35975.UDHCHp.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-20-17-21-07.bpo-35975.UDHCHp.rst index f44a90e783f15b..73f4a6da2e5c0a 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-20-17-21-07.bpo-35975.UDHCHp.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-20-17-21-07.bpo-35975.UDHCHp.rst @@ -1,3 +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 I fixed it. +documented behavior, so it's been fixed.