Typechecking with assert_type
Recently when pondering the question of when it would or would not be appropriate to put in type assertions to help catch bugs, I concluded that it makes the most sense to do so when building a data structure, but not when just passing things around between calls.
The most difficult-to-debug type errors are the ones where you've put something of the wrong type into a data structure, and it's sat there for a while not causing any obvious problem until something else tries to use it, by which time most evidence of where it came from is gone.
Inspired by this remark on the python-3000 mailing list, we bring you typecheck.assert_type.
This function can be used to do in-code typechecking (as opposed to decorator-based typechecking, e.g., accepts, returns, etc).
assert_type is intended to help you debug a subtle class of errors: accidental corruption of data structures (for example, inserting the wrong kind of key/value pair into a dictionary).
You use it like so:
from typecheck import assert_type
my_dict = dict()
# manipulate
# manipulate
# pass my_dict to some other functions
# manipulate
assert_type({str: (int, int, int)}, my_dict)
In this example, if my_dict's values are not 3-tuples of integers, assert_type will raise an AssertionError.
Why would you want to use assert_type instead of the typechecking decorators?
Simple efficiency. assert_type can be used to do typechecking only after you've completed a batch of changes, or only when you know that you've changed a data structure (instead of checking an unchanged structure over and over again).
Notes:
-
A word on why
assert_typetakes its parameters in the order it does. We chose to pass the expected type as the first parameter so thatassert_typecan be easily used with partial function application tools, allow you to do things like this:check_my_type = partial(assert_type, {str: (int, int, int)}) check_my_dict_type(my_dict_1) check_my_dict_type(my_dict_2)The
partialfunction is available from the built-infunctoolsmodule in Python 2.5 or from the functional package (available for all Python versions >= 2.3). -
You might be asking yourself, "why combine an
assertstatement with a typechecking function, instead of allowing the programmer to writeassert check_type(...)?"Good question. The main motivation behind combining these two functionalities is to preserve the detailed error messages produced by the typechecking machinery. If we had relied on the simple
assertstatement, that debugging information would be lost.