🐛 fix(playbook): import Optional for cli compatibility

restore the missing typing.Optional import in scripts/playbook.py
so older python runtimes can import the CLI module successfully.

add a regression test for typing annotation imports and register it
in the tests README.
This commit is contained in:
csh 2026-05-19 10:08:02 +08:00
parent 63e24bfe54
commit c0729c7933
3 changed files with 34 additions and 0 deletions

View File

@ -6,6 +6,7 @@ from pathlib import Path
from shutil import copy2, copytree, rmtree, which
import subprocess
import importlib.util
from typing import Optional
try:
import tomllib

View File

@ -14,6 +14,7 @@ tests/
├── test_firstparty_skills_quality.py # first-party skills 元数据与结构质量测试
├── test_gitattributes_modes.py # gitattr_mode 行为测试
├── test_no_backup_flags.py # no_backup 行为测试
├── test_playbook_typing_imports.py # playbook.py typing 导入兼容性测试
├── test_sync_directory_actions.py # sync_memory_bank/sync_prompts 行为测试
├── test_vendor_snapshot_templates.py # vendor 快照模板完整性测试
├── test_main_loop_cli.py # main_loop CLI 测试

View File

@ -0,0 +1,32 @@
import ast
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
PLAYBOOK_SCRIPT = ROOT / "scripts" / "playbook.py"
class PlaybookTypingImportTests(unittest.TestCase):
def test_optional_annotation_names_are_imported(self):
tree = ast.parse(PLAYBOOK_SCRIPT.read_text(encoding="utf-8"))
imported_names: set[str] = set()
referenced_names: set[str] = set()
for node in ast.walk(tree):
if isinstance(node, ast.Import):
for alias in node.names:
imported_names.add(alias.asname or alias.name.split(".")[0])
elif isinstance(node, ast.ImportFrom):
for alias in node.names:
imported_names.add(alias.asname or alias.name)
elif isinstance(node, ast.Name):
referenced_names.add(node.id)
if "Optional" in referenced_names:
self.assertIn("Optional", imported_names)
if __name__ == "__main__":
unittest.main()