Skip to main content

Simple Typed Argparse, Yes

Project description

Stay

Simple Typed Argparse, Yes

ruff-action Tests

Add typing to your argparse CLIs without having to modify your current parsers.

Example:

from stay import Stayspace, StayParser

class ArgSpace(Stayspace):
    foo: int
    bar: str

parser = StayParser(namespace_cls=ArgSpace)

parser.add_argument("--foo", type=int)
parser.add_argument("--bar", type=float)

args = parser.parse_args()

reveal_type(args.foo) # int
reveal_type(args.bar) # float
reveal_type(args.invalid) # Type Error

Install

To install from PyPi:

pip install -U py-stay

To install the most recent dev version

git clone https://github.com/drkspace/stay
cd stay
pip install .

Why not other typed argparse libraries?

There are two other typed argparse libraries, tap and typed-argparse. Their main deficiencies are that they can not replicate all of argparse's features, like argument groups and mutually exclusive groups. Stay, on the other hand, will always support 100% of argparse's features as the parsing class, StayParser, is a subclass of argparse.ArgumentParser.

However, Stay cannot generate a parser from a Namespace or other data structure. If you require that functionality, please use tap or typed-argparse. No Hard feelings.

Examples

Here are some examples. See examples/ for the full set.

Simple Example

#!/usr/bin/env python
# ruff: noqa: T201
from stay import StayParser, Stayspace


class CLIInput(Stayspace):
    name: str
    age: int

def main() -> None:

    parser = StayParser(namespace_cls=CLIInput)

    parser.add_argument("--name", type=str)
    parser.add_argument("--age", type=int)

    args = parser.parse_args()

    print(f"Hello {args.name}. You are {args.age} years old")

if __name__ == "__main__":
    main()

Mutually exclusive groups

Unfortunately, python's typing system is not robust enough to have a nice way to have multiple/an arbitrary number types as the namespace_cls input. You have to fake it with combining your Stayspaces into one class and using that as input to namespace_cls. You are still able to type the generic as the union of your types and then you can use a TypeIs or TypeGuard (depending on your python version) to pick out the type.

[!IMPORTANT] If you use the below strategy of creating a subclass of 2 Stayspaces, any methods or ClassVars you add to them might interfere with eachother.

#!/usr/bin/env python
# ruff: noqa: T201

from typing_extensions import TypeIs

from stay import StayParser, Stayspace


class CLIInput1(Stayspace):
    foo: int

class CLIInput2(Stayspace):
    bar: str

class CLICombined(CLIInput1, CLIInput2):
    ...

def is_inp_1(inp: CLIInput1|CLIInput2) -> TypeIs[CLIInput1]:
    return "foo" in inp

def main() -> None:

    parser = StayParser[CLIInput1|CLIInput2](namespace_cls=CLICombined)

    meg = parser.add_mutually_exclusive_group(required=True)
    meg.add_argument("--foo", type=int)
    meg.add_argument("--bar", type=str)

    args = parser.parse_args()

    if is_inp_1(args):
        print(f"You inputted foo with a value of {args.foo}")
    else:
        print(f"You inputted bar with a value of {args.bar}")

if __name__ == "__main__":
    main()

Subparser

Subparsers act just like (mutually exclusive) groups. In order to match with how argparse behaves, the results of a subparser will be "flat". You can use TypeIs/TypeGuard to narrow a Stayspace to the one for a specific subparser.

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

py_stay-0.2.1.tar.gz (5.9 kB view details)

Uploaded Source

Built Distribution

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

py_stay-0.2.1-py3-none-any.whl (5.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: py_stay-0.2.1.tar.gz
  • Upload date:
  • Size: 5.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for py_stay-0.2.1.tar.gz
Algorithm Hash digest
SHA256 dac8a856d5c157a84f2632001de56055e055225932bb4484dbab6b6060a8eec0
MD5 3516f330770aeb06d9ed1dfcbc0b747a
BLAKE2b-256 bdb4b6bc20cab4178e65cd04a6a42457b0dbb755ed20e8fa0e0dd33a721497db

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_stay-0.2.1.tar.gz:

Publisher: publish.yml on drkspace/stay

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

  • Download URL: py_stay-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 5.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for py_stay-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 adcae8973ead5faf8b750cf4e7fab09510c2a4272568710d1946745e84e3521c
MD5 6d204f6539a5f6e27b87023e7c2e31b8
BLAKE2b-256 390a6fc0384b61833dac9c0d73357f2acafd54bf8d6fd003f792a956ca4ab516

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_stay-0.2.1-py3-none-any.whl:

Publisher: publish.yml on drkspace/stay

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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