2 min read

Lesson 5: Advanced Usage — Type Safety, Flexible Input & CLI Black Magic

Lesson 5: Advanced Usage — Type Safety, Flexible Input & CLI Black Magic

Most CLI tools fail not because they lack power — but because they accept garbage input.
Today you learn to prevent that. You’ll tame user chaos with:

  • nargs for multiple values
  • choices to limit options
  • type for automatic conversion
  • required and default to guide logic
  • Custom actions — your CLI, your rules

nargs — Accept Multiple Values

Want an option to accept a list? Use nargs.

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--tags', nargs='+', help="Add one or more tags")
args = parser.parse_args()

print(f"Tags: {args.tags}")

Usage:

python app.py --tags urgent work personal

✅ Output:

Tags: ['urgent', 'work', 'personal']

Common Forms:

ValueMeaning
nargs=1Expects a single value (as list)
nargs='?'Optional arg or default
nargs='*'Zero or more values
nargs='+'One or more values (must give at least 1)

choices — Limit Accepted Input

You want the user to choose only from valid options. Use choices.

parser.add_argument('--format', choices=['json', 'csv', 'xml'], required=True)
python app.py --format yaml

💥 Output:

error: argument --format: invalid choice: 'yaml' (choose from 'json', 'csv', 'xml')

✅ Keeps your CLI clean and predictable
✅ Great for modes, output types, themes, roles, etc.


type — Convert Input Automatically

parser.add_argument('--repeat', type=int, help="Number of repetitions")
python app.py --repeat 5

args.repeat is already an int
❌ If someone tries --repeat hello, it errors out


required & default

You can combine them to guide user behavior:

parser.add_argument('--user', required=True)
parser.add_argument('--role', default='member')
  • --user must be passed
  • --role is optional and defaults to member

Custom Actions — Write Your Own Argument Logic

Want to store input, trigger functions, or validate weird formats?
Use a custom action class.

class UppercaseAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        setattr(namespace, self.dest, values.upper())

parser.add_argument('--shout', action=UppercaseAction)
python app.py --shout hello

✅ Output:

HELLO

Use this when:

  • You need to transform input (lowercase, timestamp, slugify)
  • You want to log or validate something exotic
  • You want total control

🧪 Recap Table

FeaturePurposeExample
nargsAccept multiple values--tags a b c
choicesRestrict to known values--format json
typeConvert input to right type--count 3int
requiredForce user to provide--file
defaultProvide fallback--sort-by name (default)
actionCustomize behaviorUppercaseAction

🔮 Coming Up: Final Boss

Lesson 6: Project Build — A real CLI tool using everything we’ve learned so far
📦 Commands, flags, groups, validation, custom logic, and export.

Your CLI won't just work — it’ll sparkle like sacred code.