งูต้นฉบับจับคู่บัตรคำสั่งที่วางผิดช่องกับช่องใกล้เคียงบนโต๊ะมิ้นต์

Python argparse: ชี้คำสั่งที่พิมพ์ใกล้เคียง และคุมสี error ได้

พี่โชว์Engineering

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 ที่คาดว่าจะเสนอ