mirror of
https://github.com/python/cpython.git
synced 2025-07-13 14:25:18 +00:00
bpo-41218: Only mark async code with CO_COROUTINE. (#21357)
3.8.3 had a regression where compiling with ast.PyCF_ALLOW_TOP_LEVEL_AWAIT woudl agressively mark things are coroutine even if there were not.
This commit is contained in:
parent
a103e73ce8
commit
bd46174a5a
3 changed files with 29 additions and 4 deletions
|
@ -371,6 +371,25 @@ class BuiltinTest(unittest.TestCase):
|
||||||
rv = ns['f']()
|
rv = ns['f']()
|
||||||
self.assertEqual(rv, tuple(expected))
|
self.assertEqual(rv, tuple(expected))
|
||||||
|
|
||||||
|
def test_compile_top_level_await_no_coro(self):
|
||||||
|
"""Make sure top level non-await codes get the correct coroutine flags.
|
||||||
|
"""
|
||||||
|
modes = ('single', 'exec')
|
||||||
|
code_samples = [
|
||||||
|
'''def f():pass\n''',
|
||||||
|
'''[x for x in l]'''
|
||||||
|
]
|
||||||
|
for mode, code_sample in product(modes, code_samples):
|
||||||
|
source = dedent(code_sample)
|
||||||
|
co = compile(source,
|
||||||
|
'?',
|
||||||
|
mode,
|
||||||
|
flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT)
|
||||||
|
|
||||||
|
self.assertNotEqual(co.co_flags & CO_COROUTINE, CO_COROUTINE,
|
||||||
|
msg=f"source={source} mode={mode}")
|
||||||
|
|
||||||
|
|
||||||
def test_compile_top_level_await(self):
|
def test_compile_top_level_await(self):
|
||||||
"""Test whether code some top level await can be compiled.
|
"""Test whether code some top level await can be compiled.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Python 3.8.3 had a regression where compiling with
|
||||||
|
ast.PyCF_ALLOW_TOP_LEVEL_AWAIT would aggressively mark list comprehension
|
||||||
|
with CO_COROUTINE. Now only list comprehension making use of async/await
|
||||||
|
will tagged as so.
|
|
@ -4588,10 +4588,9 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,
|
||||||
comprehension_ty outermost;
|
comprehension_ty outermost;
|
||||||
PyObject *qualname = NULL;
|
PyObject *qualname = NULL;
|
||||||
int is_async_generator = 0;
|
int is_async_generator = 0;
|
||||||
|
int top_level_await = IS_TOP_LEVEL_AWAIT(c);
|
||||||
|
|
||||||
|
|
||||||
if (IS_TOP_LEVEL_AWAIT(c)) {
|
|
||||||
c->u->u_ste->ste_coroutine = 1;
|
|
||||||
}
|
|
||||||
int is_async_function = c->u->u_ste->ste_coroutine;
|
int is_async_function = c->u->u_ste->ste_coroutine;
|
||||||
|
|
||||||
outermost = (comprehension_ty) asdl_seq_GET(generators, 0);
|
outermost = (comprehension_ty) asdl_seq_GET(generators, 0);
|
||||||
|
@ -4603,7 +4602,7 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,
|
||||||
|
|
||||||
is_async_generator = c->u->u_ste->ste_coroutine;
|
is_async_generator = c->u->u_ste->ste_coroutine;
|
||||||
|
|
||||||
if (is_async_generator && !is_async_function && type != COMP_GENEXP) {
|
if (is_async_generator && !is_async_function && type != COMP_GENEXP && !top_level_await) {
|
||||||
compiler_error(c, "asynchronous comprehension outside of "
|
compiler_error(c, "asynchronous comprehension outside of "
|
||||||
"an asynchronous function");
|
"an asynchronous function");
|
||||||
goto error_in_scope;
|
goto error_in_scope;
|
||||||
|
@ -4642,6 +4641,9 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,
|
||||||
qualname = c->u->u_qualname;
|
qualname = c->u->u_qualname;
|
||||||
Py_INCREF(qualname);
|
Py_INCREF(qualname);
|
||||||
compiler_exit_scope(c);
|
compiler_exit_scope(c);
|
||||||
|
if (top_level_await && is_async_generator){
|
||||||
|
c->u->u_ste->ste_coroutine = 1;
|
||||||
|
}
|
||||||
if (co == NULL)
|
if (co == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue