1

I have a function that allow many options as boolean values, e.g.:

def my_func(req, option_a=False, option_b=True, option_c=True):
  pass

I want to make sure that boolean values are added for these variables, so I can do a simple check as such:

def my_func(req, option_a=False, option_b=True, option_c=True):
  for param in [option_a, option_b, option_c]:
    if not isinstance(param, bool):
        raise ValueError(f'Unexpected value {param} for X. A boolean value is required')

Obviously this does not give a lot of information about which argument has the wrong value. I was wondering, therefore, if it is possible to get the name of the variable so that X in the above snippet is replaced by the variable name. An example Error would be:

Unexpected value bananas for option_b. A boolean value is required

Is this possible in Python?

Bram Vanroy
  • 27,032
  • 24
  • 137
  • 239

2 Answers2

1

Everything's possible!

def my_func(req, option_a=False, option_b=True, option_c=True):
  for param_name in ['option_a', 'option_b', 'option_c']:
    param = locals()[param_name]
    if not isinstance(param, bool):
        raise ValueError(f'Unexpected value {param} for {param_name}. A boolean value is required')

Another option would be using some **kwargs and parsing it in some way. Or maybe type annotations plus a type checker.

Arusekk
  • 827
  • 4
  • 22
1

if you accept to use **kwargs in your function instead of explicit option names, you could do this:

def my_func(req, **kwargs):
    default_params = {"option_a":False, "option_b":True, "option_c":True}
    for name,dpv in default_params.items():
        if name in kwargs:
            param = kwargs[name]
            if not isinstance(param, type(dpv)):
              raise ValueError('Unexpected value {param} for {name}. A {type} value is required'.format(param=param,name=name,type=dpv.__class__.__name__))
        else:
            kwargs[name] = dpv
    print(kwargs)

my_func(12,option_a=False,option_b=False,option_c=True)

this code has the parameters & their default values. If the type doesn't match one of the passed parameters, you get an error.

If you omit a value, kwargs is assigned a default value manually.

This works with booleans, but also with other types (of course since booleans are integers, it let integers pass, unless you change isinstance by a strict type(param) == type(dpv) check)

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • Very interesting! Does it make sense to put this in its own function, that checks the kwargs? Something like this: https://repl.it/repls/HardtofindAgileDominspector – Bram Vanroy Feb 23 '18 at 10:26