aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar MarkKoz <[email protected]>2020-07-17 23:53:17 -0700
committerGravatar MarkKoz <[email protected]>2020-07-31 22:58:06 -0700
commitdc2c1c7f44de99ad9cbc69edc90607c625562760 (patch)
tree8aeeb4690bf6d6737b1d12758814b9f9f292bcfc
parentDecorators: 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.py34
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).")