Last active
November 13, 2021 00:02
-
-
Save kissgyorgy/d080ad6d1aba50d89f76 to your computer and use it in GitHub Desktop.
Python: decorator for converting parameters from possible yes/no values to bool
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import inspect | |
import functools | |
from distutils.util import strtobool | |
def tobool(yesno): | |
"""Convert all kinds of possible "yes" values to True/False.""" | |
return bool(strtobool(yesno)) | |
def bool_param(*bool_args): | |
"""Convert given parameter possible yes/no values to True/False.""" | |
def convert_params_to_bool(func): | |
@functools.wraps(func) | |
def wrapper(*args, **kwargs): | |
for bool_arg in bool_args: | |
try: | |
# first see if we got it as a keyword argument | |
ba = kwargs.pop(bool_arg) | |
kwargs[bool_arg] = tobool(ba) | |
except KeyError: | |
argspec = inspect.getargspec(func) | |
index = argspec.args.index(bool_arg) | |
# convert to mutable type, so we can modify it in place | |
args = list(args) | |
try: | |
# if did not get as a keyword arg, try to lookup if | |
# it has been given as positional argument | |
args[index] = tobool(args[index]) | |
except IndexError: | |
# Not given as kwarg, neither arg, so we need default | |
# value corresponding to bool_arg variable | |
defaults = argspec.defaults or [] | |
num_args = len(argspec.args) - len(defaults) | |
def_index = num_args - index | |
try: | |
kwargs[bool_arg] = tobool(defaults[def_index]) | |
except IndexError: | |
# conform to python built in message when incorrect | |
# number of parameters have been given | |
message = ('{}() takes exactly {} arguments ({} given)' | |
.format(func.__name__, num_args, len(args))) | |
raise TypeError(message) | |
return func(*args, **kwargs) | |
return wrapper | |
return convert_params_to_bool |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@bool_param('param1') | |
def test1(param1, param2='noconvert'): | |
print('PARAM1:', type(param1), param1) | |
print('PARAM2:', type(param2), param2) | |
@bool_param('param1') | |
def test2(param1='yes', param2='noconvert'): | |
print('PARAM1:', type(param1), param1) | |
print('PARAM2:', type(param2), param2) | |
@bool_param('param1', 'param2') | |
def test3(param1='no', param2='yes'): | |
print('PARAM1:', type(param1), param1) | |
print('PARAM2:', type(param2), param2) | |
>>> test1('yes') | |
PARAM1: <type 'bool'> True | |
PARAM2: <type 'unicode'> noconvert | |
>>> test2() | |
PARAM1: <type 'bool'> True | |
PARAM2: <type 'unicode'> noconvert | |
>>> test3() | |
PARAM1: <type 'bool'> False | |
PARAM2: <type 'bool'> True |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment