fix: 反啃 CPython 标准库全量 (630 文件) 修复函数内 import 漏注册

- _ScopeAnalyzer 缺 visit_Import/visit_ImportFrom → 函数内 import (局部导入) 的名字没注册进作用域
  → aifc.py math/audioop、argparse.py copy/shutil/textwrap 等 763 个 E002 误报消除
- E002 无 jedi 全量: 2332 → 1569 (剩余为 import* 盲区 + 模块级条件导入, jedi 会消大半)
- E004 216 条抽查: enum i(空串真炸)/gzip buf(else 不赋) 为合理保留; functools candidate/dataclasses value 为条件关联盲区
- 新增 2 回归测试 (函数内 import / import from); 304 passed
This commit is contained in:
shuiyu67 committed 2026-08-07 09:04:53 +08:00
1 parent e16234aba9
commit 1049370231
2 files changed
+29

No files matched your search

+16
View File
@@ -351,6 +351,22 @@ class _ScopeAnalyzer(ast.NodeVisitor):
self.generic_visit(node)
self.scope_stack.pop()
def visit_Import(self, node: ast.Import):
if self.scope_stack:
for alias in node.names:
name = (alias.asname or alias.name).split(".")[0]
self.scope_stack[-1][name] = "导入" # 函数内 import (局部导入)
self.generic_visit(node)
def visit_ImportFrom(self, node: ast.ImportFrom):
if self.scope_stack:
for alias in node.names:
if alias.name == "*":
continue
name = alias.asname or alias.name
self.scope_stack[-1][name] = "导入"
self.generic_visit(node)
def visit_Lambda(self, node: ast.Lambda):
for a in node.args.args:
self._declare(a.arg)
+13
View File
@@ -580,6 +580,19 @@ class TestDataFlow:
assert "E002" not in {d["code"] for d in pd.analyze(src, "t.py")}
assert "E004" not in {d["code"] for d in pd.analyze(src, "t.py")}
def test_function_local_import_ok(self, pd):
"""函数内 import 不得误报 E002 (标准库 aifc math / argparse copy 场景)"""
src = ("def f(x):\n"
" import math\n"
" return math.frexp(x)\n")
assert "E002" not in {d["code"] for d in pd.analyze(src, "t.py")}
def test_function_local_import_from_ok(self, pd):
src = ("def f():\n"
" from math import sqrt\n"
" return sqrt(4)\n")
assert "E002" not in {d["code"] for d in pd.analyze(src, "t.py")}
def test_const_iter_always_runs(self, pd):
"""for f in ('a','b','c'): 常量非空 → 循环变量确定 (pydantic v1 host 场景)"""
src = ("def f(parts):\n"