A function decorator which makes a function tolerant (the function fail silently).
Project description
Do you often write the fail silent codes like below?
try:
# do what ever you need...
return "foo"
except:
# fail silently
return ""
This kind of codes are often found in Django projects or programs which should not raise any exceptions in product mode.
tolerance is a function decorator to make a tolerant function; a function which does not raise any exceptions even there are exceptions. This concept is quite useful for making stable product or prefer_int types of code described in Usage section.
Features
Convert a function to a tolerant function
The decorated function returns substitute (Default is None) when it is not callable. The function returns a “returned value” from substitute function when it is callable.
Ignoreing exceptions can be specified as a exception class list with exceptions argument.
When fail_silently=False is passed to the decorated function, the function does not ignore exceptions (the argument name can be changed with making switch function via argument_switch_generator function).
Installation
Use pip like:
$ pip install tolerance
Usage
Assume that you need a function which convert a string to an integer when it is possible. Without tolerance, you need to write a code like below
>>> # without tolerance
>>> def prefer_int_withot_tolerance(x):
... try:
... return int(x)
... except:
... # fail silently
... return x
>>> prefer_int_withot_tolerance(0)
0
>>> prefer_int_withot_tolerance('0')
0
>>> prefer_int_withot_tolerance('zero')
'zero'
However, with tolerance, you just need to write a single line code like
>>> from tolerance import tolerate
>>> prefer_int = tolerate(lambda x: x)(int)
>>> prefer_int(0)
0
>>> prefer_int('0')
0
>>> prefer_int('zero')
'zero'
Or you can use tolerate as a function decorator described in PEP-318
>>> from tolerance import tolerate
>>> @tolerate(lambda x: x)
... def prefer_int_318(x):
... return int(x)
>>> prefer_int_318(0)
0
>>> prefer_int_318('0')
0
>>> prefer_int_318('zero')
'zero'
The example codes above specify substitute argument of tolerate function to specify the returning value when the function has failed ( lambda x: x part). tolerate function takes several arguments to configure the function behavior. These arguments are explained in Case study and detailed in API documentation.
Case study
Q. How can I return the default value when the function fail?
Use substitute argument to specify the default value like
>>> from tolerance import tolerate
>>> @tolerate(substitute='foo')
... def raise_exception():
... raise Exception
>>> raise_exception()
'foo'
Q. How can I change the default value depends on passed arguments?
Specify substitute argument as a function
>>> from tolerance import tolerate
>>> def substitute_function(*args, **kwargs):
... # do what ever you need, this example simply return 1st argument
... return args[0]
>>> @tolerate(substitute=substitute_function)
... def raise_exception(*args):
... raise Exception
>>> raise_exception('bar', 'hoge')
'bar'
Q. How can I make the function to ignore only several exceptions?
Use exceptions argument to specify exceptions which will be ignored.
>>> from tolerance import tolerate
>>> exceptions_ignored = (
... AttributeError,
... ValueError,
... )
>>> @tolerate(exceptions=exceptions_ignored)
... def raise_exception(x):
... if x == 0:
... raise AttributeError
... elif x == 1:
... raise ValueError
... else:
... raise KeyError
>>> raise_exception(0) is None
True
>>> raise_exception(1) is None
True
>>> raise_exception(2)
Traceback (most recent call last):
...
KeyError
Q. How can I disable ignoreing exceptions in the decorated function?
Pass fail_silently=False to the decorated function.
>>> from tolerance import tolerate
>>> @tolerate()
... def raise_exception():
... raise KeyError
>>> raise_exception() is None
True
>>> raise_exception(fail_silently=False)
Traceback (most recent call last):
...
KeyError
You can change the attribute name with specifing new switch function. It will be explained below.
Q. How can I disable ignoreing exceptions globally?
Set tolerate.disabled = True to disable tolerance globally.
>>> from tolerance import tolerate
>>> @tolerate()
... def raise_exception():
... raise KeyError
>>> raise_exception() is None
True
>>> tolerate.disabled = True
>>> raise_exception()
Traceback (most recent call last):
...
KeyError
>>> # rollback
>>> tolerate.disabled = False
Q. How can I disable ignoreing exceptions in complex mannar?
Use switch argument to specify switch function.
>>> from tolerance import tolerate
>>> DEBUG = False
>>> def switch_function(*args, **kwargs):
... # do what ever you need, this sample check kwargs and DEBUG
... # remove 'fail_silently' attribute and store
... fail_silently = kwargs.pop('fail_silently', True)
... if DEBUG or not fail_silently:
... # do not ignore exceptions. note that kwargs which does not
... # have 'fail_silently' is returned back.
... return False, args, kwargs
... # do ignore exceptions. note that kwargs which does not have
... # 'fail_silently' is returned back.
... return True, args, kwargs
>>> @tolerate(switch=switch_function)
... def raise_exception():
... raise KeyError
>>> raise_exception() is None
True
>>> raise_exception(fail_silently=False)
Traceback (most recent call last):
...
KeyError
>>> DEBUG = True
>>> raise_exception()
Traceback (most recent call last):
...
KeyError
Q. I just want to change the attribute name, making switch function is too complicated
Use argument_switch_generator to make switch function.
>>> from tolerance import tolerate
>>> from tolerance import argument_switch_generator
>>> switch_function = argument_switch_generator('quiet')
>>> @tolerate(switch=switch_function)
... def raise_exception():
... raise KeyError
>>> raise_exception() is None
True
>>> # you can use `quiet=False` instead of `fail_silently`
>>> raise_exception(quiet=False)
Traceback (most recent call last):
...
KeyError
>>> # raise_exception does not know fail_silently so ignore
>>> raise_exception(fail_silently=False) is None
True
Q. I want to make the function ignoreing exceptions only when fail_silently=True is passed
Use default argument to tell argument_switch_generator function
>>> from tolerance import tolerate
>>> from tolerance import argument_switch_generator
>>> switch_function = argument_switch_generator('fail_silently', default=False)
>>> @tolerate(switch=switch_function)
... def raise_exception():
... raise KeyError
>>> raise_exception() is None
Traceback (most recent call last):
...
KeyError
>>> raise_exception(fail_silently=True) is None
True
Q. I want to disable the ignoreing exceptions when verbose=False is passed
Use reverse argument to tell argument_switch_generator function
>>> from tolerance import tolerate
>>> from tolerance import argument_switch_generator
>>> switch_function = argument_switch_generator('verbose', reverse=True)
>>> @tolerate(switch=switch_function)
... def raise_exception():
... raise KeyError
>>> raise_exception() is None
True
>>> raise_exception(verbose=True)
Traceback (most recent call last):
...
KeyError
Q. I want to use fail_silently argument even in decorated function
Use keep argument to tell argument_switch_generator function
>>> from tolerance import tolerate
>>> from tolerance import argument_switch_generator
>>> switch_function = argument_switch_generator('fail_silently', keep=True)
>>> @tolerate(switch=switch_function)
... def raise_exception(**kwargs):
... if 'fail_silently' in kwargs:
... raise KeyError
... return 'Failed!'
>>> raise_exception(fail_silently=True) is None
True
>>> raise_exception(fail_silently=False)
Traceback (most recent call last):
...
KeyError
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.