diff options
| author | 2020-07-17 23:53:17 -0700 | |
|---|---|---|
| committer | 2020-07-31 22:58:06 -0700 | |
| commit | dc2c1c7f44de99ad9cbc69edc90607c625562760 (patch) | |
| tree | 8aeeb4690bf6d6737b1d12758814b9f9f292bcfc | |
| parent | Decorators: pass bound arguments to callable (diff) | |
Add util function to get value from arg
This is a more advanced version meant to eventually replace the
`_get_arg_values` in decorators.py.
| -rw-r--r-- | bot/utils/function.py | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/bot/utils/function.py b/bot/utils/function.py new file mode 100644 index 000000000..7c5949122 --- /dev/null +++ b/bot/utils/function.py @@ -0,0 +1,34 @@ +"""Utilities for interaction with functions.""" + +import typing as t + +Argument = t.Union[int, str] + + +def get_arg_value(name_or_pos: Argument, arguments: t.OrderedDict[str, t.Any]) -> t.Any: + """ + Return a value from `arguments` based on a name or position. + + `arguments` is an ordered mapping of parameter names to argument values. + + Raise TypeError if `name_or_pos` isn't a str or int. + Raise ValueError if `name_or_pos` does not match any argument. + """ + if isinstance(name_or_pos, int): + # Convert arguments to a tuple to make them indexable. + arg_values = tuple(arguments.items()) + arg_pos = name_or_pos + + try: + name, value = arg_values[arg_pos] + return value + except IndexError: + raise ValueError(f"Argument position {arg_pos} is out of bounds.") + elif isinstance(name_or_pos, str): + arg_name = name_or_pos + try: + return arguments[arg_name] + except KeyError: + raise ValueError(f"Argument {arg_name!r} doesn't exist.") + else: + raise TypeError("'arg' must either be an int (positional index) or a str (keyword).") |