diff options
author | Eric Lin <anselor@gmail.com> | 2020-08-19 14:01:50 -0400 |
---|---|---|
committer | anselor <anselor@gmail.com> | 2021-03-18 18:26:20 -0400 |
commit | 486734e85988d0d0160147b0b44a37759c833e8a (patch) | |
tree | 3b0ef809806d86d781e869771540465cbe089e20 /cmd2/utils.py | |
parent | a0cb0e37878a03aa197ba502857afabb0ffad171 (diff) | |
download | cmd2-git-486734e85988d0d0160147b0b44a37759c833e8a.tar.gz |
Each CommandSet's settables are defined separately. cmd2.Cmd searches all registered CommandSets for settables.
Settables can now set any attribute on any object passed to it. The name the user sees may be set to a different value
than what the actual attribute is.
Cmd2 will now aggregate all settables on the cmd2.Cmd instance with each installed CommandSet.
Diffstat (limited to 'cmd2/utils.py')
-rw-r--r-- | cmd2/utils.py | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/cmd2/utils.py b/cmd2/utils.py index c9577e82..1008cb86 100644 --- a/cmd2/utils.py +++ b/cmd2/utils.py @@ -28,13 +28,15 @@ from typing import ( Optional, TextIO, Type, + TYPE_CHECKING, Union, ) from . import ( constants, ) - +if TYPE_CHECKING: # pragma: no cover + import cmd2 def is_quoted(arg: str) -> bool: """ @@ -93,7 +95,7 @@ def str_to_bool(val: str) -> bool: class Settable: - """Used to configure a cmd2 instance member to be settable via the set command in the CLI""" + """Used to configure an attribute to be settable via the set command in the CLI""" def __init__( self, @@ -101,6 +103,8 @@ class Settable: val_type: Callable, description: str, *, + settable_object: Optional[object] = None, + settable_attrib_name: Optional[str] = None, onchange_cb: Callable[[str, Any, Any], Any] = None, choices: Iterable = None, choices_provider: Optional[Callable] = None, @@ -114,6 +118,8 @@ class Settable: even validate its value. Setting this to bool provides tab completion for true/false and validation using str_to_bool(). The val_type function should raise an exception if it fails. This exception will be caught and printed by Cmd.do_set(). + :param settable_object: Object to configure with the set command + :param settable_attrib_name: Attribute name to be modified. Defaults to `name` if not specified. :param description: string describing this setting :param onchange_cb: optional function or method to call when the value of this settable is altered by the set command. (e.g. onchange_cb=self.debug_changed) @@ -137,11 +143,36 @@ class Settable: self.name = name self.val_type = val_type self.description = description + self.settable_obj = settable_object + self.settable_attrib_name = settable_attrib_name if settable_attrib_name is not None else name self.onchange_cb = onchange_cb self.choices = choices self.choices_provider = choices_provider self.completer = completer + def get_value(self) -> Any: + """ + Get the value of the settable attribute + :return: + """ + return getattr(self.settable_obj, self.settable_attrib_name) + + def set_value(self, value: Any) -> Any: + """ + Set the settable attribute on the specified destination object + :param value: New value to set + :return: New value that the attribute was set to + """ + # Try to update the settable's value + orig_value = self.get_value() + setattr(self.settable_obj, self.settable_attrib_name, self.val_type(value)) + new_value = getattr(self.settable_obj, self.settable_attrib_name) + + # Check if we need to call an onchange callback + if orig_value != new_value and self.onchange_cb: + self.onchange_cb(self.name, orig_value, new_value) + return new_value + def namedtuple_with_defaults(typename: str, field_names: Union[str, List[str]], default_values: collections_abc.Iterable = ()): """ |