# arcparse
Declare program arguments in a type-safe way.
This project builds on top of `argparse` by adding type-safety and allowing a more expressive argument parser definition.
## Example usage
```py
from arcparse import arcparser, flag, positional
from pathlib import Path
@arcparser
class Args:
path: Path = positional()
recurse: bool = flag("-r")
item_limit: int = 100
output_path: Path | None
args = Args.parse()
print(f"Scanning {args.path}...")
...
```
<details>
<summary>Help output of this parser</summary>
usage: program.py [-h] [-r] [--item-limit ITEM_LIMIT] [--output-path OUTPUT_PATH] path
positional arguments:
path
options:
-h, --help show this help message and exit
-r, --recurse
--item-limit ITEM_LIMIT
--output-path OUTPUT_PATH
</details>
For more examples see [Examples](examples/).
## Installation
```shell
# Using pip
$ pip install arcparse
```
## Features
- Positional, Option and [Flag](./examples/flag.py) arguments
- Name overriding
- [Multiple values per argument](./examples/multiple.py)
- [Type conversions](./examples/conversion.py)
- [Mutually exclusive groups](./examples/mutual_exclusion.py)
- [Subparsers](./examples/subparsers.py)
- [Parser inheritance](./examples/inheritance.py) (with [overriding](./examples/override.py))
- [Presence validation](./examples/presence_validation.py)
## Credits
This project was inspired by [swansonk14/typed-argument-parser](https://github.com/swansonk14/typed-argument-parser).
## Known issues
### Annotations
`from __future__ import annotations` makes all annotations strings at runtime. This library relies on class variable annotations's types being actual types. `inspect.get_annotations(obj, eval_str=True)` is used to evaluate string annotations to types in order to assign converters. If an argument is annotated with a non-builtin type which is defined outside of the argument-defining class body the type can't be found which results in `NameError`s. This is avoidable either by only using custom types which have been defined in the argument-defining class body (which is restrictive), or alternatively by not using the `annotations` import which should not be necessary from python 3.14 forward thanks to [PEP 649](https://peps.python.org/pep-0649/).
Raw data
{
"_id": null,
"home_page": "https://github.com/Kuba314/arcparse",
"name": "arcparse",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.12",
"maintainer_email": null,
"keywords": "argparse, declarative, argument, parsing, type-safe",
"author": "Jakub Rozek",
"author_email": "jakub.rozek314@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/29/ca/f9e60efd93d5ca6a73272a111f830b76f8276177ac870cf2d8bc1c956da2/arcparse-1.3.1.tar.gz",
"platform": null,
"description": "# arcparse\nDeclare program arguments in a type-safe way.\n\nThis project builds on top of `argparse` by adding type-safety and allowing a more expressive argument parser definition.\n\n## Example usage\n```py\nfrom arcparse import arcparser, flag, positional\nfrom pathlib import Path\n\n@arcparser\nclass Args:\n path: Path = positional()\n recurse: bool = flag(\"-r\")\n item_limit: int = 100\n output_path: Path | None\n\nargs = Args.parse()\nprint(f\"Scanning {args.path}...\")\n...\n```\n<details>\n <summary>Help output of this parser</summary>\n\n usage: program.py [-h] [-r] [--item-limit ITEM_LIMIT] [--output-path OUTPUT_PATH] path\n\n positional arguments:\n path\n\n options:\n -h, --help show this help message and exit\n -r, --recurse\n --item-limit ITEM_LIMIT\n --output-path OUTPUT_PATH\n\n</details>\n\nFor more examples see [Examples](examples/).\n\n## Installation\n```shell\n# Using pip\n$ pip install arcparse\n```\n\n## Features\n- Positional, Option and [Flag](./examples/flag.py) arguments\n- Name overriding\n- [Multiple values per argument](./examples/multiple.py)\n- [Type conversions](./examples/conversion.py)\n- [Mutually exclusive groups](./examples/mutual_exclusion.py)\n- [Subparsers](./examples/subparsers.py)\n- [Parser inheritance](./examples/inheritance.py) (with [overriding](./examples/override.py))\n- [Presence validation](./examples/presence_validation.py)\n\n## Credits\nThis project was inspired by [swansonk14/typed-argument-parser](https://github.com/swansonk14/typed-argument-parser).\n\n## Known issues\n\n### Annotations\n`from __future__ import annotations` makes all annotations strings at runtime. This library relies on class variable annotations's types being actual types. `inspect.get_annotations(obj, eval_str=True)` is used to evaluate string annotations to types in order to assign converters. If an argument is annotated with a non-builtin type which is defined outside of the argument-defining class body the type can't be found which results in `NameError`s. This is avoidable either by only using custom types which have been defined in the argument-defining class body (which is restrictive), or alternatively by not using the `annotations` import which should not be necessary from python 3.14 forward thanks to [PEP 649](https://peps.python.org/pep-0649/).\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Declare program arguments in a type-safe way",
"version": "1.3.1",
"project_urls": {
"Homepage": "https://github.com/Kuba314/arcparse",
"Repository": "https://github.com/Kuba314/arcparse"
},
"split_keywords": [
"argparse",
" declarative",
" argument",
" parsing",
" type-safe"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "9895c0a3acfb5f666c524a41f9561ff18c05bbf157e5bc844ff974014d3fe314",
"md5": "9a8745c336c2139989e6d61d61a70312",
"sha256": "fcd58ef46da8868710bb5b477c1899ff45b4041126710734e9b33a8504a7af57"
},
"downloads": -1,
"filename": "arcparse-1.3.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "9a8745c336c2139989e6d61d61a70312",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.12",
"size": 15121,
"upload_time": "2025-02-01T20:39:30",
"upload_time_iso_8601": "2025-02-01T20:39:30.478141Z",
"url": "https://files.pythonhosted.org/packages/98/95/c0a3acfb5f666c524a41f9561ff18c05bbf157e5bc844ff974014d3fe314/arcparse-1.3.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "29caf9e60efd93d5ca6a73272a111f830b76f8276177ac870cf2d8bc1c956da2",
"md5": "146cd0bbe1c9599e7d62c673b73219ab",
"sha256": "79f8eecf24a2178d6dde0fdf7551dc9c1e2346c1c41424ca12b2d3e16668cd04"
},
"downloads": -1,
"filename": "arcparse-1.3.1.tar.gz",
"has_sig": false,
"md5_digest": "146cd0bbe1c9599e7d62c673b73219ab",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.12",
"size": 12663,
"upload_time": "2025-02-01T20:39:32",
"upload_time_iso_8601": "2025-02-01T20:39:32.414946Z",
"url": "https://files.pythonhosted.org/packages/29/ca/f9e60efd93d5ca6a73272a111f830b76f8276177ac870cf2d8bc1c956da2/arcparse-1.3.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-01 20:39:32",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Kuba314",
"github_project": "arcparse",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "arcparse"
}