iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0
Vibe Coding

一個 Vibe Coding 專案從原型到有人在用系列 第 17 篇

型別檢查全過,換 Windows 一跑就紅

  • 分享至 

  • xImage
  •  

你跑過型別檢查嗎?最後一行印出 Success: no issues found,你就覺得程式裡叫的每個函式都存在、型別都對得上了。

8 月 31 日下午,AI 照一張工作單(交給 AI 的任務說明)修好三個問題,工作單要它收尾前跑一次 mypy .。它回報三個修正都完成,節錄測試和檢查的部分:

全測試 1824 passed 0 failed;ruff/mypy……通過

改動推上 GitHub 之後,CI(每次推上去自動跑的一輪檢查)在 Windows 電腦上跑的型別檢查紅了,也就是檢查失敗:

tests\test_usage_statusline.py:204: error: Module has no attribute "fork"

同一份程式,在我這台 Mac 上沒問題,換到 Windows 就有一個函式不存在。

CI 在 Mac 和 Windows 上各跑一次 mypy

usage 是我做的開源小工具,在終端機和 Mac 選單列上,顯示 Claude Code、Codex 等 AI 工具用了多少 token、花了多少錢。7 月 15 日起,它也有 Windows 版。

所以每次推上 GitHub,CI 會借 GitHub 的一台 Mac、一台 Windows 電腦,各跑一次 mypy。

mypy 是 Python 的型別檢查工具。它不執行程式,只把程式從頭讀一遍,檢查你叫的函式存不存在、傳進去的東西型別對不對。usage 開的是最嚴格的模式,設定檔裡寫的是 strict = true。

平常 AI 改完程式,工作單會要它自己跑一次 mypy .。AI 是在我這台 Mac 上工作的,所以這一次檢查,也是在 Mac 上跑。

mypy 看的是「跑它的這台電腦」

os.fork() 是 Python 用來把正在跑的程式複製一份的函式。Mac 和 Linux 有,Windows 沒有。

mypy 怎麼知道?它內建一份 Python 標準函式庫的型別說明,fork 在裡面是這樣寫的:

if sys.platform != "win32":
    # Unix only
    def fork() -> int: ...

sys.platform 是目前的作業系統。mypy 讀到這段,會照「跑它的這台電腦」來判斷:在 Mac 上跑,fork 存在;在 Windows 上跑,fork 不存在。

所以 AI 在 Mac 上跑 mypy,看到的是 Mac 的標準。os.fork() 那一行在 Mac 上完全合法,它回報通過,沒有說錯。只是這份程式也要在 Windows 上跑,那邊的標準,它沒檢查過。

https://ithelp.ithome.com.tw/upload/images/20261001/20183178GUCyuVbuSs.png

在 Mac 上,照 Windows 的標準檢查一次

mypy 有一個選項 --platform,可以指定要照哪個作業系統檢查。

我把 8 月 31 日 CI 紅燈的那一版程式拿出來,在 Mac 上跑兩次:

$ mypy .
Success: no issues found in 220 source files

$ mypy . --platform win32
tests/test_usage_statusline.py:204: error: Module has no attribute "fork"
Found 1 error in 1 file (checked 220 source files)

第二次,就是 Windows 那台 CI 的紅燈:同一個檔、同一行、同一句錯誤。不用開 Windows,在自己的 Mac 上就抓得到。

usage 從 5 月開始寫到現在,從來沒有用過 --platform。

這一次錯在測試檔。那個測試本來就設定成在 Windows 上跳過,不會真的執行,只是 mypy 還是會檢查它。當天的修正,是在 os.fork() 那一行加上 # type: ignore,叫 mypy 忽略這一行的錯。只加這個,換 Mac 那台會不滿意:Mac 有 fork,這個「忽略」根本用不到,最嚴格模式會把用不到的忽略也當成錯。所以同一個修正裡,設定檔還替這個測試檔關掉了這一項檢查。Windows 那台的紅燈,從下午 2 點半多一直亮到晚上 8 點 10 分,才轉回綠燈。

7 月 25 日那次,錯在正式程式裡

同樣的事,7 月 25 日發生過一次,規模大得多。

那天加的是一個新功能:開一個桌面視窗,讓 Claude Code、Codex 等幾個 AI 在裡面輪流討論。推上去,Windows 那台的 mypy 印出 26 個錯誤:

discussion_cli.py:777: error: Module has no attribute "getpgid"; maybe "getpid"
discussion_cli.py:781: error: Module has no attribute "killpg"  [attr-defined]
discussion_window.py:549: error: Name "NSApp" is not defined  [name-defined]
...
Found 26 errors in 3 files (checked 156 source files)

getpgid 查出一群程式屬於哪一組,killpg 把這一組一起結束,這兩個也只有 Mac 和 Linux 有。這次錯的不是測試檔,是 usage 真的會執行的程式:討論逾時或被取消時,要結束那幾個 AI 的程式,用的就是 getpgid 和 killpg。如果在 Windows 上跑到這裡,就會叫到一個不存在的函式。

這一版我一樣拿出來,在 Mac 上跑兩次。一般跑,Success: no issues found in 156 source files;加上 --platform win32,Found 26 errors in 3 files,跟 CI 一樣。

https://ithelp.ithome.com.tw/upload/images/20261001/20183178HzpLZtdDno.png

這次的修法不只是叫 mypy 別管:程式多寫了一個 Windows 版的結束方式,改用 Python 內建、Windows 也有的 process.terminate() 和 process.kill(),執行時照作業系統選一個用。

那天早上,Windows 那台 CI 前後紅了三輪才轉綠。CI 是一步一步跑的,mypy 失敗,排在後面的測試就不跑;mypy 修好之後,測試才跑得到,又冒出新的失敗。

Mac 那台,也抓過 Windows 才有的東西

前面兩次,都是 Mac 上一般跑檢查不出來、Windows 那台 CI 抓到。反過來也發生過。

7 月 29 日,Windows 版的程式用了 ctypes.windll,這是 Windows 才有的系統介面。這次紅的是 Mac 那台 CI:

wintray.py:619: error: Module has no attribute "windll"  [attr-defined]

翻出你專案裡的平台判斷

現在就可以做一件事:在你的專案裡搜尋 sys.platform、os.name,或是 fork、windll 這類只有某個作業系統才有的東西。

有找到,你的程式很可能有「只在某種作業系統上成立」的部分。用 mypy 的話,把你會支援的作業系統各跑一次:

mypy . --platform win32
mypy . --platform darwin
mypy . --platform linux

darwin 是 Mac,linux 是 Linux。平常只跑一次的那個,就是你自己這台。

今天可以帶走的

工作單裡有一格「做完怎麼算對」,Day 4、Day 8 到 Day 16 各在這格加了幾行。今天再加一行:

做完怎麼算對:
- (Day 4、Day 8 到 Day 16 加的幾行)
- 支援多個作業系統的專案:型別檢查每個作業系統各跑一次(mypy --platform),回報要寫明在哪個作業系統上跑的

今天的「通過」,只代表跑它的那台電腦。明天看一個沒有任何檢查在管的問題:usage 的繁體中文介面上寫著「项目」「时间」「来源」,一共 52 句是簡體字。其中 48 句是 5 月 24 日帶進來的,跟 Day 16 那批空白的日文、韓文翻譯是同一次改動。8 月 5 日才修掉,中間發了 138 個版本,沒有一個測試檢查字是繁體還是簡體。

參考資料

  • usage 專案:https://github.com/aqua5230/usage
  • 8 月 31 日修正 os.fork 型別錯誤的改動:https://github.com/aqua5230/usage/commit/5ab4bd0
  • 7 月 25 日修正 Windows 型別錯誤的改動:https://github.com/aqua5230/usage/commit/00a3a2b
  • mypy 的 --platform 選項:https://mypy.readthedocs.io/en/stable/command_line.html#platform-configuration
  • mypy 怎麼看待 sys.platform 判斷:https://mypy.readthedocs.io/en/stable/common_issues.html#python-version-and-system-platform-checks

上一篇
翻譯測試全綠,日文介面有 63 句是英文
系列文
一個 Vibe Coding 專案從原型到有人在用 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言