def setUp(self): from typecheck import register_type, _TC_TypeError, unregister_type import types class ExactValue(object): def __init__(self, value): self.type = value def __typecheck__(self, func, to_check): if to_check != self.type: raise _TC_TypeError(to_check, self.type) @classmethod def __typesig__(cls, obj): # Note that you can either include this test # or your classes (like ExactValue) can inherit # from CheckType; either works, but you have # to do one or the other. if isinstance(obj, cls): return obj if isinstance(obj, int): return cls(obj) self.ExactValue = ExactValue register_type(ExactValue)
def UnorderedIteratorMixin(class_name): class UIM(object): @classmethod def __typesig__(cls, obj): if isinstance(obj, cls): return _UnorderedIteratorMixin(class_name, obj) def __repr__(self): return "%s%s" % (class_name, str(tuple(e for e in self))) # We register each produced class anew # If someone needs to unregister these classes, they should # save a copy of it before including it in the class-definition: # # my_UIM = UnorderedIteratorMixin("FooClass") # class FooClass(my_UIM): # ... # # Alternatively, you could just look in FooClass.__bases__ later; whatever register_type(UIM) return UIM
pat_len = len(self._types) for i, val in enumerate(to_check): type = self._types[i % pat_len] try: check_type(type, func, val) except _TC_Exception, e: raise _TC_IndexError(i, e) @classmethod def __typesig__(cls, obj): if isinstance(obj, list) and len(obj) > 1: return cls(*obj) register_type(PatternList) class Length(TypeAnnotation): def __init__(self, length): self.type = self self._length = int(length) def __hash__(self): return hash(str(self.__class__) + str(self._length)) def __eq__(self, other): if self.__class__ is not other.__class__: return False return self._length == other._length
self.right = right def __str__(self): if self.left is None and self.right is None: return "Tree(%s)" % str(self.val) return "Tree(%s, %s, %s)" % (str(self.val), str(self.left), str(self.right)) __repr__ = __str__ @classmethod def __typesig__(cls, obj): if isinstance(obj, cls): if obj.left is None and obj.right is None: return TreeType(obj.val) register_type(Tree) register_type(TreeType) @typecheck_args(Tree(int)) def preorder(tree): l = [tree.val] if tree.left is not None: l.extend(preorder(tree.left)) if tree.right is not None: l.extend(preorder(tree.right)) return l self.Tree = Tree self.preorder = preorder self._TC_TreeChildTypeError = _TC_TreeChildTypeError
### blah blah blah ### ### This serves as a class factory, whose produced classes ### attempt to mask the fact they exist. Their purpose ### is to redirect __typesig__ calls to appropriate ### instances of _UnorderedIteratorMixin def UnorderedIteratorMixin(class_name): class UIM(object): @classmethod def __typesig__(cls, obj): if isinstance(obj, cls): return _UnorderedIteratorMixin(class_name, obj) def __repr__(self): return "%s%s" % (class_name, str(tuple(e for e in self))) # We register each produced class anew # If someone needs to unregister these classes, they should # save a copy of it before including it in the class-definition: # # my_UIM = UnorderedIteratorMixin("FooClass") # class FooClass(my_UIM): # ... # # Alternatively, you could just look in FooClass.__bases__ later; whatever register_type(UIM) return UIM register_type(_UnorderedIteratorMixin)
def test_double_register(self): from typecheck import register_type register_type(self.ExactValue)
raise _TC_LengthError(len(to_check), 0) for obj in to_check: error = False for type in self._types: try: check_type(type, func, obj) except _TC_Exception: error = True continue else: error = False break if error: raise _TC_KeyError(obj, _TC_TypeError(obj, self._type)) def __eq__(self, other): if self.__class__ is not other.__class__: return False return self.type == other.type def __hash__(self): return hash(str(hash(self.__class__)) + str(hash(frozenset(self.type)))) @classmethod def __typesig__(self, obj): if isinstance(obj, set): return Set(obj) register_type(Set)
class TypeCheckedTree(TestCase): def setUp(self): from typecheck import accepts, register_type from typecheck import _TC_Exception, Type from typecheck import _TC_NestedError, _TC_TypeError class _TC_TreeChildTypeError(_TC_NestedError): def __init__(self, child, inner_exception): _TC_NestedError.__init__(self, inner_exception) self.child = child def error_message(self): return ("in the %s child" % self.child) + _TC_NestedError.error_message(self) class TreeType(object): def __init__(self, val): self._type = Type(val) self.type = self def __typecheck__(self, func, to_check): if not isinstance(to_check, Tree): raise _TC_TypeError(to_check, self._type) try: typecheck.check_type(self._type, func, to_check.val) except _TC_Exception: raise _TC_TypeError(to_check.val, self._type.type) for side in ('right', 'left'): child = getattr(to_check, side) if child is not None: try: typecheck.check_type(self, func, child) except _TC_Exception, e: raise _TC_TreeChildTypeError(side, e) @classmethod def __typesig__(cls, obj): if isinstance(obj, cls): return obj def __str__(self): return "Tree(%s)" % str(self._type) __repr__ = __str__ class Tree(object): def __init__(self, val, left=None, right=None): self.val = val self.left = left self.right = right def __str__(self): if self.left is None and self.right is None: return "Tree(%s)" % str(self.val) return "Tree(%s, %s, %s)" % (str(self.val), str( self.left), str(self.right)) __repr__ = __str__ @classmethod def __typesig__(cls, obj): if isinstance(obj, cls): if obj.left is None and obj.right is None: return TreeType(obj.val) register_type(Tree) register_type(TreeType) @accepts(Tree(int)) def preorder(tree): l = [tree.val] if tree.left is not None: l.extend(preorder(tree.left)) if tree.right is not None: l.extend(preorder(tree.right)) return l self.Tree = Tree self.preorder = preorder self._TC_TreeChildTypeError = _TC_TreeChildTypeError
### class MyClass(UnorderedIteratorMixin("MyClass")): ### blah blah blah ### ### This serves as a class factory, whose produced classes ### attempt to mask the fact they exist. Their purpose ### is to redirect __typesig__ calls to appropriate ### instances of _UnorderedIteratorMixin def UnorderedIteratorMixin(class_name): class UIM(object): @classmethod def __typesig__(cls, obj): if isinstance(obj, cls): return _UnorderedIteratorMixin(class_name, obj) def __repr__(self): return "%s%s" % (class_name, str(tuple(e for e in self))) # We register each produced class anew # If someone needs to unregister these classes, they should # save a copy of it before including it in the class-definition: # # my_UIM = UnorderedIteratorMixin("FooClass") # class FooClass(my_UIM): # ... # # Alternatively, you could just look in FooClass.__bases__ later; whatever register_type(UIM) return UIM register_type(_UnorderedIteratorMixin)