|
Type Assertions in Python
Python is a dynamically typed
language, meaning that it is not necessary to declare the types of
variables. This makes Python programs concise and easy to write, but
when writing significant code in Python I find myself wanting type
declarations both as documentation and as runtime sanity checks.
Here's a simple way to add type declarations to Python in the form
of runtime assertions. An object's type is declared by calling a
function
_typecheck(argNum,
object, typespec)
where object is the Python object to check and
typespec is a type specification (defined below).
argNum, if positive, is used in formatting error messages. For
example, assuming the __debug__ system variable is
True,
_typecheck(1, myVar, int)
checks that myVar is an integer. If it's not, an
exception is raised:
TypeError: argument 1: expecting <type 'int'>
That's all there is to it. The nifty part is that type
specifications are pretty flexible, being similar to Common Lisp
type specifiers, which nicely correlates with the kinds of
flexible data structures one typically encounters in Python. A type
specification can be:
- A simple type:
int, str,
bool, types.FunctionType, etc.
- A list of type specifications, which describes a union of types.
For example,
[int, str, types.NoneType]
describes a quantity that can be an integer, a string, or
None.
- A tuple of the form
(tuple, typespec1,
typespec2, ...)
which describes a tuple and the types of the tuple's elements. For
example,
(tuple, int, str)
describes a 2-element tuple consisting of an integer and a
string.
- A tuple of one of the forms
(list, typespec)
(list, typespec,
min)
(list, typespec, min,
max)
which describes a list, the type of the list's elements, and optional
constraints on the length of the list. For example,
(list, int, 3, 5)
describes a list of between 3 and 5 integers.
- A tuple of the form
(dict, typespeckey,
typespecvalue)
which describes a dictionary and the types of the dictionary's keys
and values. For example,
(dict, int, str)
describes a dictionary that maps integers to strings.
- Any combination of the above. For example,
[(list, (tuple, int, str), 1), types.NoneType]
describes a quantity that can be either 1) a list of at least one
element, each of which is a 2-tuple consisting of an integer and a
string; or 2) None.
Here's the code: typecheck.py
Greg
Janée
Created: 2005-02-07
Last modified: 2005-02-07 14:14
|