A minimal library to make your option-parsing easier.
Project description
$ lethargy --option-parsing-for-simple-apps▏
Simple scripts don't need the complexity of a full CLI framework. Lethargy is a small and minimal library that makes it easy to only take the arguments you need, as you need them, and use the remaining arguments for whatever you want.
You should not use this library if you are building a program that has functionality centered around the command line. The features that are omitted are intentionally left out. Ultimately, they would be better provided by a library such as Click or Argparse.
This library does not try to compete with other CLI libraries, but instead allow scripts and prototypes to be iterated on faster by implementing basic command line paradigms.
Features:
- Makes implementing basic CLI functionality fast
- Lightweight (small codebase, only depends on standard library)
- Simple, boilerplate-free and Pythonic syntax
- Support for long and short options
- Treat an option as a flag, or accept arguments
- Allows a defined or undefined number of arguments
What it doesn't do:
- Short-option group expansion (eg.
-xyz
->-x -y -z
) =
arguments (eg.--quotes=always
)
Example
The program below takes an optional --debug flag, and --exclude which will greedily take every argument provided afterwards.
#!/usr/bin/env python3
from lethargy import Opt, argv
DEBUG = Opt("debug").take_flag(argv)
EXCLUDED = set(Opt("exclude").takes(...).take_args(argv))
# Will only print if DEBUG is set to True
dprint = print if DEBUG else lambda *_, **__: None
# We've removed the two options this program takes, process the remaining args
# Exclude the name of the script by starting from index 1
for name in argv[1:]:
if name not in EXCLUDED:
dprint(name)
$ ./script.py --debug a b c d e f --exclude d e
script.py
a
b
c
f
Manually parsing the options, it's neither easily readable or maintainable, nor is it easy to make guarantees about the safety of mutating the arg list.
Installation
Lethargy is on PyPI. Use your package manager of choice to install lethargy
.
pip install lethargy
Table of Contents
Contents
Usage
Creating an option
The Opt
constructor takes any amount of names. These names will all be converted to --skewered-kebab-case (though it preserves capitalisation), or be prefixed with a single dash (-
) if the name is just a single character.
from lethargy import Opt
# -x or --example
Opt("x", "example")
# --option-parsing-for-simple-apps
Opt("option parsing for simple appes")
If the option takes arguments, use the takes
method to set the number of arguments. This will be discussed further in the "taking arguments" sections below.
Using str
and repr
Opt
instances have a helpful str
and repr
.
Converting it to a string will show its names and the number of values it takes in an easily readable way.
from lethargy import Opt
print(Opt('name'))
# --name
print(Opt('f', 'files').takes(2))
# -f|--files <value> <value>
Taking a flag
A very common pattern is to extract a debug or verbose flag from the list of arguments. It's not uncommon that this may be the only option that the script accepts.
Use the take_flag
method to remove the option from the argument list.
from lethargy import Opt, argv
args = ['--debug', 'other', 'values']
DEBUG = Opt('debug').take_flag(argv)
print(DEBUG)
# True
print(args)
# ['other', 'values']
In this case, if --debug was present in the list, it would have been removed and the method would return True. Otherwise, it would return False and make no changes to the list.
Taking a single argument
An option that takes a single argument will return a single value.
from lethargy import Opt
args = ['--example', 'value', 'floating']
val = Opt('example').takes(1).take_args(args)
no_val = Opt('abc').takes(1).take_args(args)
print(val)
# value
print(no_val)
# None
print(args)
# ['floating']
If an option that takes arguments is given fewer than expected, lethargy.ArgsError
is raised. No mutation will occur.
from lethargy import Opt, ArgsError
# --example is given, but the option is expecting 1 argument.
bad = ['--example']
try:
Opt('example').takes(1).take_args(bad)
except ArgsError:
pass
print(bad)
# ['--example']
Taking multiple arguments
When taking more than 1 argument, a list of arguments is returned.
from lethargy import Opt
args = ['-', '--name', 'separate', 'records']
first, last = Opt('name').takes(2).take_args(args)
print(first, last)
# separate records
print(args)
# ['-']
If the option is not provided, it returns a list of None that has the correct length. This guarantees that multiple assignment is safe.
from lethargy import Opt
first, last = Opt('name').takes(2).take_args([])
print(first, last)
# None None
If the default is specified using the default
parameter (eg. take_args(args, default=''
), it will be returned as-is.
Taking any number of arguments ("greediness")
If the number of arguments the option takes is ...
, the option will greedily consume each argument remaining in the list after the option name.
from lethargy import Opt
args = ['script.py', '-f', 'a', 'b', 'c', '--files', 'd']
values = Opt('f', 'files').takes(...).take_args(args)
print(values)
# ['a', 'b', 'c', '--files', 'd']
print(args)
# ['script.py']
These options should be taken last to avoid accidentally eating another option.
By default, an empty list is returned if there are no arguments provided.
values = Opt('x').takes(...).take_args([])
print(values)
# []
Raising instead of defaulting
By setting raises=True
in the take_args
method call, lethargy.MissingOption
will be raised instead of returning the default.
Recipe book
Some common patterns used for basic CLI scripts. Anything more complex than these could be done better using Click or Argparse.
Mandatory option with helpful error
This example shows how you would combine raising instead of defaulting and the string formatting of an Opt
instance.
from lethargy import Opt, argv, MissingOption
opt = Opt('my option').takes(2)
try:
args = opt.take_args(argv, raises=True)
except MissingOption:
print(f'Missing required option: {opt}')
exit(1)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.