Skip to main content

argsl️

argsl is for everybody who finds argparse too verbose.

argsl (“args DSL” / “argparse DSL”) lets you define CLI arguments in a tiny DSL and get an argparse.Namespace back — with types, defaults, and optional --help text.

from argsl import argsl

args = argsl("""
filename <path>         # positional file/path
--name|-n <str!>        # required option
--debug|-d <flag>       # boolean switch
""")

…instead of writing argparse boilerplate.


  • Expressive: one line per argument
  • No boilerplate: returns argparse.Namespace (parsed from sys.argv)
  • Typed: int, float, str, path, bool, flag, choice
  • Compatible with argparse: wraps it internally

Installation

Using uv (recommended)

uv add argsl

Or with pip

pip install argsl

Basic Example

from argsl import argsl

args = argsl("""
filename <path>                          # positional file/path
--name|-n <str=env:USER>                 # optional with env fallback
--level|-l <choice:low,med,high="med"> # choice with default
--debug|-d <flag>                        # boolean flag
--onlylong <int=1>                       # long-only argument
--no-cache <flag>                        # store_true flag; app decides semantics
""")

print(vars(args))

In your pyproject.toml:

[project.scripts]
run = "main:main"

Run it:

uv run run file.txt --name Alice --debug --level high --no-cache

DSL Format

Each non-empty line describes one argument:

<flags or positional> <type-expression> [# help text]

Examples:

  • Positional:
    • filename <path>
  • Long option only:
    • --count <int=3>
  • Long + short option:
    • --name|-n <str!>

Flags / option names

  • Use --long for long options and -s for short options.
  • Combine long and short options with | without spaces:
    • --name|-n <str!>
    • --name | -n <str!> (avoid spaces around |)

Inline help text with #

If a line contains #, everything after the first # becomes the help= text passed to argparse.

args = argsl("""
--debug|-d <flag>  # Enable debug logging
""")

Notes (current behavior):

  • The split is done on the first # anywhere in the line.
  • Help text is trimmed (strip()).
  • Lines starting with # are ignored.
  • # is not quote-aware. If you put # inside a quoted default (e.g. <str="a#b">), it will still be treated as the start of help text.

Supported Type Expressions

Type expressions live inside <...>.

Built-in types

DSL Meaning argparse behavior
<str> string value type=str
<int> integer value type=int
<float> float value type=float
<path> filesystem path type=pathlib.Path
<bool> boolean value from a string parses 1/true/yes (case-insensitive)
<flag> boolean flag action="store_true" (default False, becomes True if present)

Required (!)

  • ! marks named options as required:
    • --name <str!> → required=True
  • For positionals, argparse already requires them by default, so ! is effectively redundant.

Defaults (=)

You can provide defaults with =.

--count <int=3>
--title <str="hello world">

Defaults are parsed with ast.literal_eval when possible (numbers, quoted strings, etc.). If parsing fails, the raw string is used.

Environment fallback (=env:VAR)

Use an environment variable as a default:

--user <str=env:USER>
--home <path=env:HOME>

This sets default=os.getenv("VAR") (which may be None if the variable is unset).

Multiple values (*)

Add * to accept one or more values:

--list <str*>

This maps to nargs="+".

Choices (choice:)

Restrict input to a fixed set of strings:

--level <choice:low,med,high>

You can also set a default using =:

--level <choice:low,med,high="med">
--level <choice:low,med,high=med>

(Choices are always treated as strings.)


Supported Flag Variants

args = argsl("""
--user|-u <str!>      # short + long
--only <int=1>        # long-only option
--debug <flag>        # store_true
--no-cache <flag>     # store_true; app interprets as "disable cache"
""")

Test Coverage & Edge Cases

Covered in tests (see tests/test_argsl.py and tests/test_argsl_all.py):

  • required positional + typed
  • required named args (--foo <str!>)
  • optional args with defaults (--bar <int=42>)
  • multiple values (--list <str*>)
  • boolean flags (--debug <flag>)
  • env fallback (--x <str=env:HOME>)
  • quoted defaults (--title <str="The Answer">)
  • long-only and short+long (--onlylong, --msg|-m)
  • choice types + defaults (--level <choice:low,med,high="med">)

Development Workflow

Using uv:

uv add .[dev]
uv add '.[dev]'   # on zsh (macos)
uv run test

Or with classic tools:

pip install -e .[dev]
pip install -e '.[dev]'   # on zsh (macos)
pytest

Publishing to PyPI

rm -rf dist/  # remove old builds (PyPI rejects re-uploads)
uv build
uv publish

MIT licensed • Built by Gwang-Jin Kim

Metadata

Release files for argsl 0.1.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for argsl 0.1.4
File Size Uploaded Provenance Actions
argsl-0.1.4.tar.gz 5.5 kB Without provenance Details for argsl-0.1.4.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for argsl 0.1.4
File Interpreter ABI Platform Actions
argsl-0.1.4-py3-none-any.whl Python 3 none any Details for argsl-0.1.4-py3-none-any.whl

Total release size: 10.8 kB

Release files / argsl-0.1.4.tar.gz

Download URL argsl-0.1.4.tar.gz
Size 5.5 kB
Tags Source
SHA-256 checksum
How to use checksums
36f188af7dc40e711ea8d7b8c9150c71a1cfe7c7e1dc9a0355983f0ffe6e1116
BLAKE2b-256 checksum
How to use checksums
2f549b838d3236b09d7f99fa3e0f70b89d72b7eef7536bd266e82dac76ec4579
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.6.4

Release files / argsl-0.1.4-py3-none-any.whl

Download URL argsl-0.1.4-py3-none-any.whl
Size 5.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4c937d812849c20db2ed23b8d43dd9b4502ce8a415eb31a15cdabdc223270f05
BLAKE2b-256 checksum
How to use checksums
dedf61e9481a2874575ab821877c58055f8932d797f45fd7756f5ad723b5ea71
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.6.4

Security for argsl 0.1.4

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page