These utilities make it straightforward to add basic error checks to methods and functions, typically of arguments. They provide uniform and informative error messages.
Check that len(value) is equal to target. Raises ValueError if it isn’t, or if value doesn’t have the __len__ attribute. name may be used to generate a more useful message.
>>> t = (1, 2, 3)
>>> check_arity(t, 3)
>>> check_arity(t, 2, name='your triple')
Traceback (most recent call last):
...
ValueError: expected your triple to be length 2, got (1, 2, 3)
>>> check_arity(None, 2, name='your triple')
Traceback (most recent call last):
...
ValueError: expected your triple to have the __len__ attribute, got None
Check that len(value) is greater than or equal to target. Raises ValueError if it isn’t, or if value doesn’t have the __len__ attribute. name may be used to generate a more useful message.
>>> t = (1, 2, 3)
>>> check_arity_at_least(t, 3)
>>> t = (1, 2, 3)
>>> check_arity_at_least(t, 2)
>>> check_arity_at_least(t, 4, name='your triple')
Traceback (most recent call last):
...
ValueError: expected your triple to be at least length 4, got (1, 2, 3)
>>> check_arity_at_least(None, 3, name='your triple')
Traceback (most recent call last):
...
ValueError: expected your triple to have the __len__ attribute, got None
Check that value is equal to target. Raises ValueError if it isn’t. name may be used to generate a more useful message.
>>> check_equal(1.0, 1.0)
>>> check_equal(-3, 1)
Traceback (most recent call last):
...
ValueError: expected 1, got -3
>>> check_equal(-3, 10, name='duration')
Traceback (most recent call last):
...
ValueError: expected duration to be 10, got -3
Check that value is greater than threshold.
Raises ValueError if value is not greater than threshold, using optional name in the exception message.
>>> check_greater_than(1.0, 0.0)
>>> check_greater_than(0, -10)
>>> check_greater_than(10, 20, 'count')
Traceback (most recent call last):
...
ValueError: expected count to be to be greater than 20, got 10
Check that value is hashable. Raise a ValueError if it isn’t. name may be used to generate a more useful message.
>>> check_hashable(None)
>>> check_hashable(3)
>>> check_hashable('33')
>>> check_hashable(3.125)
>>> check_hashable((3, '33', 3.1416015625))
>>> check_hashable([3, '33', 3.1416015625], name="your triple")
Traceback (most recent call last):
...
ValueError: expected your triple to be to be hashable, got [3, '33', 3.1416015625]
>>> check_hashable((3, '33', []))
Traceback (most recent call last):
...
ValueError: expected to be hashable, got (3, '33', [])
Check that value is an instance of typ. Raises TypeError if the check fails. Note that typ can be a single type or a tuple of types as per the builtin isinstance(). Optional name, a string, may be used to generate a more useful error message. Optional qualifier, a string is inserted into error message immediately preceding the name of the expected type.
Note
To support use of functools.partial the argument order is the opposite of isinstance().
>>> check_instance(list, list())
>>> check_instance((tuple, list), ())
>>> checkint = functools.partial(check_instance, int)
>>> for i in range(5): checkint(i)
Default failure formatting
>>> for i in range(5): checkint(chr(i))
Traceback (most recent call last):
...
TypeError: expected 'int', got 'str'
More helpful failure formatting
>>> check_instance(list, tuple(), name='dates', qualifier='non-empty ')
Traceback (most recent call last):
...
TypeError: expected dates to be non-empty 'list', got 'tuple'
Failure when a sequence of types is provided
>>> check_instance((tuple, list), dict(), 'arg')
Traceback (most recent call last):
...
TypeError: expected arg to be one of ('tuple', 'list'), got 'dict'
Failure when using collections types:
>>> check_instance(collections.Callable, 'not_callable')
Traceback (most recent call last):
...
TypeError: expected 'Callable', got 'str'
Check that value is integral (equal to an integer). Raises ValueError if it isn’t. Optional name may be given in order to generate a more useful message.
On success, returns the integer to which value is equal.
>>> check_integral(1.0)
1
>>> check_integral(1.125, 'duration')
Traceback (most recent call last):
...
ValueError: expected duration to be an integral value, got 1.125
>>> check_integral('foo')
Traceback (most recent call last):
...
ValueError: expected an integral type, got 'str'
>>> check_integral(None)
Traceback (most recent call last):
...
ValueError: expected an integral type, got 'NoneType'
Check that value is less than threshold.
Raises ValueError if value is not less than threshold, using optional name in the exception message.
>>> check_less_than(0.0, 1.0)
>>> check_less_than(-10, 0)
>>> check_less_than(10, 5, 'count')
Traceback (most recent call last):
...
ValueError: expected count to be to be less than 5, got 10
Check that value is an element of container.
Raises ValueError if value is not not in container, using optional name in the exception message.
Container may be a sequence...
>>> check_membership(1, (1, 2, 3))
... or a set
>>> check_membership(1, set((1, 2, 3)))
... or a dict
>>> check_membership(1, {1: 2, 3: 4})
>>> check_membership(-3, (1, 2, 3), 'count')
Traceback (most recent call last):
...
ValueError: expected count to be in (1, 2, 3), got -3
Check that len(value) is greater than or equal to 0. Raises ValueError if it isn’t, or if value doesn’t have the __len__ attribute. name may be used to generate a more useful message.
>>> t = (1, 2, 3)
>>> check_nonempty(t)
>>> check_nonempty(set(), name='your set')
Traceback (most recent call last):
...
ValueError: expected your set to be non-empty, got set([])
>>> check_nonempty(None, name='your thing')
Traceback (most recent call last):
...
ValueError: expected your thing to have the __len__ attribute, got None
Check that value is a nonempty string. Raises ValueError if it isn’t. Optional name may be given in order to generate a more useful message.
>>> check_nonempty_str('foo', name='string1')
>>> check_nonempty_str(2, name='string2')
Traceback (most recent call last):
...
TypeError: expected string2 to be 'str', got 'int'
Check that value is non-negative.
Raises ValueError if value is not non-negative, using optional name in the exception message.
>>> check_nonnegative(1.0)
>>> check_nonnegative(0)
>>> check_nonnegative(-3, 'count')
Traceback (most recent call last):
...
ValueError: expected count to be a non-negative number, got -3
Check that value is non-negative and integral
Check that value is an existing path in the filesystem. Raises ValueError if it isn’t, or if value isn’t a nonempty string. name may be used to generate a more useful message.
>>> check_path_exists('.')
>>> check_path_exists(1)
Traceback (most recent call last):
...
TypeError: expected 'str', got 'int'
>>> check_path_exists('/I/really/doubt/it/very/much')
Traceback (most recent call last):
...
ValueError: expected a valid path, failed to find path /I/really/doubt/it/very/much
Check that obj can be pickled and unpickled to give an equivalent object. Also checks that the hashability and hash of obj and the unpickled object are equivalent. Optional protocol, default pickle.HIGHEST_PROTOCOL is the pickle protocol to use. Note that some Python constructs, e.g. classes with '__slots__' attribute, will fail to pickle if an old protocol is specified.
By default the function returns None, but if optional return_unpickled is True then the unpickled version of obj will be returned.
Note that unlike most functions in this module, this function is intended to be used during basic tests, and is not intended to be used routinely during object construction.
>>> check_pickle(tuple('abc'))
>>> check_pickle(list('abc'))
>>> check_pickle(tuple('XYZ'), protocol=0)
>>> check_pickle(tuple('XYZ'), protocol=1)
>>> check_pickle(tuple('XYZ'), protocol=2)
Older protocols may not be able to pickle things that newer protocols can
>>> slot_eg = _slots(xrange(5))
>>> slot_eg2 = check_pickle(slot_eg, return_unpickled=True)
>>> slot_eg2._slotness == slot_eg._slotness
True
>>> check_pickle(slot_eg, protocol=0)
Traceback (most recent call last):
...
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled
>>> check_pickle(object())
Traceback (most recent call last):
...
TypeError: pickling-unpickling failed to create equivalent instance of __builtin__.object
>>> check_pickle(_bad_hash('abcd'))
Traceback (most recent call last):
...
TypeError: pickling-unpickling failed to have same hash behavior, instance of __main__._bad_hash
>>> check_pickle(tuple('XYZ'), protocol=2500)
Traceback (most recent call last):
...
ValueError: pickle protocol must be <= ...
Check that value is positive. Raises ValueError if it isn’t. name may be used to generate a more useful message.
>>> check_positive(1.0)
>>> check_positive(-3)
Traceback (most recent call last):
...
ValueError: expected a positive number, got -3
>>> check_positive(-3, name='duration')
Traceback (most recent call last):
...
ValueError: expected duration to be a positive number, got -3
Check that value is positive and integral
Check that s1 == s2. Raise a ValueError if they are not equal.
>>> check_str_equal('abc', 'abc')
>>> check_str_equal('abc', 'abcd')
Traceback (most recent call last):
...
ValueError: expected strings to be equal, found difference in position 3 (None != d)
>>> check_str_equal('this difference is a bit harder to spot', 'this difference is a pit harder to spot')
Traceback (most recent call last):
...
ValueError: expected strings to be equal, found difference in position 21 (b != p)