返回 Bug 清单
BUG-0216project-08高已修复backend-logic

局部导入作用域错误 —— 函数内 import 不外泄,另一函数调用即 NameError

发现:2026-09-30验证:2026-10-31置信度:98%

症状

某后台线程启动成功、日志显示 scheduler started,但紧接着第一次扫描就报 NameError: name 'xxx' is not defined,功能实际不可用。而代码里【明明有】from .alerts import check_and_alert。

根因

那个 import 写在【调用方函数】_start_auto_renew_scheduler 的函数体内,而不是模块顶层。Python 的函数内 import 只在该函数的【局部作用域】生效,不会外泄给同模块的其它函数。于是 _scan_and_renew 里调用 check_and_alert 时找不到该名字 ⇒ NameError ⇒ 被外层 try/except 捕获 ⇒ 记为 ERROR,线程继续循环,功能静默失效。

修复方案

1) 把被多个函数共用的 import 提到【模块顶层】——这是最直接的修法; 2) 若因循环依赖必须在函数内导入,则每个使用它的函数都要各自导入; 3) 更根本:不要让『启动成功』作为功能可用的证据 —— 后台线程应有【首轮执行成功】的日志或指标,而不是只有 started; 4) 用静态检查兜住这类问题:ruff/pyflakes 的 F821 (undefined name) 能在 CI 阶段发现,比运行时才发现早得多。

检测命令

python3 -m pyflakes <module>.py | grep F821   # 或 rg -n 'def .*\n(.|\n)*?from .* import' 找函数内 import

修复命令

def _scan_and_renew(...):
    from .alerts import check_and_alert  # 补上局部导入
    ...
# 更好的做法:把 import 移到模块顶层

错误签名

[ERROR] omnicert: [auto-renew] scan failed: name 'check_and_alert' is not defined

技术信息

来源项目

project-08

标签

python, import-scope, nameerror, silent-failure, background-thread...