Welcome to tolerance’s documentation!¶
tolerance¶
- Author
- Alisue <lambdalisue@hashnote.net>
- Supported python versions
- 2.6, 2.7, 3.2, 3.3, 3.4
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.
Check online documentation for more details.
Features¶
- Convert a function to a tolerant function
- The decorated function returns
substitute
(Default isNone
) when it is not callable. The function returns a “returned value” fromsubstitute
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 viaargument_switch_generator
function).
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.
Change log¶
- Version 0.1.0
- Initial development
- Manually tested with Python 2.4, 2.5, 2.7, 3.2, 3.3
- Version 0.1.1
switch
shortcut feature is added- Drop off supporting Python 2.4 and 2.5
- Support Python 3.2 and 3.3 via 2to3
- Use tox for testing
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
>>> #
>>> # From Version 0.1.1
>>> #
>>> @tolerate(switch='quiet')
... def raise_exception():
... raise KeyError
>>> raise_exception() is None
True
>>> raise_exception(quiet=False)
Traceback (most recent call last):
...
KeyError
>>> raise_exception(fail_silently=False) is None
True
Note
From Version 0.1.1, you can simply specify the argument name to switch
argument and then tolerant
function will call
argument_switch_generator
internally with the specified name.
See detailed informations on API documentation
Q. I want to make the function ignoreing exceptions only when fail_silently=True
is passed¶
- Use
default
argument to tellargument_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
>>> #
>>> # From Version 0.1.1
>>> #
>>> @tolerate(switch=[None, False])
... def raise_exception():
... raise KeyError
>>> raise_exception() is None
Traceback (most recent call last):
...
KeyError
>>> @tolerate(switch={'default': False})
... def raise_exception():
... raise KeyError
>>> raise_exception() is None
Traceback (most recent call last):
...
KeyError
Note
From Version 0.1.1, you can simply specify *args
or **kwargs
of
argument_switch_generator
to switch
argument and tolerant
function will call argument_switch_generator
internally with the
specified arguments.
See detailed informations on API documentation
Q. I want to disable the ignoreing exceptions when verbose=False
is passed¶
- Use
reverse
argument to tellargument_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
>>> #
>>> # From Version 0.1.1
>>> #
>>> @tolerate(switch={'argument_name': 'verbose', 'reverse': True})
... 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 tellargument_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
>>> #
>>> # From Version 0.1.1
>>> #
>>> @tolerate(switch={'keep': True})
... 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
How to run the tests¶
Install requirement packages with
requirements-test.txt
:$ pip install -r requirements-test
Run tests with
nosetests
command provided by nose (it is automatically installed viarequirements-test.txt
)$ nosetests
All configuration for running tests can be found at [nosetests]
section of
setup.cfg
file.
API documents¶
tolerance Package¶
tolerance
Package¶
tolerance
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.
-
tolerance.
tolerate
(substitute=None, exceptions=None, switch=<function switch_function>)[source]¶ A function decorator which makes a function fail silently
To disable fail silently in a decorated function, specify
fail_silently=False
. To disable fail silenlty in decorated functions globally, specifytolerate.disabled
.Parameters: fn : function
A function which will be decorated.
substitute : function or returning value
A function used instead of
fn
or returning value whenfn
failed.exceptions : list of exceptions or None
A list of exception classes or None. If exceptions is specified, ignore exceptions only listed in this parameter and raise exception if the exception is not listed.
switch : string, list/tuple, dict, function or None
A switch function which determine whether silent the function failar. The function receive
*args
and**kwargs
which will specified tofn
and should return status (bool), args, and kwargs. If the function returnFalse
then agggressive decorated function worked as normal function (raise exception when there is exception). Default switch function is generated byargument_switch_generator()
withargument_switch_generator('fail_silently')
so iffail_silently=False
is specified to the function, the function works as noramlly.From Version 0.1.1, when switch is specified as non functional value,
argument_switch_generator()
will be called with switch as arguments. If string is specified, the switch generator will be called asargument_switch_generator(switch)
. If list or tuple is specified, the switch generator will be called asargument_switch_generator(*switch)
. If dict is specified, the switch generator will be called asargument_switch_generator(**switch)
.Returns: function
A decorated function
Examples
>>> # >>> # use tolerate as a function wrapper >>> # >>> parse_int = tolerate()(int) >>> parse_int(0) 0 >>> parse_int("0") 0 >>> parse_int("zero") is None True >>> # >>> # use tolerate as a function decorator (PIP-318) >>> # >>> @tolerate(lambda x: x) ... def prefer_int(x): ... return int(x) >>> prefer_int(0) 0 >>> prefer_int("0") 0 >>> prefer_int("zero") 'zero' >>> # >>> # filter exceptions be ignored >>> # >>> @tolerate(exceptions=(KeyError, ValueError)) ... def force_int(x): ... string_numbers = { ... 'zero': 0, ... 'one': 1, ... 'two': 2, ... 'three': 3, ... 'four': 4, ... 'five': 5, ... 'six': 6, ... 'seven': 7, ... 'eight': 8, ... 'nine': 9 ... } ... if isinstance(x, (int, float)): ... return int(x) ... elif isinstance(x, str): ... if x in string_numbers: ... return string_numbers[x] ... elif x in ('ten', 'hundred', 'thousand'): ... raise KeyError ... raise ValueError ... else: ... raise AttributeError >>> force_int('zero') 0 >>> force_int('ten') is None # KeyError True >>> force_int('foo') is None # ValueError True >>> force_int(object) # AttributeError Traceback (most recent call last): ... AttributeError >>> # >>> # disable tolerance by passing `fail_silently=False` >>> # >>> force_int('ten', fail_silently=False) # KeyError Traceback (most recent call last): ... KeyError >>> # >>> # disable tolerance globally by setting `tolerate.disabled=True` >>> # >>> tolerate.disabled = True >>> force_int('foo') # ValueError Traceback (most recent call last): ... ValueError >>> tolerate.disabled = False # rollback >>> # >>> # Features from Version 0.1.1 >>> # >>> # specify switch as a string >>> parse_int_string = tolerate(switch='patient')(int) >>> parse_int_string('zero') is None True >>> parse_int_string('zero', patient=False) Traceback (most recent call last): ... ValueError: ... >>> # specify switch as a list >>> parse_int_list = tolerate(switch=['fail_silently', False])(int) >>> parse_int_list('zero') Traceback (most recent call last): ... ValueError: ... >>> parse_int_string('zero', fail_silently=True) is None True >>> # specify switch as a dict >>> parse_int_dict = tolerate(switch={'argument_name': 'aggressive', ... 'reverse': True})(int) >>> parse_int_dict('zero') is None True >>> parse_int_dict('zero', aggressive=False) is None True >>> parse_int_dict('zero', aggressive=True) is None Traceback (most recent call last): ... ValueError: ...
-
tolerance.
argument_switch_generator
(argument_name=None, default=True, reverse=False, keep=False)[source]¶ Create switch function which return the status from specified named argument
Parameters: argument_name : string or None
An argument name which is used to judge the status. If
None
is specified, the value oftolerance.utils.DEFAULT_ARGUMENT_NAME
will be used instead.default : boolean
A default value of this switch function. It is used when specifid
**kwargs
does not have named argumentreverse : boolean
Reverse the status (Default:
False
)keep : boolean
If it is
True
, keep named argument in**kwargs
.Returns: function
A switch function which return status, args, and kwargs respectively.
Examples
>>> # >>> # generate switch function with default parameters >>> # >>> fn = argument_switch_generator('fail_silently') >>> # return `default` value and specified *args and **kwargs when >>> # `fail_silently` is not specified in **kwargs >>> fn() == (True, tuple(), {}) True >>> # return `fail_silently` value when it is specified >>> fn(fail_silently=True) == (True, tuple(), {}) True >>> fn(fail_silently=False) == (False, tuple(), {}) True >>> # >>> # generate switch function with `default=False` >>> # >>> fn = argument_switch_generator('fail_silently', default=False) >>> # return `default` value so `False` is returned back >>> fn() == (False, tuple(), {}) True >>> # >>> # generate switch function with `reverse=True` >>> # >>> fn = argument_switch_generator('fail_silently', reverse=True) >>> # `default` value is independent from `reverse=True` >>> fn() == (True, tuple(), {}) True >>> # `fail_silently` value is influenced by `reverse=True` >>> fn(fail_silently=True) == (False, tuple(), {}) True >>> fn(fail_silently=False) == (True, tuple(), {}) True >>> # >>> # generate switch function with `keep=True` >>> # >>> fn = argument_switch_generator('fail_silently', keep=True) >>> # `fail_silently` attribute remains even in returned back kwargs >>> status, args, kwargs = fn(fail_silently=True) >>> 'fail_silently' in kwargs True
decorators
Module¶
tolerance decorator module
-
tolerance.decorators.
DEFAULT_TOLERATE_SWITCH
(*args, **kwargs)¶ Default tolerate switch function
-
tolerance.decorators.
tolerate
(substitute=None, exceptions=None, switch=<function switch_function>)[source]¶ A function decorator which makes a function fail silently
To disable fail silently in a decorated function, specify
fail_silently=False
. To disable fail silenlty in decorated functions globally, specifytolerate.disabled
.Parameters: fn : function
A function which will be decorated.
substitute : function or returning value
A function used instead of
fn
or returning value whenfn
failed.exceptions : list of exceptions or None
A list of exception classes or None. If exceptions is specified, ignore exceptions only listed in this parameter and raise exception if the exception is not listed.
switch : string, list/tuple, dict, function or None
A switch function which determine whether silent the function failar. The function receive
*args
and**kwargs
which will specified tofn
and should return status (bool), args, and kwargs. If the function returnFalse
then agggressive decorated function worked as normal function (raise exception when there is exception). Default switch function is generated byargument_switch_generator()
withargument_switch_generator('fail_silently')
so iffail_silently=False
is specified to the function, the function works as noramlly.From Version 0.1.1, when switch is specified as non functional value,
argument_switch_generator()
will be called with switch as arguments. If string is specified, the switch generator will be called asargument_switch_generator(switch)
. If list or tuple is specified, the switch generator will be called asargument_switch_generator(*switch)
. If dict is specified, the switch generator will be called asargument_switch_generator(**switch)
.Returns: function
A decorated function
Examples
>>> # >>> # use tolerate as a function wrapper >>> # >>> parse_int = tolerate()(int) >>> parse_int(0) 0 >>> parse_int("0") 0 >>> parse_int("zero") is None True >>> # >>> # use tolerate as a function decorator (PIP-318) >>> # >>> @tolerate(lambda x: x) ... def prefer_int(x): ... return int(x) >>> prefer_int(0) 0 >>> prefer_int("0") 0 >>> prefer_int("zero") 'zero' >>> # >>> # filter exceptions be ignored >>> # >>> @tolerate(exceptions=(KeyError, ValueError)) ... def force_int(x): ... string_numbers = { ... 'zero': 0, ... 'one': 1, ... 'two': 2, ... 'three': 3, ... 'four': 4, ... 'five': 5, ... 'six': 6, ... 'seven': 7, ... 'eight': 8, ... 'nine': 9 ... } ... if isinstance(x, (int, float)): ... return int(x) ... elif isinstance(x, str): ... if x in string_numbers: ... return string_numbers[x] ... elif x in ('ten', 'hundred', 'thousand'): ... raise KeyError ... raise ValueError ... else: ... raise AttributeError >>> force_int('zero') 0 >>> force_int('ten') is None # KeyError True >>> force_int('foo') is None # ValueError True >>> force_int(object) # AttributeError Traceback (most recent call last): ... AttributeError >>> # >>> # disable tolerance by passing `fail_silently=False` >>> # >>> force_int('ten', fail_silently=False) # KeyError Traceback (most recent call last): ... KeyError >>> # >>> # disable tolerance globally by setting `tolerate.disabled=True` >>> # >>> tolerate.disabled = True >>> force_int('foo') # ValueError Traceback (most recent call last): ... ValueError >>> tolerate.disabled = False # rollback >>> # >>> # Features from Version 0.1.1 >>> # >>> # specify switch as a string >>> parse_int_string = tolerate(switch='patient')(int) >>> parse_int_string('zero') is None True >>> parse_int_string('zero', patient=False) Traceback (most recent call last): ... ValueError: ... >>> # specify switch as a list >>> parse_int_list = tolerate(switch=['fail_silently', False])(int) >>> parse_int_list('zero') Traceback (most recent call last): ... ValueError: ... >>> parse_int_string('zero', fail_silently=True) is None True >>> # specify switch as a dict >>> parse_int_dict = tolerate(switch={'argument_name': 'aggressive', ... 'reverse': True})(int) >>> parse_int_dict('zero') is None True >>> parse_int_dict('zero', aggressive=False) is None True >>> parse_int_dict('zero', aggressive=True) is None Traceback (most recent call last): ... ValueError: ...
functional
Module¶
utils
Module¶
tolerance utility module
-
tolerance.utils.
argument_switch_generator
(argument_name=None, default=True, reverse=False, keep=False)[source]¶ Create switch function which return the status from specified named argument
Parameters: argument_name : string or None
An argument name which is used to judge the status. If
None
is specified, the value oftolerance.utils.DEFAULT_ARGUMENT_NAME
will be used instead.default : boolean
A default value of this switch function. It is used when specifid
**kwargs
does not have named argumentreverse : boolean
Reverse the status (Default:
False
)keep : boolean
If it is
True
, keep named argument in**kwargs
.Returns: function
A switch function which return status, args, and kwargs respectively.
Examples
>>> # >>> # generate switch function with default parameters >>> # >>> fn = argument_switch_generator('fail_silently') >>> # return `default` value and specified *args and **kwargs when >>> # `fail_silently` is not specified in **kwargs >>> fn() == (True, tuple(), {}) True >>> # return `fail_silently` value when it is specified >>> fn(fail_silently=True) == (True, tuple(), {}) True >>> fn(fail_silently=False) == (False, tuple(), {}) True >>> # >>> # generate switch function with `default=False` >>> # >>> fn = argument_switch_generator('fail_silently', default=False) >>> # return `default` value so `False` is returned back >>> fn() == (False, tuple(), {}) True >>> # >>> # generate switch function with `reverse=True` >>> # >>> fn = argument_switch_generator('fail_silently', reverse=True) >>> # `default` value is independent from `reverse=True` >>> fn() == (True, tuple(), {}) True >>> # `fail_silently` value is influenced by `reverse=True` >>> fn(fail_silently=True) == (False, tuple(), {}) True >>> fn(fail_silently=False) == (True, tuple(), {}) True >>> # >>> # generate switch function with `keep=True` >>> # >>> fn = argument_switch_generator('fail_silently', keep=True) >>> # `fail_silently` attribute remains even in returned back kwargs >>> status, args, kwargs = fn(fail_silently=True) >>> 'fail_silently' in kwargs True