Python argparse: ชี้คำสั่งที่พิมพ์ใกล้เคียง และคุมสี error ได้
CLI ที่ตอบเพียง invalid choice ทำให้ typo หนึ่งตัวกลายเป็นการเปิด help แล้วย้อนหาเอง Python 3.14 เพิ่ม suggest_on_error=True ให้ argparse เสนอ choice หรือ subcommand ที่สะกดใกล้เคียง และมี color สำหรับควบคุมสีของข้อความ help/error ครับ
ข้อดีไม่ใช่แค่สวยขึ้น แต่ลดเวลาจาก “ผิดตรงไหน” ไปถึง “แก้เป็นอะไร” เหมือนพนักงานบอกว่าโต๊ะ 12 น่าจะเป็นโต๊ะ 21 แทนการชี้ป้ายว่าหมายเลขไม่ถูกต้อง
from __future__ import annotations
import argparse
import contextlib
import io
import unittest
def parser() -> argparse.ArgumentParser:
cli = argparse.ArgumentParser(
prog="ship",
suggest_on_error=True,
color=False,
)
cli.add_argument("environment", choices=("staging", "production"))
return cli
class ArgparseSuggestionsTests(unittest.TestCase):
def test_valid_choice(self):
self.assertEqual(parser().parse_args(["staging"]).environment, "staging")
def test_typo_suggests_nearby_choice(self):
stderr = io.StringIO()
with contextlib.redirect_stderr(stderr), self.assertRaises(SystemExit):
parser().parse_args(["stagin"])
self.assertIn("staging", stderr.getvalue())
if __name__ == "__main__":
unittest.main()
Suggestion ไม่ได้เปลี่ยน validation: input ที่ไม่อยู่ใน choices ยังล้มเหลวเหมือนเดิม จึงช่วยผู้ใช้โดยไม่เดาคำสั่งแล้วรันให้เงียบ ๆ ส่วน color=False เหมาะกับ test, log และระบบที่ไม่รองรับ ANSI; หน้า terminal ปกติปล่อย default เพื่อให้ argparse ตัดสินจาก environment ได้
หาก library ต้องรองรับ Python เก่า ให้ตรวจเวอร์ชันหรือกำหนด attribute หลังสร้าง parser ตามเอกสาร แต่อย่าจับ TypeError กว้างจนกลบ option อื่นที่สะกดผิด
Recap
- เปิด suggestion เมื่อ choices เป็น string ที่คนพิมพ์เอง
- อย่า auto-correct แล้ว execute โดยไม่ยืนยัน
- ปิดสีใน snapshot tests และ machine-readable logs
- ทดสอบทั้ง input ถูกและ typo ที่คาดว่าจะเสนอ