From d43cf9c61792c999c7ebc020ee7c770bf0036d5e Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 18 May 2023 19:58:27 -0700 Subject: [PATCH] gh-104640: Disallow walrus in comprehension within type scopes --- Lib/test/test_type_params.py | 3 +++ Python/symtable.c | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_type_params.py b/Lib/test/test_type_params.py index 466e3bd43a68e5..d4f5de573f51d2 100644 --- a/Lib/test/test_type_params.py +++ b/Lib/test/test_type_params.py @@ -136,6 +136,9 @@ def test_disallowed_expressions(self): check_syntax_error(self, "class X[T: (y := 3)]: pass") check_syntax_error(self, "class X[T](y := Sequence[T]): pass") check_syntax_error(self, "def f[T](y: (x := Sequence[T])): pass") + check_syntax_error(self, "class X[T]([(x := 3) for _ in range(2)] and B): pass") + check_syntax_error(self, "def f[T: [(x := 3) for _ in range(2)]](): pass") + check_syntax_error(self, "type T = [(x := 3) for _ in range(2)]") class TypeParamsNonlocalTest(unittest.TestCase): diff --git a/Python/symtable.c b/Python/symtable.c index bd523f0cdd7409..73cbb2b8e995b2 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -35,6 +35,15 @@ #define NAMED_EXPR_COMP_IN_CLASS \ "assignment expression within a comprehension cannot be used in a class body" +#define NAMED_EXPR_COMP_IN_TYPEVAR_BOUND \ +"assignment expression within a comprehension cannot be used in a TypeVar bound" + +#define NAMED_EXPR_COMP_IN_TYPEALIAS \ +"assignment expression within a comprehension cannot be used in a type alias" + +#define NAMED_EXPR_COMP_IN_TYPEPARAM \ +"assignment expression within a comprehension cannot be used within the definition of a generic" + #define NAMED_EXPR_COMP_CONFLICT \ "assignment expression cannot rebind comprehension iteration variable '%U'" @@ -1857,7 +1866,7 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e) } /* If we find a FunctionBlock entry, add as GLOBAL/LOCAL or NONLOCAL/LOCAL */ - if (_PyST_IsFunctionLike(ste)) { + if (ste->ste_type == FunctionBlock) { long target_in_scope = _PyST_GetSymbol(ste, target_name); if (target_in_scope & DEF_GLOBAL) { if (!symtable_add_def(st, target_name, DEF_GLOBAL, LOCATION(e))) @@ -1880,9 +1889,27 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e) return symtable_add_def_helper(st, target_name, DEF_GLOBAL, ste, LOCATION(e)); } - /* Disallow usage in ClassBlock */ - if (ste->ste_type == ClassBlock) { - PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_IN_CLASS); + /* Disallow usage in ClassBlock and type scopes */ + if (ste->ste_type == ClassBlock || + ste->ste_type == TypeParamBlock || + ste->ste_type == TypeAliasBlock || + ste->ste_type == TypeVarBoundBlock) { + switch (ste->ste_type) { + case ClassBlock: + PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_IN_CLASS); + break; + case TypeParamBlock: + PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_IN_TYPEPARAM); + break; + case TypeAliasBlock: + PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_IN_TYPEALIAS); + break; + case TypeVarBoundBlock: + PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_IN_TYPEVAR_BOUND); + break; + default: + Py_UNREACHABLE(); + } PyErr_RangedSyntaxLocationObject(st->st_filename, e->lineno, e->col_offset + 1, pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy