mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	gh-121637: Syntax error for optimized-away incorrect await (#121656)
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									69f2dc5c06
								
							
						
					
					
						commit
						2762c6cc5e
					
				
					 5 changed files with 104 additions and 52 deletions
				
			
		|  | @ -5675,14 +5675,16 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, | |||
|     PyCodeObject *co = NULL; | ||||
|     inlined_comprehension_state inline_state = {NULL, NULL, NULL, NO_LABEL, NO_LABEL}; | ||||
|     comprehension_ty outermost; | ||||
| #ifndef NDEBUG | ||||
|     int scope_type = c->u->u_scope_type; | ||||
|     int is_top_level_await = IS_TOP_LEVEL_AWAIT(c); | ||||
| #endif | ||||
|     PySTEntryObject *entry = _PySymtable_Lookup(SYMTABLE(c), (void *)e); | ||||
|     if (entry == NULL) { | ||||
|         goto error; | ||||
|     } | ||||
|     int is_inlined = entry->ste_comp_inlined; | ||||
|     int is_async_generator = entry->ste_coroutine; | ||||
|     int is_async_comprehension = entry->ste_coroutine; | ||||
| 
 | ||||
|     location loc = LOC(e); | ||||
| 
 | ||||
|  | @ -5697,22 +5699,17 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, | |||
|     } | ||||
|     else { | ||||
|         if (compiler_enter_scope(c, name, COMPILER_SCOPE_COMPREHENSION, | ||||
|                                 (void *)e, e->lineno, NULL) < 0) | ||||
|         { | ||||
|                                 (void *)e, e->lineno, NULL) < 0) { | ||||
|             goto error; | ||||
|         } | ||||
|     } | ||||
|     Py_CLEAR(entry); | ||||
| 
 | ||||
|     if (is_async_generator && type != COMP_GENEXP && | ||||
|         scope_type != COMPILER_SCOPE_ASYNC_FUNCTION && | ||||
|         scope_type != COMPILER_SCOPE_COMPREHENSION && | ||||
|         !is_top_level_await) | ||||
|     { | ||||
|         compiler_error(c, loc, "asynchronous comprehension outside of " | ||||
|                                "an asynchronous function"); | ||||
|         goto error_in_scope; | ||||
|     } | ||||
|     assert (!is_async_comprehension || | ||||
|             type == COMP_GENEXP || | ||||
|             scope_type == COMPILER_SCOPE_ASYNC_FUNCTION || | ||||
|             scope_type == COMPILER_SCOPE_COMPREHENSION || | ||||
|             is_top_level_await); | ||||
| 
 | ||||
|     if (type != COMP_GENEXP) { | ||||
|         int op; | ||||
|  | @ -5777,7 +5774,7 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, | |||
| 
 | ||||
|     ADDOP_I(c, loc, CALL, 0); | ||||
| 
 | ||||
|     if (is_async_generator && type != COMP_GENEXP) { | ||||
|     if (is_async_comprehension && type != COMP_GENEXP) { | ||||
|         ADDOP_I(c, loc, GET_AWAITABLE, 0); | ||||
|         ADDOP_LOAD_CONST(c, loc, Py_None); | ||||
|         ADD_YIELD_FROM(c, loc, 1); | ||||
|  | @ -6138,16 +6135,10 @@ compiler_visit_expr(struct compiler *c, expr_ty e) | |||
|         ADD_YIELD_FROM(c, loc, 0); | ||||
|         break; | ||||
|     case Await_kind: | ||||
|         if (!IS_TOP_LEVEL_AWAIT(c)){ | ||||
|             if (!_PyST_IsFunctionLike(SYMTABLE_ENTRY(c))) { | ||||
|                 return compiler_error(c, loc, "'await' outside function"); | ||||
|             } | ||||
| 
 | ||||
|             if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION && | ||||
|                     c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION) { | ||||
|                 return compiler_error(c, loc, "'await' outside async function"); | ||||
|             } | ||||
|         } | ||||
|         assert(IS_TOP_LEVEL_AWAIT(c) || (_PyST_IsFunctionLike(SYMTABLE_ENTRY(c)) && ( | ||||
|             c->u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION || | ||||
|             c->u->u_scope_type == COMPILER_SCOPE_COMPREHENSION | ||||
|         ))); | ||||
| 
 | ||||
|         VISIT(c, expr, e->v.Await.value); | ||||
|         ADDOP_I(c, loc, GET_AWAITABLE, 0); | ||||
|  |  | |||
|  | @ -70,10 +70,10 @@ | |||
| #define DUPLICATE_TYPE_PARAM \ | ||||
| "duplicate type parameter '%U'" | ||||
| 
 | ||||
| #define ASYNC_WITH_OUTISDE_ASYNC_FUNC \ | ||||
| #define ASYNC_WITH_OUTSIDE_ASYNC_FUNC \ | ||||
| "'async with' outside async function" | ||||
| 
 | ||||
| #define ASYNC_FOR_OUTISDE_ASYNC_FUNC \ | ||||
| #define ASYNC_FOR_OUTSIDE_ASYNC_FUNC \ | ||||
| "'async for' outside async function" | ||||
| 
 | ||||
| #define LOCATION(x) SRC_LOCATION_FROM_AST(x) | ||||
|  | @ -82,6 +82,8 @@ | |||
|     PyErr_RangedSyntaxLocationObject((FNAME), \ | ||||
|         (L).lineno, (L).col_offset + 1, (L).end_lineno, (L).end_col_offset + 1) | ||||
| 
 | ||||
| #define IS_ASYNC_DEF(st) ((st)->st_cur->ste_type == FunctionBlock && (st)->st_cur->ste_coroutine) | ||||
| 
 | ||||
| static PySTEntryObject * | ||||
| ste_new(struct symtable *st, identifier name, _Py_block_ty block, | ||||
|         void *key, _Py_SourceLocation loc) | ||||
|  | @ -1660,12 +1662,18 @@ check_import_from(struct symtable *st, stmt_ty s) | |||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| allows_top_level_await(struct symtable *st) | ||||
| { | ||||
|     return (st->st_future->ff_features & PyCF_ALLOW_TOP_LEVEL_AWAIT) && | ||||
|             st->st_cur->ste_type == ModuleBlock; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void | ||||
| maybe_set_ste_coroutine_for_module(struct symtable *st, stmt_ty s) | ||||
| { | ||||
|     if ((st->st_future->ff_features & PyCF_ALLOW_TOP_LEVEL_AWAIT) && | ||||
|         (st->st_cur->ste_type == ModuleBlock)) | ||||
|     { | ||||
|     if (allows_top_level_await(st)) { | ||||
|         st->st_cur->ste_coroutine = 1; | ||||
|     } | ||||
| } | ||||
|  | @ -2054,7 +2062,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) | |||
|     } | ||||
|     case AsyncWith_kind: | ||||
|         maybe_set_ste_coroutine_for_module(st, s); | ||||
|         if (!symtable_raise_if_not_coroutine(st, ASYNC_WITH_OUTISDE_ASYNC_FUNC, LOCATION(s))) { | ||||
|         if (!symtable_raise_if_not_coroutine(st, ASYNC_WITH_OUTSIDE_ASYNC_FUNC, LOCATION(s))) { | ||||
|             VISIT_QUIT(st, 0); | ||||
|         } | ||||
|         VISIT_SEQ(st, withitem, s->v.AsyncWith.items); | ||||
|  | @ -2062,7 +2070,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) | |||
|         break; | ||||
|     case AsyncFor_kind: | ||||
|         maybe_set_ste_coroutine_for_module(st, s); | ||||
|         if (!symtable_raise_if_not_coroutine(st, ASYNC_FOR_OUTISDE_ASYNC_FUNC, LOCATION(s))) { | ||||
|         if (!symtable_raise_if_not_coroutine(st, ASYNC_FOR_OUTSIDE_ASYNC_FUNC, LOCATION(s))) { | ||||
|             VISIT_QUIT(st, 0); | ||||
|         } | ||||
|         VISIT(st, expr, s->v.AsyncFor.target); | ||||
|  | @ -2279,6 +2287,20 @@ symtable_visit_expr(struct symtable *st, expr_ty e) | |||
|         if (!symtable_raise_if_annotation_block(st, "await expression", e)) { | ||||
|             VISIT_QUIT(st, 0); | ||||
|         } | ||||
|         if (!allows_top_level_await(st)) { | ||||
|             if (!_PyST_IsFunctionLike(st->st_cur)) { | ||||
|                 PyErr_SetString(PyExc_SyntaxError, | ||||
|                                 "'await' outside function"); | ||||
|                 SET_ERROR_LOCATION(st->st_filename, LOCATION(e)); | ||||
|                 VISIT_QUIT(st, 0); | ||||
|             } | ||||
|             if (!IS_ASYNC_DEF(st) && st->st_cur->ste_comprehension == NoComprehension) { | ||||
|                 PyErr_SetString(PyExc_SyntaxError, | ||||
|                                 "'await' outside async function"); | ||||
|                 SET_ERROR_LOCATION(st->st_filename, LOCATION(e)); | ||||
|                 VISIT_QUIT(st, 0); | ||||
|             } | ||||
|         } | ||||
|         VISIT(st, expr, e->v.Await.value); | ||||
|         st->st_cur->ste_coroutine = 1; | ||||
|         break; | ||||
|  | @ -2798,6 +2820,16 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e, | |||
|     if (!symtable_exit_block(st)) { | ||||
|         return 0; | ||||
|     } | ||||
|     if (is_async && | ||||
|         !IS_ASYNC_DEF(st) && | ||||
|         st->st_cur->ste_comprehension == NoComprehension && | ||||
|         !allows_top_level_await(st)) | ||||
|     { | ||||
|         PyErr_SetString(PyExc_SyntaxError, "asynchronous comprehension outside of " | ||||
|                                            "an asynchronous function"); | ||||
|         SET_ERROR_LOCATION(st->st_filename, LOCATION(e)); | ||||
|         return 0; | ||||
|     } | ||||
|     if (is_async) { | ||||
|         st->st_cur->ste_coroutine = 1; | ||||
|     } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jelle Zijlstra
						Jelle Zijlstra