feat: 把 PyPtt.TwoFactorAuthRequired 標成 TWO_FACTOR_AUTH_REQUIRED,別被 LoginError 吃掉 - #24
Merged
Merged
Conversation
…ginError 吃掉 PyPtt 2.3.6 新增 TwoFactorAuthRequired,用於偵測到 PTT 兩階段驗證畫面。 它繼承 LoginError,而 _handle_ptt_exception 是依 EXCEPTION_MAPPING 的插入 順序做 isinstance 線性掃描,LoginError 會先命中,把「請先從這台機器手動 登入完成一次驗證」的指引訊息換成泛用的「登入失敗」。 - utils.py 在掃描迴圈之前加顯式分支。放在迴圈前而非塞進 dict,是因為 dict 順序是隱性契約,顯式分支的意圖不會被後人重排時弄壞 - message 直接透傳 str(e),不在本 repo 複製指引文字 — 那段字在 PyPtt 的 i18n 語言檔裡,複製會兩處不同步,也會失去語系切換 - 補 LoginError 仍回 LOGIN_FAILED 的回歸測試,避免反過來搶走父類 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017UbZgc9a53f3sLyAg3DNbF
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
PTT 於 2026-08-04 上線兩階段驗證 (2FA)。PyPtt 2.3.6 新增了
TwoFactorAuthRequired,遇到 2FA 畫面時丟出,訊息會告訴使用者:PTT 的 2FA 可設為「僅新 IP 需驗證」,同一 IP 再次登入會跳過,所以先從這台機器用一般 BBS 客戶端手動登入完成一次驗證即可。問題是這個訊息到不了使用者手上。
TwoFactorAuthRequired繼承PyPtt.LoginError,而_handle_ptt_exception是依EXCEPTION_MAPPING的插入順序做isinstance線性掃描(src/utils.py),LoginError排在前面會先命中,指引訊息就被換成泛用的「登入失敗」/LOGIN_FAILED。實測佐證:同一個開了 2FA 的帳號,用工作區版 PyPtt 2.3.6 直接登入會在 0.18 秒拋出
TwoFactorAuthRequired;透過本 MCP server 則只拿到LOGIN_FAILED。改了什麼
src/utils.py— 在掃描迴圈之前加顯式 isinstance 分支。放迴圈前而非塞進 dict,是因為 dict 順序是隱性契約,顯式分支的意圖不會被後人重排時弄壞message直接透傳str(e),不在本 repo 複製指引文字——那段字在 PyPtt 的 i18n 語言檔裡,複製會造成兩處不同步,也會失去語系切換能力src/api_ptt.py— docstring 的錯誤碼清單新增TWO_FACTOR_AUTH_REQUIRED(grep 確認全庫只有這一處清單)src/_version.py— 0.3.0 → 0.3.1驗證
pytest src/→ 20 passedcode == "TWO_FACTOR_AUTH_REQUIRED"且message為 PyPtt 原文而非「登入失敗」LoginError仍須回LOGIN_FAILED,避免反過來把父類搶走AssertionError: assert 'LOGIN_FAILED' == 'TWO_FACTOR_AUTH_REQUIRED',確認測試真的保護到這件事附註
requirements.txt未 pinpyptt,Dockerfile 每次建置裝最新版且 workflow 設no-cache: true,所以 merge 後的 image 會自動帶到 PyPtt 2.3.6。實作中對屬性存取加了getattr短路保險,舊版共存時不會炸。🤖 Generated with Claude Code
https://claude.ai/code/session_017UbZgc9a53f3sLyAg3DNbF