Main Function Pattern

Core Principle

Separate business logic from CLI handling to make code reusable as a library module.

main() Function

Accepts explicit parameters with defaults. Contains all business logic. Returns results, raises exceptions. Never calls sys.exit(). Can be imported and called from other modules.

if __name__ == "__main__" Block

Handles argument parsing only. Converts CLI strings to appropriate types. Calls main() with parsed arguments. Catches expected exceptions and converts to exit codes. All sys.exit() calls contained here. Provides user-friendly error messages to stderr.

Benefits

Same code works as both script and library. Defaults defined once in main() signature. Easy to test (no sys.exit() to mock). Clear separation of concerns. Unexpected exceptions show full traceback automatically.

Operation status contracts

When callable business operations deliberately return process-style statuses for a CLI wrapper, document the contract at the operation boundary (for example, 0 = success and 1 = failure). A bare return is usually undef, not an interchangeable success result. Prefer returned values or exceptions for library-facing APIs; use numeric statuses only where the wrapper intentionally maps them to the process exit status.

version 2  ·  updated 2026-08-26