# clickdc
This is a package to define click command line options from a python `dataclass`.
You can define a python `dataclass` from `dataclasses` with fields that have
proper types when assigned by click parsing library. Then each field is
initialized with a option, argument, command or group from `clickdc` library.
```python
from dataclasses import dataclass
import clickdc
import click
@dataclass
class Args:
option: bool = clickdc.option(is_flag=True, help="This is an option")
command: int = clickdc.argument(type=int)
```
When the `dataclass` is decorated with `clickdc.adddc` to a function, this
library collects all options and arguments from the `dataclass` definition and
decorates the function. Then upon calling the function, this library
reconstructs the object using only arguments with names equal to the fields in
the `dataclass`, removing the arguments in the process.
```python
@click.command(help="This is a command")
@clickdc.adddc("args", Args)
def cli(args: Args):
print(args)
print(clickdc.to_args(args)) # converts dataclass back to string '--option command'
```
If a keyword argument `clickdc` is missing, the field name is added with
an underscore replaced by dashes with two front dashes in front, and the
argument is added as a string as positional argument to `click.argument`
call. If the argument already exists, it is not added twice, for ease
of porting.
```python
long_option: Optional[str] = clickdc.option("-o", help="--long-option is added automatically")
args: str = clickdc.option(help="Positional argument 'args' is added automatically")
```
Additionally, some keyword arguments to the underlying `click.option` or
`click.argument` are inferred from the `dataclass` field type depending on
on the following conditions. Use field type `Any` or add `type=`, for example
`type=str`, to ad-hoc disable the mechanisms.
- If the field:
- is initialized using an `option` or `argument`,
- does not have the type `Any`,
- does not have any keyword argument `type required is_flag default nargs count flag_value`
- and does not have an argument `clickdc` passed with `None`
- Then:
- if the field is an option, then if the field type
- is `bool`, add `is_flag=True`
- is `Optional[T]`, add `type=T`
- is `Tuple[T, ...]`, add type=T, multiple=True,
- is any other type `T`, add `type=T, required=True`
- if the field is an argument, then if the field type:
- is `Tuple[T, ...]`, add `type=T, nargs=-1`
- is any other type `T`, add `type=T`
The correct type for multiple arguments returned by `click` is `Tuple[T, ...]`.
```python
custom: Tuple[float, ...] = clickdc.option(type=float, multiple=True)
moreargs: Tuple[int, ...] = clickdc.argument(type=int, nargs=5)
options: Tuple[float, ...] = clickdc.option()
arguments: Tuple[int, ...] = clickdc.argument()
```
The `dataclass` field initializes functions - command, group, option, argument - take the
same options as their click counterparts with one additional positional
argument called `clickdc` for this module options. The `clickdc` can be assigned
just to `None` to disable automatic adding of the options and keyword
arguments by this module.
```python
option: bool = clickdc.option("--option", is_flag=True, clickdc=None)
command: int = clickdc.argument("command", type=int, clickdc=None)
```
You can use `from pydantic.dataclasses import dataclass` to have type checking
for your `dataclass`.
You can safely mix any `clickdc` options with `click` options. Typically, I
would do:
```python
@dataclass
class Args:
options: bool = clickdc.option(help="Options here")
@click.command(help="But command here")
@clickdc.adddc("args", Args)
@click.option("-v", "--verbose", count=True)
def cli(args: Args, verbose: int):
print(args)
print(verbose)
```
You can inherit `dataclasses` and decorate using multiple. It works just by
decorating the function with the proper `click.` function inferred from the
field type.
# TODO
`dataclasses(default, default_factory)` require some questionable polishing.
# Epilogue
Written by Kamil Cukrowski
Raw data
{
"_id": null,
"home_page": null,
"name": "clickdc",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": null,
"author": "Kamil Cukrowski",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/c6/c6/bae77666e82b78efeb11f53adbffef757141d7c236ab933e522b469910b4/clickdc-0.1.1.tar.gz",
"platform": null,
"description": "# clickdc\n\nThis is a package to define click command line options from a python `dataclass`.\n\nYou can define a python `dataclass` from `dataclasses` with fields that have\nproper types when assigned by click parsing library. Then each field is\ninitialized with a option, argument, command or group from `clickdc` library.\n\n```python\nfrom dataclasses import dataclass\nimport clickdc\nimport click\n\n@dataclass\nclass Args:\n option: bool = clickdc.option(is_flag=True, help=\"This is an option\")\n command: int = clickdc.argument(type=int)\n```\n\nWhen the `dataclass` is decorated with `clickdc.adddc` to a function, this\nlibrary collects all options and arguments from the `dataclass` definition and\ndecorates the function. Then upon calling the function, this library\nreconstructs the object using only arguments with names equal to the fields in\nthe `dataclass`, removing the arguments in the process.\n\n```python\n@click.command(help=\"This is a command\")\n@clickdc.adddc(\"args\", Args)\ndef cli(args: Args):\n print(args)\n print(clickdc.to_args(args)) # converts dataclass back to string '--option command'\n```\n\nIf a keyword argument `clickdc` is missing, the field name is added with\nan underscore replaced by dashes with two front dashes in front, and the\nargument is added as a string as positional argument to `click.argument`\ncall. If the argument already exists, it is not added twice, for ease\nof porting.\n\n```python\n long_option: Optional[str] = clickdc.option(\"-o\", help=\"--long-option is added automatically\")\n args: str = clickdc.option(help=\"Positional argument 'args' is added automatically\")\n```\n\n\nAdditionally, some keyword arguments to the underlying `click.option` or\n`click.argument` are inferred from the `dataclass` field type depending on\non the following conditions. Use field type `Any` or add `type=`, for example\n`type=str`, to ad-hoc disable the mechanisms.\n\n- If the field:\n - is initialized using an `option` or `argument`,\n - does not have the type `Any`,\n - does not have any keyword argument `type required is_flag default nargs count flag_value`\n - and does not have an argument `clickdc` passed with `None`\n- Then:\n - if the field is an option, then if the field type\n - is `bool`, add `is_flag=True`\n - is `Optional[T]`, add `type=T`\n - is `Tuple[T, ...]`, add type=T, multiple=True,\n - is any other type `T`, add `type=T, required=True`\n - if the field is an argument, then if the field type:\n - is `Tuple[T, ...]`, add `type=T, nargs=-1`\n - is any other type `T`, add `type=T`\n\nThe correct type for multiple arguments returned by `click` is `Tuple[T, ...]`.\n\n```python\n custom: Tuple[float, ...] = clickdc.option(type=float, multiple=True)\n moreargs: Tuple[int, ...] = clickdc.argument(type=int, nargs=5)\n options: Tuple[float, ...] = clickdc.option()\n arguments: Tuple[int, ...] = clickdc.argument()\n```\n\n\nThe `dataclass` field initializes functions - command, group, option, argument - take the\nsame options as their click counterparts with one additional positional\nargument called `clickdc` for this module options. The `clickdc` can be assigned\njust to `None` to disable automatic adding of the options and keyword\narguments by this module.\n\n```python\n option: bool = clickdc.option(\"--option\", is_flag=True, clickdc=None)\n command: int = clickdc.argument(\"command\", type=int, clickdc=None)\n```\n\nYou can use `from pydantic.dataclasses import dataclass` to have type checking\nfor your `dataclass`.\n\nYou can safely mix any `clickdc` options with `click` options. Typically, I\nwould do:\n\n```python\n@dataclass\nclass Args:\n options: bool = clickdc.option(help=\"Options here\")\n\n@click.command(help=\"But command here\")\n@clickdc.adddc(\"args\", Args)\n@click.option(\"-v\", \"--verbose\", count=True)\ndef cli(args: Args, verbose: int):\n print(args)\n print(verbose)\n```\n\nYou can inherit `dataclasses` and decorate using multiple. It works just by\ndecorating the function with the proper `click.` function inferred from the\nfield type.\n\n\n\n# TODO\n\n`dataclasses(default, default_factory)` require some questionable polishing.\n\n# Epilogue\n\nWritten by Kamil Cukrowski\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Manage click arguments using python dataclass",
"version": "0.1.1",
"project_urls": {
"documentation": "https://github.com/Kamilcuk/clickdc",
"homepage": "https://github.com/Kamilcuk/clickdc",
"repository": "https://github.com/Kamilcuk/clickdc"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "ec3960a317ee2c67250bf2e70c1791ffd0d2e218927f019147ea89f7a6320727",
"md5": "8bb69c74a67e48230878f7e3da45ea91",
"sha256": "de5ac1c1af8253b45f9a6f75468efd1f0bb487d52fecb43dc3d9e970ca689fe7"
},
"downloads": -1,
"filename": "clickdc-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "8bb69c74a67e48230878f7e3da45ea91",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 7918,
"upload_time": "2024-10-09T20:01:33",
"upload_time_iso_8601": "2024-10-09T20:01:33.778165Z",
"url": "https://files.pythonhosted.org/packages/ec/39/60a317ee2c67250bf2e70c1791ffd0d2e218927f019147ea89f7a6320727/clickdc-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "c6c6bae77666e82b78efeb11f53adbffef757141d7c236ab933e522b469910b4",
"md5": "800a17ff685d7915dc9b6785f19d04ae",
"sha256": "077f04d7ad00509b43aa8e37a9c7df307c00a73f7fef265235ef98ca54235b9b"
},
"downloads": -1,
"filename": "clickdc-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "800a17ff685d7915dc9b6785f19d04ae",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 10128,
"upload_time": "2024-10-09T20:01:34",
"upload_time_iso_8601": "2024-10-09T20:01:34.730626Z",
"url": "https://files.pythonhosted.org/packages/c6/c6/bae77666e82b78efeb11f53adbffef757141d7c236ab933e522b469910b4/clickdc-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-09 20:01:34",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Kamilcuk",
"github_project": "clickdc",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "typing_extensions",
"specs": []
},
{
"name": "click",
"specs": []
}
],
"lcname": "clickdc"
}