{"id":20313928,"url":"https://github.com/ethanabrooks/dollar-lambda","last_synced_at":"2025-04-11T17:17:05.617Z","repository":{"id":41098506,"uuid":"284256887","full_name":"ethanabrooks/dollar-lambda","owner":"ethanabrooks","description":"An argument parsing library based on function first principles","archived":false,"fork":false,"pushed_at":"2022-07-30T17:39:59.000Z","size":2151,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-10T17:51:28.031Z","etag":null,"topics":["argument-parser","functional-programming","parser","parser-combinators","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ethanabrooks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-08-01T12:36:44.000Z","updated_at":"2023-09-05T22:34:05.000Z","dependencies_parsed_at":"2022-08-28T23:30:25.693Z","dependency_job_id":null,"html_url":"https://github.com/ethanabrooks/dollar-lambda","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethanabrooks%2Fdollar-lambda","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethanabrooks%2Fdollar-lambda/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethanabrooks%2Fdollar-lambda/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethanabrooks%2Fdollar-lambda/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ethanabrooks","download_url":"https://codeload.github.com/ethanabrooks/dollar-lambda/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248447600,"owners_count":21105140,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["argument-parser","functional-programming","parser","parser-combinators","python"],"created_at":"2024-11-14T18:13:30.882Z","updated_at":"2025-04-11T17:17:05.597Z","avatar_url":"https://github.com/ethanabrooks.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg height=\"300\" src=\"https://dollar-lambda.readthedocs.io/en/latest/_static/logo.png\"\u003e\n\u003c/p\u003e\n\n[$λ](https://dollar-lambda.readthedocs.io/) provides an alternative to [`argparse`](https://docs.python.org/3/library/argparse.html)\nbased on parser combinators and functional first principles. Arguably, `$λ` is way more expressive than any reasonable\nperson would ever need... but even if it's not the parser that we need, it's the parser we deserve.\n\n# Installation\n```\npip install dollar-lambda\n```\n\n# [Documentation](https://dollar-lambda.readthedocs.io/)\n\n# Highlights\n`$λ` comes with syntactic sugar that can make building parsers completely boilerplate-free.\nFor complex parsing situations that exceed the expressive capacity of this syntax,\nthe user can also drop down to the lower-level syntax that lies behind the sugar, which can\nhandle any reasonable amount of logical complexity.\n\n## The [`@command`](https://dollar-lambda.readthedocs.io/en/latest/api.html?highlight=command#dollar_lambda.decorators.command)\ndecorator\nFor the vast majority of parsing patterns,\n[`@command`](https://dollar-lambda.readthedocs.io/en/latest/api.html?highlight=command#dollar_lambda.decorators.command)\nis the most concise way to define a parser:\n\n\n```python\nfrom dollar_lambda import command\n\n\n@command()\ndef main(x: int, dev: bool = False, prod: bool = False):\n    print(dict(x=x, dev=dev, prod=prod))\n```\n\nHere is the help text generated by this parser:\n\n\n```python\nmain(\"-h\")\n```\n\n    usage: -x X --dev --prod\n    dev: (default: False)\n    prod: (default: False)\n\n\nOrdinarily you provide no arguments to `main` and it would get them from the command line.\nThe explicit arguments in this Readme are for demonstration purposes only.\nHere is how the main function handles input:\n\n\n```python\nmain(\"-x\", \"1\", \"--dev\")\n```\n\n    {'x': 1, 'dev': True, 'prod': False}\n\n\nUse the `parsers` argument to add custom logic using the lower-level syntax:\n\n\n```python\nfrom dollar_lambda import flag\n\n\n@command(parsers=dict(kwargs=flag(\"dev\") | flag(\"prod\")))\ndef main(x: int, **kwargs):\n    print(dict(x=x, **kwargs))\n```\n\nThis parser requires either a `--dev` or `--prod` flag and maps it to the `kwargs` argument:\n\n\n```python\nmain(\"-h\")\n```\n\n    usage: -x X [--dev | --prod]\n\n\nThis assigns `{'dev': True}` to the `kwargs` argument:\n\n\n```python\nmain(\"-x\", \"1\", \"--dev\")\n```\n\n    {'x': 1, 'dev': True}\n\n\nThis assigns `{'prod': True}` to the `kwargs` argument:\n\n\n```python\nmain(\"-x\", \"1\", \"--prod\")\n```\n\n    {'x': 1, 'prod': True}\n\n\nThis fails because the parser requires one or the other:\n\n\n```python\nmain(\"-x\", \"1\")\n```\n\n    usage: -x X [--dev | --prod]\n    The following arguments are required: --dev\n\n\n## [`CommandTree`](https://dollar-lambda.readthedocs.io/en/latest/commandtree.html) for dynamic dispatch\nFor many programs, a user will want to use one entrypoint for one set of\narguments, and another for another set of arguments. Returning to our example,\nlet's say we wanted to execute `prod_function` when the user provides the\n`--prod` flag, and `dev_function` when the user provides the `--dev` flag:\n\n\n```python\nfrom dollar_lambda import CommandTree\n\ntree = CommandTree()\n\n\n@tree.command()\ndef base_function(x: int):\n    print(\"Ran base_function with arguments:\", dict(x=x))\n\n\n@base_function.command()\ndef prod_function(x: int, prod: bool):\n    print(\"Ran prod_function with arguments:\", dict(x=x, prod=prod))\n\n\n@base_function.command()\ndef dev_function(x: int, dev: bool):\n    print(\"Ran dev_function with arguments:\", dict(x=x, dev=dev))\n```\n\nLet's see how this parser handles different inputs.\nIf we provide the `--prod` flag, `$λ` automatically invokes\n `prod_function` with the parsed arguments:\n\n\n```python\ntree(\n    \"-x\", \"1\", \"--prod\"\n)  # usually you provide no arguments and tree gets them from sys.argv\n```\n\n    Ran prod_function with arguments: {'x': 1, 'prod': True}\n\n\nIf we provide the `--dev` flag, `$λ` invokes `dev_function`:\n\n\n```python\ntree(\"-x\", \"1\", \"--dev\")\n```\n\n    Ran dev_function with arguments: {'x': 1, 'dev': True}\n\n\nWith this configuration, the parser will run `base_function` if neither\n`--prod` nor `--dev` are given:\n\n\n```python\ntree(\"-x\", \"1\")\n```\n\n    Ran base_function with arguments: {'x': 1}\n\n\nThere are many other ways to use [`CommandTree`](https://dollar-lambda.readthedocs.io/en/latest/commandtree.html).\nTo learn more, we recommend the [`CommandTree` tutorial](https://dollar-lambda.readthedocs.io/en/latest/command_tree.html).\n\n## Lower-level syntax\n[`@command`](https://dollar-lambda.readthedocs.io/en/latest/api.html?highlight=command#dollar_lambda.decorators.command)\nand [`CommandTree`](https://dollar-lambda.readthedocs.io/en/latest/api.html#dollar_lambda.decorators.CommandTree)\ncover many use cases,\nbut they are both syntactic sugar for a lower-level interface that is far\nmore expressive.\n\nSuppose you want to implement a parser that first tries to parse an option\n(a flag that takes an argument),\n`-x X` and if that fails, tries to parse the input as a variadic sequence of\nfloats:\n\n\n```python\nfrom dollar_lambda import argument, option\n\np = option(\"x\", type=int) | argument(\"y\", type=float).many()\n```\n\nWe go over this syntax in greater detail in the [tutorial](https://dollar-lambda.readthedocs.io/en/latest/tutorial.html).\nFor now, suffice to say that [`argument`](https://dollar-lambda.readthedocs.io/en/latest/api.html?highlight=argument#dollar_lambda.parsers.argument)\n defines a positional argument,\n[`many`](https://dollar-lambda.readthedocs.io/en/latest/variations.html?highlight=many#many) allows parsers to be applied\nzero or more times, and [`|`](https://dollar-lambda.readthedocs.io/en/latest/api.html?highlight=__or__#dollar_lambda.parsers.Parser.__or__) expresses alternatives.\n\nHere is the help text:\n\n\n```python\np.parse_args(\n    \"-h\"\n)  # usually you provide no arguments and parse_args gets them from sys.argv\n```\n\n    usage: [-x X | [Y ...]]\n\n\nAs promised, this succeeds:\n\n\n```python\np.parse_args(\"-x\", \"1\")\n```\n\n\n\n\n    {'x': 1}\n\n\n\nAnd this succeeds:\n\n\n```python\np.parse_args(\"1\", \"2\", \"3\")\n```\n\n\n\n\n    {'y': [1.0, 2.0, 3.0]}\n\n\n\n### Thanks\nSpecial thanks to [\"Functional Pearls\"](https://www.cs.nott.ac.uk/~pszgmh/pearl.pdf) by Graham Hutton and Erik Meijer for bringing these topics to life.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fethanabrooks%2Fdollar-lambda","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fethanabrooks%2Fdollar-lambda","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fethanabrooks%2Fdollar-lambda/lists"}