Skip to content

Conversation

@e2720pjk
Copy link
Owner

@e2720pjk e2720pjk commented Dec 24, 2025

概述

修復 codesage config init --interactive 命令中的 ValueError 錯誤,該錯誤由於 questionary.checkbox()default 參數接受了錯誤的數據類型導致。修復方案使用 questionary.Choice 對象的正確 API 來實現多選項預選功能。

問題描述

錯誤訊息

執行以下命令時:

poetry run codesage config init --interactive

在完成語言選擇和排除模式輸入後,會出現以下錯誤:

Welcome to the CodeSage configuration wizard!
? Select the languages you want to analyze: done (3 selections)
? Enter file patterns to exclude (comma-separated): .*,node_modules,vendor
Traceback (most recent call last):
  ...
  File "cli-tool/CodeSnapAI/codesage/cli/interactive.py", line 22, in run_wizard
    snapshot_formats = questionary.checkbox(
  ...
ValueError: Invalid `default` value passed. The value (`['json', 'markdown']`) does not exist in the set of choices.

影響範圍

  • 影響版本: CodeSnapAI v0.2.0
  • 影響命令: codesage config init --interactive
  • 影響功能: 交互式配置嚮導無法完成

根本原因

1. API 誤用

questionary.checkbox()default 參數類型定義:

def checkbox(
    message: str,
    choices: Sequence[Union[str, Choice, Dict[str, Any]]],
    default: Optional[str] = None,  # ✅ 只能是字符串或 None
    ...
) -> Question:

但代碼中錯誤地傳遞了列表:

# codesage/cli/interactive.py:22-26
snapshot_formats = questionary.checkbox(
    "Select the snapshot formats to generate:",
    choices=['json', 'markdown', 'yaml'],
    default=['json', 'markdown']  # ❌ 錯誤:default 不接受列表
).ask()

2. 正確的 API 用法

根據 questionary 文檔,若要預選多個選項,應使用 Choice 對象:

from questionary import Choice

snapshot_formats = questionary.checkbox(
    "Select the snapshot formats to generate:",
    choices=[
        Choice('json', checked=True),      # ✅ 使用 checked=True 預選
        Choice('markdown', checked=True),  # ✅ 使用 checked=True 預選
        'yaml'                              # 不預選
    ]
).ask()

3. 與默認配置的一致性

默認配置文件 codesage/cli/templates/default_config.yaml 中定義:

snapshot:
  formats:
    - json
    - markdown

修復方案確保交互式嚮導的預選值與默認配置保持一致。

解決方案

修改文件

文件: codesage/cli/interactive.py

變更詳情

1. 添加導入

在文件頂部添加 Choice 的導入:

# 修改前
import questionary
import yaml
import click

# 修改後
import questionary
from questionary import Choice  # 新增導入
import yaml
import click

2. 修復 snapshot_formats checkbox

修改 codesage/cli/interactive.py:22-26

# 修改前
snapshot_formats = questionary.checkbox(
    "Select the snapshot formats to generate:",
    choices=['json', 'markdown', 'yaml'],
    default=['json', 'markdown']
).ask()

# 修改後
snapshot_formats = questionary.checkbox(
    "Select the snapshot formats to generate:",
    choices=[
        Choice('json', checked=True),
        Choice('markdown', checked=True),
        'yaml'
    ]
).ask()

變更說明

項目 說明
API 修正 使用 Choice 對象代替 default 參數
預選邏輯 json 和 markdown 設為預選,yaml 不預選
一致性 與默認配置文件保持一致
向後兼容 不影響現有功能
測試兼容 現有測試的 mock 返回值保持有效

預期效果

修復前

$ poetry run codesage config init --interactive
Welcome to the CodeSage configuration wizard!
? Select the languages you want to analyze: done (3 selections)
? Enter file patterns to exclude (comma-separated): .*,node_modules,vendor
Traceback (most recent call last):
  ...
ValueError: Invalid `default` value passed. The value (`['json', 'markdown']`) does not exist in the set of choices.

結果: ❌ 失敗,無法完成配置

修復後

$ poetry run codesage config init --interactive
Welcome to the CodeSage configuration wizard!
? Select the languages you want to analyze: done (3 selections)
? Enter file patterns to exclude (comma-separated): .*,node_modules,vendor
? Select the snapshot formats to generate: [x] json
                                               [x] markdown
                                               [ ] yaml
? Set the high complexity threshold: 10
? Enable snapshot compression? Yes
? Maximum number of snapshots to keep: 10
? Number of days to keep snapshots: 30

Generated configuration:
analysis:
  languages:
  - python
  - go
  - javascript
  exclude:
  - .*
  - node_modules
  - vendor
  complexity_thresholds:
    high: 10
snapshot:
  formats:
  - json
  - markdown
  compression:
    enabled: true
  versioning:
    max_versions: 10
    retention_days: 30
? Save this configuration? Yes
Configuration saved to .codesage.yaml
Configuration file created at .codesage.yaml

結果: ✅ 成功,配置文件已生成

關於 Markdown 格式的說明

實現狀態

在修復方案中,我們將 markdown 設為預選格式,這與默認配置文件一致。然而,需要注意的是:

  1. Markdown 格式生成器已實現

    • MarkdownGenerator 類存在於 codesage/snapshot/markdown_generator.py
    • 在測試中被成功使用(tests/integration/test_snapshot_pipeline.py:65
  2. CLI 命令標記為未完成

    • codesage/cli/commands/snapshot.py:149 標記為 "not yet implemented"
    • 這可能是指 CLI 命令的集成,而非生成器本身
  3. 測試驗證通過

    • test_full_pipeline 測試成功驗證了 Markdown 生成器的功能
    • 生成的 Markdown 報告包含預期的內容

建議

如果需要完全支持 CLI 層面的 Markdown 格式,建議在後續 PR 中完善以下內容:

  1. snapshot.py 中移除 "not yet implemented" 標記
  2. 集成 MarkdownGenerator 到 CLI 命令中
  3. 添加相關的單元測試和集成測試

測試計劃

單元測試

現有的單元測試 test_interactive_wizard.py 使用 mock 方式,不會受此修復影響:

@patch('questionary.confirm')
@patch('questionary.text')
@patch('questionary.checkbox')
def test_interactive_wizard(mock_checkbox, mock_text, mock_confirm, tmp_path):
    # Mock 返回值保持不變
    mock_checkbox.return_value.ask.side_effect = [
        ['python', 'go'],
        ['json', 'markdown']  # 這個返回值不變
    ]
    ...

手動測試

# 1. 清理舊配置(如果存在)
rm -f .codesage.yaml

# 2. 執行交互式配置嚮導
poetry run codesage config init --interactive

# 3. 驗證生成的配置文件
cat .codesage.yaml

# 4. 驗證配置有效性
poetry run codesage config validate

預期測試結果

測試項目 修復前 修復後
執行嚮導 ❌ ValueError ✅ 成功
預選 json 和 markdown ❌ N/A ✅ 正確預選
生成配置文件 ❌ 失敗 ✅ 成功
配置驗證 ❌ N/A ✅ 通過
單元測試 ✅ 通過(mock) ✅ 通過(mock)

工作量評估

項目 工作量
代碼修改 ~10 行
導入添加 ~1 行
手動測試 ~5 分鐘
文檔編寫 ~15 分鐘
總計 ~20 分鐘

檢查清單

  • 修復 ValueError: Invalid 'default' value passed 錯誤
  • 使用正確的 Choice API 預選多個選項
  • 確保預選值與默認配置文件一致
  • 保持向後兼容性
  • 現有單元測試通過
  • 手動測試驗證

已知限制

  1. Markdown 格式的 CLI 支持狀態

    • Markdown 生成器已實現且可用
    • 但 CLI 命令標記為 "not yet implemented"
    • 本 PR 不解決此問題,僅修復預選邏輯
  2. 測試覆蓋率

    • 現有測試使用 mock,不實際測試 questionary API
    • 建議未來添加端到端測試以驗證交互式流程

參考資料


PR 標籤: bug, fix, questionary, interactive-wizard, api-usage
審查者: 待指派
測試者: 待指派


創建時間: 2025-12-25
預計修復時間: ~20 分鐘
狀態: 待審閱

--

Linked issues / bugs

Fixes #1

- Updated string literals from single to double quotes for consistency
- Improved code formatting and spacing throughout the file
- Simplified nested dictionary structures for better readability
- Enhanced checkbox choices with explicit default selections using Choice objects
- Removed redundant braces in compression configuration
- Added proper line breaks after top-level imports and function definition
- Maintained existing functionality while improving code maintainability
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.

Issue: config init --interactive fails with ValueError in questionary.checkbox

3 participants