Skip to main content

A minimal library to make your option-parsing easier.

Project description

$ lethargy --option-parsing-for-simple-apps▏

Latest version on PyPI Supported Python versions MIT License Library size

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.

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.

You should not use Lethargy if you are building a program that has functionality centered around the command line. Libraries such as Click or Argparse are better for implementing large applicatons.

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 = Opt("exclude").takes(...).take_args(argv)

# Only `print` if DEBUG is set to True
dprint = print if DEBUG else lambda *_, **__: None

# Removed the two options this program takes, process the remaining args.
# Excludes 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
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)

Implementing debug/verbose flags

Normally, programs can take --debug or -v/--verbose flags, which tell the program to print more information. This is especially useful when debugging a script.

dprint and vprint will only be the print function if the corresponding flag was given. If not, it will be a function that does nothing and returns nothing. This lets you treat the two conditional print functions identically to print (accepting the same args/kwargs)

from lethargy import Opt, argv

DEBUG = Opt('debug').take_flag(argv)
VERBOSE = Opt('v', 'verbose').take_flag(argv)

def print_if(cond):
  return print if cond else lambda *_, **__: None

dprint = print_if(DEBUG)
vprint = print_if(VERBOSE)

This is actually a common-enough pattern that Lethargy provides the print_if, take_debug and take_verbose functions.

from lethargy import print_if, take_debug, take_verbose, argv

dprint = print_if(take_debug(argv))
vprint = print_if(take_verbose(argv))

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lethargy-0.2.1.tar.gz (10.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lethargy-0.2.1-py3-none-any.whl (9.2 kB view details)

Uploaded Python 3

File details

Details for the file lethargy-0.2.1.tar.gz.

File metadata

  • Download URL: lethargy-0.2.1.tar.gz
  • Upload date:
  • Size: 10.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/0.12.17 CPython/3.7.4 Darwin/19.0.0

File hashes

Hashes for lethargy-0.2.1.tar.gz
Algorithm Hash digest
SHA256 8aec116575feb86176e41e8c4cad688cc8ace4392e882c8a868577b25280b55b
MD5 38f895f0bdccdb9f80e9a7f4fdb98d13
BLAKE2b-256 7e9eb6c86ce67c3d4ebbbc383299d9a79df4f4065afc12063c135c953e7adeb2

See more details on using hashes here.

File details

Details for the file lethargy-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: lethargy-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 9.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/0.12.17 CPython/3.7.4 Darwin/19.0.0

File hashes

Hashes for lethargy-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0e6b8239d4ebca1903c949a8c42f85583cb4950067005d037aef0cc46a1cc70a
MD5 0d29c2b2dfbd9e27a707355377e3f005
BLAKE2b-256 31c140681ba45af67cf07683e6344c78ea8c5367a8e3aea9e73ecc1b951c0a71

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page