Skip to content

fix(shell): keep else/elif/except/finally inside multi-line REPL block - #381

Merged
pikasTech merged 1 commit into
pikasTech:masterfrom
akkako:fix/shell-block-else
Sep 11, 2026
Merged

fix(shell): keep else/elif/except/finally inside multi-line REPL block#381
pikasTech merged 1 commit into
pikasTech:masterfrom
akkako:fix/shell-block-else

Conversation

@akkako

@akkako akkako commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

现象

通过串口(CDC)REPL 逐行执行含 if/else 的多行脚本时,条件分支失效:if 分支执行完,else 分支也被无条件执行。

if condition:
    ...
    print('succss')
else:
    ...
    print('fail')

实际输出(两个分支都打印):

succss
fail

原因

_inner_do_obj_runChar()(1.11.8 中为 _do_obj_runChar())用「下一行是否以空格/Tab 开头」来判断是否仍处于缩进块内(PikaObj.c“go out from block”):

if ((shell->lineBuff[0] != ' ') && (shell->lineBuff[0] != '\t')) {
    shell->inBlock = pika_false;            /* 结束块并整段 obj_run */
    ...
}

问题在于:顶层 else: / elif 是顶格无缩进的,所以被判定为“dedent、块结束”。执行顺序变成:

读到 else: 时,它先被追加进块缓冲,随后立刻触发结束 → obj_run() 执行了 if...else:(此时 else 后面还没有 body),于是 if 分支跑完打印 succss
下一行 print('connect fail') 已不在块状态,被当成一条独立语句执行 → else 的 body 被无条件执行,打印 fail

本质上 REPL 把 Python 中“同级的续行关键字”误判成了“块结束”。

修复

新增一个判定函数:缩进行、以及顶格的块续行关键字(else / elif / except / finally)都算作“仍在当前块内”,其它顶格语句才结束块。这样整段 if/for/else 会一次性交给 obj_run() 编译执行。

@pikasTech
pikasTech merged commit 99ea824 into pikasTech:master Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants