Command-Line Argument Handling

All Qlattice Python scripts use standard argparse for command-line argument parsing. The previous q.get_arg() / q.get_option() helpers are deprecated in favor of the standard library.

Core Rules

  1. Use underscores in option names. Option names must use underscores (_), not hyphens (-), so that the argparse-generated attribute name matches the option name directly:

    parser.add_argument("--no_inversion", ...)   # ✓  attribute: no_inversion
    parser.add_argument("--no-inversion", ...)   # ✗  attribute: no_inversion (ambiguous)
    parser.add_argument("--random_permute_job_tag_traj_list", ...)
    
  2. Do not use dest. Since option names use underscores, argparse’s default attribute name (--foo_barfoo_bar) always matches the option. The dest parameter should never be needed.

  3. Use parse_known_args() for MPI safety. Scripts launched via mpiexec may receive extra arguments from the MPI runtime. Always use parse_known_args() instead of parse_args() to ignore unknown arguments gracefully:

    args, _ = parser.parse_known_args()
    
  4. Use the raw no_* flags directly in logic. Do not convert negative flags (e.g. --no_inversion) into positive booleans (e.g. is_performing_inversion). Invert the logic inline where needed:

    if not sys_args.no_inversion:     # ✓
    if sys_args.is_performing_inversion:  # ✗
    
  5. Post-process list/composite arguments in parse_args(). Simple transformations (e.g. splitting a comma-separated string into a list) belong inside the parse_args() function:

    args, _ = parser.parse_known_args()
    args.job_tag_list = args.job_tag_list.split(",")
    return args
    
  6. Call parse_args() inside if __name__ == "__main__":. The parse_args() function is defined at module level but called only when the script is executed directly, not when imported:

    if __name__ == "__main__":
        sys_args = parse_args()
        job_tag_list = sys_args.job_tag_list
    

Reference Example

import argparse
import sys

# ... imports and function definitions ...

def parse_args():
    parser = argparse.ArgumentParser(
        description="Script description."
    )
    parser.add_argument(
        "--job_tag_list",
        type=str,
        default="test-4nt8-checker",
        help="Comma-separated list of job tags (default: 'test-4nt8-checker')",
    )
    parser.add_argument(
        "--no_inversion",
        action="store_true",
        default=False,
        help="Skip the inversion step",
    )
    parser.add_argument(
        "--no_contract",
        action="store_true",
        default=False,
        help="Skip the contraction step",
    )
    parser.add_argument(
        "--random_permute_job_tag_traj_list",
        action="store_true",
        default=False,
        help="Randomly permute the job_tag/traj list",
    )
    args, _ = parser.parse_known_args()
    args.job_tag_list = args.job_tag_list.split(",")
    return args

if __name__ == "__main__":
    sys_args = parse_args()
    # use sys_args.no_inversion, sys_args.no_contract, etc.
    if not sys_args.no_inversion:
        run_inversion()
    if not sys_args.no_contract:
        run_contraction()

Migration from q.get_arg()

Old pattern

New pattern

q.get_arg("--job_tag_list", default="tag1").split(",")

sys_args.job_tag_list (split in parse_args())

q.get_arg("--no-inversion", default=None) is None

not sys_args.no_inversion

q.get_option("--random-permute-job_tag-traj-list")

sys_args.random_permute_job_tag_traj_list