Skip to content

Commit

Permalink
refactor: use DTO for both inferred and declared args
Browse files Browse the repository at this point in the history
forgot to add the new module :)
  • Loading branch information
neithere committed Oct 12, 2023
1 parent ea35440 commit 7ba3bf2
Showing 1 changed file with 85 additions and 0 deletions.
85 changes: 85 additions & 0 deletions src/argh/dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"""
Data transfer objects for internal usage.
"""
from dataclasses import dataclass, field
from typing import Any, Callable, Dict, List, Optional, Union, Type


class NotDefined:
"""
Specifies that an argument should not be passed to
ArgumentParser.add_argument(), even as None
"""


@dataclass
class ParserAddArgumentSpec:
"""
DTO, maps CLI arg(s) onto a function arg.
Ends up in ArgumentParser.add_argument().
"""

func_arg_name: Optional[str] # TODO: make it required (needs rearranging the logic)
cli_arg_names: List[str]
is_required: Union[bool, Type[NotDefined]] = NotDefined
default_value: Any = NotDefined
nargs: Optional[str] = None
other_add_parser_kwargs: Dict[str, Any] = field(default_factory=dict)

# https://kislyuk.github.io/argcomplete/#specifying-completers
completer: Optional[Callable] = None

def update(self, other: "ParserAddArgumentSpec") -> None:
for name in other.cli_arg_names:
if name not in self.cli_arg_names:
self.cli_arg_names.append(name)

if other.is_required != NotDefined:
self.is_required = other.is_required

if other.default_value != NotDefined:
self.default_value = other.default_value

if other.nargs:
self.nargs = other.nargs

if other.completer:
self.completer = other.completer

self.other_add_parser_kwargs.update(other.other_add_parser_kwargs)

def get_all_kwargs(self) -> Dict[str, Any]:
kwargs: Dict[str, Any] = {}

if self.is_required != NotDefined:
kwargs["required"] = self.is_required

if self.default_value != NotDefined:
kwargs["default"] = self.default_value

if self.nargs:
kwargs["nargs"] = self.nargs

return dict(kwargs, **self.other_add_parser_kwargs)

@classmethod
def make_from_kwargs(cls, func_arg_name, cli_arg_names, parser_add_argument_kwargs: Dict[str, Any]) -> "ParserAddArgumentSpec":
"""
Constructs and returns a `ParserAddArgumentSpec` instance
according to keyword arguments according to the
`ArgumentParser.add_argument()` signature.
"""
kwargs_copy = parser_add_argument_kwargs.copy()
instance = cls(
func_arg_name=func_arg_name,
cli_arg_names=cli_arg_names,
)
if "required" in kwargs_copy:
instance.is_required = kwargs_copy.pop("required")
if "nargs" in kwargs_copy:
instance.nargs = kwargs_copy.pop("nargs")
if "default" in kwargs_copy:
instance.default_value = kwargs_copy.pop("default")
if kwargs_copy:
instance.other_add_parser_kwargs = kwargs_copy
return instance

0 comments on commit 7ba3bf2

Please sign in to comment.