Skip to content

Commit

Permalink
properly handle deserializing Tuple[str, ...] and str types
Browse files Browse the repository at this point in the history
  • Loading branch information
Kamilcuk committed Oct 9, 2024
1 parent 63e714f commit de2d3a6
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 13 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ the `dataclass`, removing the arguments in the process.

```python
@click.command(help="This is a command")
@clickdc("args", Args)
@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
Expand Down Expand Up @@ -106,6 +107,8 @@ 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.
Expand Down
21 changes: 10 additions & 11 deletions src/clickdc.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
and get click arguments to parse.
"""

import abc
import dataclasses
import functools
import logging
Expand Down Expand Up @@ -250,20 +251,18 @@ def to_args(self, obj: DataclassInstance) -> List[str]:
ret: List[str] = []
if self.is_option() or self.is_argument():
value = getattr(obj, self.name)
name = self.dashdashoption()
if self.kwargs.get("is_flag"):
name = self.dashdashoption() if self.is_option() else ""
nameeq = (name + "=") if name else ""
if value is None:
pass
elif self.is_option() and self.kwargs.get("is_flag"):
if value:
ret.append(name)
elif is_tuple_arr(type(value)) or isinstance(value, Iterable):
if value:
for i in value:
if self.is_option():
ret.append(name)
ret.append(str(i))
elif isinstance(value, (list, tuple)):
for i in value:
ret.append(nameeq + str(i))
else:
if self.is_option():
ret.append(name)
ret.append(str(value))
ret.append(nameeq + str(value))
return ret


Expand Down
11 changes: 10 additions & 1 deletion tests/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,14 +243,23 @@ def test_to_args():
class Args:
opta: bool = clickdc.option("-a")
optb: Tuple[int, ...] = clickdc.option("-b")
optc: Tuple[str, ...] = clickdc.option("-c")
optd: Optional[str] = clickdc.option("-d")
cmda: int = clickdc.argument()
cmdb: int = clickdc.argument()
cmdc: Tuple[int, ...] = clickdc.argument()

run(Args, "1 2 3 4 5 6", "1 2 3 4 5 6", toargs=True)
run(Args, "--opta 1 2 3 4", "--opta 1 2 3 4", toargs=True)
run(Args, "-a 1 2 3 4", "--opta 1 2 3 4", toargs=True)
run(Args, "-a -b 1 -b 2 1 2 3", "--opta --optb 1 --optb 2 1 2 3", toargs=True)
run(Args, "-a -b 1 -b 2 1 2 3", "--opta --optb=1 --optb=2 1 2 3", toargs=True)
run(
Args,
"-a -b 1 -b 2 -c aaa -c bbb -c ddd 1 2 3",
"--opta --optb=1 --optb=2 --optc=aaa --optc=bbb --optc=ddd 1 2 3",
toargs=True,
)
run(Args, "-d aaa -d bbb -d ccc 1 2 3", "--optd=ccc 1 2 3", toargs=True)


def test_to_list_option():
Expand Down

0 comments on commit de2d3a6

Please sign in to comment.