Claude Code for getopt: Python C-Style Command Line Parser — Claude Skills 360 Blog
Blog / AI / Claude Code for getopt: Python C-Style Command Line Parser
AI

Claude Code for getopt: Python C-Style Command Line Parser

Published: November 21, 2028
Read time: 5 min read
By: Claude Skills 360

Python’s getopt module parses command-line arguments in the Unix C-style getopt(3) tradition, useful for porting C/shell scripts or building minimal CLI parsers. import getopt. Parse: opts, args = getopt.getopt(argv, shortopts, longopts=[])argv is typically sys.argv[1:]; shortopts is a string like "hvo:" where a colon means the option requires a value (e.g., -o value); longopts is a list like ["help", "verbose", "output="] where = means the option requires a value (e.g., --output=file); returns opts as a list of (option, value) tuples (value is "" for flags) and args as the list of non-option arguments. GNU mode: getopt.gnu_getopt(argv, shortopts, longopts) — same signature but allows options to appear after positional arguments (standard getopt stops at the first non-option). Errors: getopt.GetoptError — raised for unknown options or missing required values; .msg → human-readable description; .opt → the offending option string. Claude Code generates CLI tools, option processors, subcommand dispatchers, and legacy script adapters.

CLAUDE.md for getopt

## getopt Stack
- Stdlib: import getopt, sys
- Parse:  opts, args = getopt.getopt(sys.argv[1:], "hvo:", ["help","verbose","output="])
-         for opt, val in opts:
-             if opt in ("-h", "--help"): ...
-             if opt in ("-o", "--output"): output = val
- GNU:    gnu_getopt  # allows options after positional args
- Error:  except getopt.GetoptError as e: print(e.msg)
- Note:   Prefer argparse for new code; getopt for porting C/shell scripts

getopt Command Line Parser Pipeline

# app/getoptutil.py — parser, schema, dispatch, help, subcommands
from __future__ import annotations

import getopt
import os
import sys
from dataclasses import dataclass, field
from typing import Any


# ─────────────────────────────────────────────────────────────────────────────
# 1. Option schema and typed parser
# ─────────────────────────────────────────────────────────────────────────────

@dataclass
class OptDef:
    name:     str             # long name without --
    short:    str             # single char without -, or "" if none
    takes_value: bool = False # True if option requires an argument
    default:  Any = None
    help:     str = ""


def build_getopt_strings(
    opts: list[OptDef],
) -> tuple[str, list[str]]:
    """
    Build the shortopts string and longopts list from OptDef objects.

    Example:
        opts = [OptDef("help","h"), OptDef("output","o",True,"out.txt")]
        shortopts, longopts = build_getopt_strings(opts)
    """
    short_parts = []
    long_parts = []
    for opt in opts:
        if opt.short:
            short_parts.append(opt.short + (":" if opt.takes_value else ""))
        long_parts.append(opt.name + ("=" if opt.takes_value else ""))
    return "".join(short_parts), long_parts


def parse_opts(
    argv: list[str],
    opts: list[OptDef],
    gnu: bool = False,
) -> tuple[dict[str, Any], list[str]]:
    """
    Parse argv against a list of OptDef, returning (values_dict, positional_args).
    Values default to OptDef.default if option not provided.

    Example:
        opts = [
            OptDef("help",    "h", False, False, "Show help"),
            OptDef("verbose", "v", False, False, "Verbose output"),
            OptDef("output",  "o", True,  "-",   "Output file"),
        ]
        values, args = parse_opts(sys.argv[1:], opts)
        if values["help"]: print_help(opts)
    """
    short_str, long_list = build_getopt_strings(opts)
    by_short = {"-" + o.short: o for o in opts if o.short}
    by_long = {"--" + o.name: o for o in opts}

    values = {o.name: o.default for o in opts}
    try:
        pairs, positional = (
            getopt.gnu_getopt(argv, short_str, long_list)
            if gnu
            else getopt.getopt(argv, short_str, long_list)
        )
    except getopt.GetoptError as e:
        raise SystemExit(f"Error: {e.msg}") from e

    for opt_str, val in pairs:
        opt_def = by_short.get(opt_str) or by_long.get(opt_str)
        if opt_def is None:
            continue
        values[opt_def.name] = val if opt_def.takes_value else True

    return values, positional


# ─────────────────────────────────────────────────────────────────────────────
# 2. Help formatter
# ─────────────────────────────────────────────────────────────────────────────

def format_help(
    prog: str,
    opts: list[OptDef],
    usage: str = "[options] [args...]",
    description: str = "",
) -> str:
    """
    Format a help string from a list of OptDef objects.

    Example:
        print(format_help("mytool", opts, description="Process files"))
    """
    lines = [f"Usage: {prog} {usage}"]
    if description:
        lines += ["", description]
    lines += ["", "Options:"]
    for opt in opts:
        short = f"-{opt.short}, " if opt.short else "    "
        value_hint = " <val>" if opt.takes_value else "      "
        default = f"  (default: {opt.default!r})" if opt.default not in (None, False, "") else ""
        lines.append(f"  {short}--{opt.name}{value_hint}  {opt.help}{default}")
    return "\n".join(lines)


# ─────────────────────────────────────────────────────────────────────────────
# 3. Subcommand dispatcher
# ─────────────────────────────────────────────────────────────────────────────

@dataclass
class Subcommand:
    name:    str
    fn:      "callable"
    opts:    list[OptDef] = field(default_factory=list)
    help:    str = ""


class CommandDispatcher:
    """
    Minimal subcommand dispatcher built on getopt.

    Example:
        dispatcher = CommandDispatcher("mytool")

        @dispatcher.command("compress", help="Compress files")
        def compress_cmd(values, args):
            level = values.get("level", "6")
            print(f"Compress {args} at level {level}")

        dispatcher.dispatch(sys.argv[1:])
    """

    def __init__(self, prog: str):
        self.prog = prog
        self._commands: dict[str, Subcommand] = {}
        self._global_opts: list[OptDef] = [
            OptDef("help", "h", False, False, "Show this help"),
        ]

    def command(
        self,
        name: str,
        opts: list[OptDef] | None = None,
        help: str = "",
    ):
        """Decorator to register a subcommand handler."""
        def decorator(fn):
            self._commands[name] = Subcommand(
                name=name, fn=fn,
                opts=(opts or []) + [OptDef("help", "", False, False, "")],
                help=help,
            )
            return fn
        return decorator

    def _print_usage(self):
        cmds = "  ".join(self._commands)
        print(f"Usage: {self.prog} [{cmds}] [options]")
        print()
        for name, sub in self._commands.items():
            print(f"  {name:15s}  {sub.help}")

    def dispatch(self, argv: list[str]) -> int:
        """Parse argv and dispatch to the matching subcommand. Returns exit code."""
        if not argv or argv[0] in ("-h", "--help", "help"):
            self._print_usage()
            return 0
        cmd_name = argv[0]
        sub = self._commands.get(cmd_name)
        if sub is None:
            print(f"Unknown command: {cmd_name!r}", file=sys.stderr)
            self._print_usage()
            return 1
        values, args = parse_opts(argv[1:], sub.opts, gnu=True)
        if values.get("help"):
            print(format_help(f"{self.prog} {cmd_name}", sub.opts, help=sub.help))
            return 0
        return sub.fn(values, args) or 0


# ─────────────────────────────────────────────────────────────────────────────
# 4. Raw getopt examples
# ─────────────────────────────────────────────────────────────────────────────

def getopt_example_short(argv: list[str]) -> dict:
    """
    Parse -h -v -o <file> from argv.

    Example:
        result = getopt_example_short(["-v", "-o", "out.txt", "file1.txt"])
    """
    try:
        opts, args = getopt.getopt(argv, "hvo:")
    except getopt.GetoptError as e:
        return {"error": e.msg}
    result: dict = {"verbose": False, "output": None, "help": False, "args": args}
    for opt, val in opts:
        if opt == "-h":
            result["help"] = True
        elif opt == "-v":
            result["verbose"] = True
        elif opt == "-o":
            result["output"] = val
    return result


def getopt_example_long(argv: list[str]) -> dict:
    """
    Parse --verbose --output=<file> --format=<fmt> from argv.

    Example:
        result = getopt_example_long(["--verbose", "--output=out.csv", "data.txt"])
    """
    try:
        opts, args = getopt.getopt(argv, "vo:f:", ["verbose", "output=", "format="])
    except getopt.GetoptError as e:
        return {"error": e.msg}
    result: dict = {"verbose": False, "output": None, "format": "text", "args": args}
    for opt, val in opts:
        if opt in ("-v", "--verbose"):
            result["verbose"] = True
        elif opt in ("-o", "--output"):
            result["output"] = val
        elif opt in ("-f", "--format"):
            result["format"] = val
    return result


# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    print("=== getopt demo ===")

    # ── short options ─────────────────────────────────────────────────────────
    print("\n--- getopt_example_short ---")
    for argv in [
        ["-v", "-o", "out.txt", "file.txt"],
        ["-h"],
        ["-v", "pos1", "pos2"],
        ["--unknown"],
    ]:
        result = getopt_example_short(argv)
        print(f"  {argv}{result}")

    # ── long options ──────────────────────────────────────────────────────────
    print("\n--- getopt_example_long ---")
    for argv in [
        ["--verbose", "--output=data.csv", "input.txt"],
        ["--format=json", "a.txt", "b.txt"],
        ["-v", "-f", "csv"],
    ]:
        result = getopt_example_long(argv)
        print(f"  {argv}{result}")

    # ── parse_opts with OptDef schema ─────────────────────────────────────────
    print("\n--- parse_opts ---")
    opts_def = [
        OptDef("help",    "h", False, False, "Show help"),
        OptDef("verbose", "v", False, False, "Verbose output"),
        OptDef("output",  "o", True,  "-",   "Output path"),
        OptDef("workers", "w", True,  "4",   "Number of workers"),
    ]
    for argv in [
        ["-v", "-o", "result.txt", "src/"],
        ["--workers=8", "--verbose", "file1", "file2"],
        ["-h"],
    ]:
        values, args = parse_opts(argv, opts_def)
        print(f"  {argv}")
        print(f"    values={values}  args={args}")

    # ── format_help ───────────────────────────────────────────────────────────
    print("\n--- format_help ---")
    print(format_help("mytool", opts_def,
                      description="Process input files with optional compression."))

    # ── CommandDispatcher ────────────────────────────────────────────────────
    print("\n--- CommandDispatcher ---")
    dispatcher = CommandDispatcher("mytool")

    @dispatcher.command("run", help="Run the pipeline")
    def run_cmd(values, args):
        print(f"    run  verbose={values.get('verbose')}  args={args}")

    @dispatcher.command("check", help="Validate inputs")
    def check_cmd(values, args):
        print(f"    check  args={args}")

    for argv in [["run", "-v", "file.txt"], ["check", "a.py", "b.py"], ["--help"]]:
        print(f"  dispatch({argv})")
        dispatcher.dispatch(argv)

    print("\n=== done ===")

For the argparse alternative — argparse.ArgumentParser provides automatic --help generation, type conversion, nargs, choices, metavar, subparsers, mutually exclusive groups, and rich error messages — use argparse for all new Python CLI tools; use getopt when porting existing C or shell scripts that follow the exact POSIX getopt(3) option syntax, when adding minimal command-line parsing with zero boilerplate, or when working in an environment where you need identical behavior to a C program’s option parsing. For the click (PyPI) alternative — @click.command(), @click.option(), and @click.argument() decorators build rich CLI applications with automatic help, shell completion, color output, and testing support — use click for polished CLI tools intended for end users; use getopt for internal scripts, quick utilities, or legacy compat where the decoration overhead is unwanted. The Claude Skills 360 bundle includes getopt skill sets covering OptDef with build_getopt_strings()/parse_opts() typed schema parser, format_help() help formatter, CommandDispatcher with @command decorator and subcommand dispatch, and getopt_example_short()/getopt_example_long() pattern examples. Start with the free tier to try command-line parsing patterns and getopt pipeline code generation.

Keep Reading

AI

Claude Code for email.contentmanager: Python Email Content Accessors

Read and write EmailMessage body content with Python's email.contentmanager module and Claude Code — email contentmanager ContentManager for the class that maps content types to get and set handler functions allowing EmailMessage to support get_content and set_content with type-specific behaviour, email contentmanager raw_data_manager for the ContentManager instance that handles raw bytes and str payloads without any conversion, email contentmanager content_manager for the standard ContentManager instance used by email.policy.default that intelligently handles text plain text html multipart and binary content types, email contentmanager get_content_text for the handler that returns the decoded text payload of a text-star message part as a str, email contentmanager get_content_binary for the handler that returns the raw decoded bytes payload of a non-text message part, email contentmanager get_data_manager for the get-handler lookup used by EmailMessage get_content to find the right reader function for the content type, email contentmanager set_content text for the handler that creates and sets a text part correctly choosing charset and transfer encoding, email contentmanager set_content bytes for the handler that creates and sets a binary part with base64 encoding and optional filename Content-Disposition, email contentmanager EmailMessage get_content for the method that reads the message body using the registered content manager handlers, email contentmanager EmailMessage set_content for the method that sets the message body and MIME headers in one call, email contentmanager EmailMessage make_alternative make_mixed make_related for the methods that convert a simple message into a multipart container, email contentmanager EmailMessage add_attachment for the method that attaches a file or bytes to a multipart message, and email contentmanager integration with email.message and email.policy and email.mime and io for building high-level email readers attachment extractors text body accessors HTML readers and policy-aware MIME construction pipelines.

5 min read Feb 12, 2029
AI

Claude Code for email.charset: Python Email Charset Encoding

Control header and body encoding for international email with Python's email.charset module and Claude Code — email charset Charset for the class that wraps a character set name with the encoding rules for header encoding and body encoding describing how to encode text for that charset in email messages, email charset Charset header_encoding for the attribute specifying whether headers using this charset should use QP quoted-printable encoding BASE64 encoding or no encoding, email charset Charset body_encoding for the attribute specifying the Content-Transfer-Encoding to use for message bodies in this charset such as QP or BASE64, email charset Charset output_codec for the attribute giving the Python codec name used to encode the string to bytes for the wire format, email charset Charset input_codec for the attribute giving the Python codec name used to decode incoming bytes to str, email charset Charset get_output_charset for returning the output charset name, email charset Charset header_encode for encoding a header string using the charset's header_encoding method, email charset Charset body_encode for encoding body content using the charset's body_encoding, email charset Charset convert for converting a string from the input_codec to the output_codec, email charset add_charset for registering a new charset with custom encoding rules in the global charset registry, email charset add_alias for adding an alias name that maps to an existing registered charset, email charset add_codec for registering a codec name mapping for use by the charset machinery, and email charset integration with email.message and email.mime and email.policy and email.encoders for building international email senders non-ASCII header encoders Content-Transfer-Encoding selectors charset-aware message constructors and MIME encoding pipelines.

5 min read Feb 11, 2029
AI

Claude Code for email.utils: Python Email Address and Header Utilities

Parse and format RFC 2822 email addresses and dates with Python's email.utils module and Claude Code — email utils parseaddr for splitting a display-name plus angle-bracket address string into a realname and email address tuple, email utils formataddr for combining a realname and address string into a properly quoted RFC 2822 address with angle brackets, email utils getaddresses for parsing a list of raw address header strings each potentially containing multiple comma-separated addresses into a list of realname address tuples, email utils parsedate for parsing an RFC 2822 date string into a nine-tuple compatible with time.mktime, email utils parsedate_tz for parsing an RFC 2822 date string into a ten-tuple that includes the UTC offset timezone in seconds, email utils parsedate_to_datetime for parsing an RFC 2822 date string into an aware datetime object with timezone, email utils formatdate for formatting a POSIX timestamp or the current time as an RFC 2822 date string with optional usegmt and localtime flags, email utils format_datetime for formatting a datetime object as an RFC 2822 date string, email utils make_msgid for generating a globally unique Message-ID string with optional idstring and domain components, email utils decode_rfc2231 for decoding an RFC 2231 encoded parameter value into a tuple of charset language and value, email utils encode_rfc2231 for encoding a string as an RFC 2231 encoded parameter value, email utils collapse_rfc2231_value for collapsing a decoded RFC 2231 tuple to a Unicode string, and email utils integration with email.message and email.headerregistry and datetime and time for building address parsers date formatters message-id generators header extractors and RFC-compliant email construction utilities.

5 min read Feb 10, 2029

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free