From b8413a9bf22362ad6eba7b4a4ddec94b81a0b5c6 Mon Sep 17 00:00:00 2001 From: Timotej Bernat Date: Mon, 22 Apr 2024 17:00:51 -0600 Subject: [PATCH] Added decorator to allow functions which expect a single tuple (or list) to accept starred non-keyword arguments --- polymerist/genutils/decorators/functional.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/polymerist/genutils/decorators/functional.py b/polymerist/genutils/decorators/functional.py index 2f03c86..1e47ba4 100644 --- a/polymerist/genutils/decorators/functional.py +++ b/polymerist/genutils/decorators/functional.py @@ -1,6 +1,6 @@ '''Decorators for modifying functions''' -from typing import Callable, Optional, Union +from typing import Callable, Iterable, Optional, Type, Union import inspect from functools import wraps @@ -49,6 +49,24 @@ def in_place_wrapper(obj : object, *args : Args, in_place : bool=False, **kwargs return in_place_wrapper +@extend_to_methods +def flexible_tuple_input(func : Callable[[tuple], T], valid_types : Union[Type, tuple[Type]]=object) -> Callable[[Iterable], T]: + '''Wrapper which allows a function which expects a single tuple to accept Iterable or even star-unpacked arguments''' + @wraps(func) + def wrapper(*args) -> T: # wrapper which accepts an arbitrary number of non-keyword argument + if (len(args) == 1) and isinstance(args[0], Iterable): + args = args[0] + + inputs = [] + for value in args: + if isinstance(value, valid_types): # works because isinstance() accepts either a single type or a tuple of types + inputs.append(value) + else: + raise TypeError + return func(inputs) # TODO: modify input type signature of wrapper function + + return wrapper + @extend_to_methods def allow_string_paths(funct : Callable[[Path, Args, KWArgs], T]) -> Callable[[Union[Path, str], Args, KWArgs], T]: '''Modifies a function which expects a Path as its first argument to also accept string-paths'''