def checktype(value,type_):
"""Check value against the type spec. If everything
is OK, this just returns the value itself.
If the types don't check out, an exception is thrown."""
# True skips any check
if type_ is True:
return value
# types are checked using isinstance
if type(type_)==type:
if not isinstance(value,type_):
raise CheckError("isinstance failed",value,"of type",type(value),"is not of type",type_)
return value
# for a list, check that all elements of a collection have a type
# of some list element, allowing declarations like [str] or [str,unicode]
# no recursive checks right now
if type(type_)==list:
if not numpy.iterable(value):
raise CheckError("expected iterable",value)
for x in value:
if not reduce(max,[isinstance(x,t) for t in type_]):
raise CheckError("element",x,"of type",type(x),"fails to be of type",type_)
return value
# for sets, check membership of the type in the set
if type(type_)==set:
for t in type_:
if isinstance(value,t): return value
raise CheckError("set membership failed",value,type_,var=var) # FIXME var?
# for tuples, check that all conditions are satisfied
if type(type_)==tuple:
for t in type_:
checktype(value,type_)
return value
# callables are just called and should either use assertions or
# explicitly raise CheckError
if callable(type_):
type_(value)
return value
# otherwise, we don't understand the type spec
raise Exception("unknown type spec: %s"%type_)
评论列表
文章目录