fix(ast): 解析 PEP695 泛型函数类型参数 [T],修复函数体被误提升模块级
- _parse_funcdef 消费并存储 def f[T](...) 的类型参数(与 class 解析器一致) - FunctionDef 增加 type_params 字段(默认 None,非泛型函数不受影响) - 修复: 之前 [T] 未消费导致 _expect_op(Colon) 失败、函数体被误提升到模块级,b = Box(42) 被注册为模块级全局,函数内赋值误报需用 global 声明
This commit is contained in:
1 parent
2fb386a4ff
commit
44ff0d551f
2 files changed
+31
-3
No files matched your search
+22
-1
@@ -1929,6 +1929,27 @@ def _parse_funcdef(ps: Parser | t.CPtr, is_async: t.CInt) -> AST | t.CPtr:
|
||||
return None
|
||||
name: str = _cur_str(ps)
|
||||
_advance(ps)
|
||||
# PEP 695 泛型函数类型参数: def add[T](a: T, b: T) — 解析并存入 type_params。
|
||||
# (与 class 解析器一致;之前缺失此处理导致 _expect_op(Colon) 失败、函数体被
|
||||
# 误提升到模块级——b = Box(42) 被当作模块级全局注册,函数内赋值误报
|
||||
# "需用 global 声明"。翻译时 type_params 映射到 int 兜底。)
|
||||
type_params_fd: list[str] | t.CPtr = None
|
||||
if _accept_op(ps, TokOp.Lsqb):
|
||||
type_params_fd = list[str](ps.pool, 8)
|
||||
while not _match_op(ps, TokOp.Rsqb):
|
||||
if _cur_type(ps) == TokenType.EndMarker:
|
||||
break
|
||||
if _cur_type(ps) == TokenType.Name:
|
||||
tp_name_fd: str = _cur_str(ps)
|
||||
_advance(ps)
|
||||
# 跳过可选 bound/约束: [T: bound] 或 [T: (A, B)]
|
||||
if _match_op(ps, TokOp.Colon):
|
||||
_advance(ps)
|
||||
_parse_test(ps)
|
||||
type_params_fd.append(tp_name_fd)
|
||||
if not _accept_op(ps, TokOp.Comma):
|
||||
break
|
||||
_expect_op(ps, TokOp.Rsqb)
|
||||
args: AST | t.CPtr = None
|
||||
if _accept_op(ps, TokOp.LPar):
|
||||
args = _parse_varargslist(ps, 0)
|
||||
@@ -1939,7 +1960,7 @@ def _parse_funcdef(ps: Parser | t.CPtr, is_async: t.CInt) -> AST | t.CPtr:
|
||||
_expect_op(ps, TokOp.Colon)
|
||||
dec_list: list[AST | t.CPtr] | t.CPtr = ps.pending_decorators
|
||||
ps.pending_decorators = None
|
||||
node: FunctionDef | t.CPtr = FunctionDef(ps.pool, name, args, dec_list, returns, is_async)
|
||||
node: FunctionDef | t.CPtr = FunctionDef(ps.pool, name, args, dec_list, returns, is_async, type_params_fd)
|
||||
_parse_suite_into_children(ps, node)
|
||||
_set_pos(node, lineno, col, 0, 0)
|
||||
return node
|
||||
|
||||
@@ -307,12 +307,17 @@ class Expr(AST):
|
||||
|
||||
class FunctionDef(AST):
|
||||
"""FunctionDef(name: str, args: AST,
|
||||
decorator_list: list[AST | t.CPtr], returns: AST, flags: CInt)"""
|
||||
decorator_list: list[AST | t.CPtr], returns: AST, flags: CInt,
|
||||
type_params: list[str] | t.CPtr = None)
|
||||
|
||||
type_params: 泛型函数类型参数名列表(PEP 695 def f[T](...): 中的 [T]),
|
||||
None 表示非泛型函数。"""
|
||||
name: str
|
||||
args: AST | t.CPtr
|
||||
decorator_list: list[AST | t.CPtr] | t.CPtr
|
||||
returns: AST | t.CPtr
|
||||
flags: t.CInt
|
||||
type_params: list[str] | t.CPtr
|
||||
|
||||
def __new__(self, pool: memhub.MemManager | t.CPtr,
|
||||
name: str, args: AST | t.CPtr,
|
||||
@@ -326,12 +331,14 @@ class FunctionDef(AST):
|
||||
def __init__(self, pool: memhub.MemManager | t.CPtr,
|
||||
name: str, args: AST | t.CPtr,
|
||||
decorator_list: list[AST | t.CPtr] | t.CPtr,
|
||||
returns: AST | t.CPtr, is_async: t.CInt):
|
||||
returns: AST | t.CPtr, is_async: t.CInt,
|
||||
type_params: list[str] | t.CPtr = None):
|
||||
_init_ast(self, pool, 0, 0)
|
||||
self.name = _copy_str(pool, name)
|
||||
self.args = args
|
||||
self.decorator_list = decorator_list
|
||||
self.returns = returns
|
||||
self.type_params = type_params
|
||||
if is_async:
|
||||
self.flags = FLAG_IS_ASYNC
|
||||
else:
|
||||
|
||||
Reference in new issue
Block a user