def _typecheck1 (object, spec): if type(spec) is type: return type(object) is spec elif type(spec) is list: for s in spec: if _typecheck1(object, s): return True return False elif type(spec) is tuple: if spec[0] == tuple: if type(object) is not tuple or len(object) != len(spec)-1: return False for o, s in zip(object, spec[1:]): if not _typecheck1(o, s): return False return True elif spec[0] == list: if type(object) is not list or\ (len(spec) >= 3 and len(object) < spec[2]) or\ (len(spec) >= 4 and len(object) > spec[3]): return False for o in object: if not _typecheck1(o, spec[1]): return False return True elif spec[0] == dict: if type(object) is not dict: return False for (k, v) in object.items(): if not _typecheck1(k, spec[1]): return False if not _typecheck1(v, spec[2]): return False return True else: return False else: return False def _formatSpec (spec): if type(spec) is type: return str(spec) elif type(spec) is list: m = "" for s in spec: if m != "": m += " or " m += _formatSpec(s) return m elif type(spec) is tuple: if spec[0] == tuple: m = "" for s in spec[1:]: if m != "": m += ", " m += _formatSpec(s) return "tuple (" + m + ")" elif spec[0] == list: m = "list" if len(spec) >= 3: m += " " + str(spec[2]) + ".." if len(spec) >= 4: m += str(spec[3]) else: m += "*" return m + " [" + _formatSpec(spec[1]) + "]" elif spec[0] == dict: return "dictionary {" + _formatSpec(spec[1]) + " : " +\ _formatSpec(spec[2]) + "}" else: return "?" else: return "?" def _typecheck (argNum, object, spec): if __debug__: if not _typecheck1(object, spec): if argNum > 0: m = "argument " + str(argNum) + ": " else: m = "" raise TypeError, m + "expecting " + _formatSpec(spec)