Appendix G — Script Entry Points and Exit Behaviour Answers

Completed Check

Keep parser setup, runtime behaviour, and script startup separate. Returning integers from main() gives the caller a clear success or failure signal, and the __name__ guard lets the file behave differently when it’s imported versus run directly.

import argparse
import errno
from pathlib import Path


def build_argument_parser():
    parser = argparse.ArgumentParser(prog="bernauer")
    parser.add_argument("domain", help="domain to test, e.g. example.test")
    parser.add_argument("-w", "--wordlist", default="data/wordlist.txt")
    return parser


def main(args):
    if not Path(args.wordlist).is_file():
        print("No such file or directory")
        return errno.ENOENT

    print(f"Ready to scan {args.domain}")
    print(f"Wordlist: {args.wordlist}")
    return 0


parser = build_argument_parser()
print(main(parser.parse_args(["example.test"])))
print(main(parser.parse_args(["example.test", "--wordlist", "missing.txt"])))
Ready to scan example.test
Wordlist: data/wordlist.txt
0
No such file or directory
2

In a real script, the final startup line would be raise SystemExit(main(build_argument_parser().parse_args())). This notebook simulates arguments explicitly so rendering the answer doesn’t accidentally parse Jupyter’s own command-line options.

References: __main__, PEP 299, and errno.