Package translate :: Package misc :: Package typecheck :: Module mixins
[hide private]
[frames] | no frames]

Source Code for Module translate.misc.typecheck.mixins

 1  from translate.misc.typecheck import _TC_NestedError, _TC_TypeError, check_type, Or 
 2  from translate.misc.typecheck import register_type, _TC_Exception 
3 4 -class _TC_IterationError(_TC_NestedError):
5 - def __init__(self, iteration, value, inner_exception):
6 _TC_NestedError.__init__(self, inner_exception) 7 8 self.iteration = iteration 9 self.value = value
10
11 - def error_message(self):
12 return ("at iteration %d (value: %s)" % (self.iteration, repr(self.value))) + _TC_NestedError.error_message(self)
13
14 ### This is the shadow class behind UnorderedIteratorMixin. 15 ### Again, it tries to pretend it doesn't exist by mimicing 16 ### the class of <obj> as much as possible. 17 ### 18 ### This mixin provides typechecking for iterator classes 19 ### where you don't care about the order of the types (ie, 20 ### you simply Or() the types together, as opposed to patterned 21 ### lists, which would be ordered mixins) 22 -class _UnorderedIteratorMixin(object):
23 - def __init__(self, class_name, obj):
24 vals = [o for o in obj] 25 26 self.type = self 27 self._type = Or(*vals) 28 self.__cls = obj.__class__ 29 self.__vals = vals 30 # This is necessary because it's a huge pain in the ass 31 # to get the "raw" name of the class once it's created 32 self.__cls_name = class_name
33
34 - def __typecheck__(self, func, to_check):
35 if not isinstance(to_check, self.__cls): 36 raise _TC_TypeError(to_check, self) 37 38 for i, item in enumerate(to_check): 39 try: 40 check_type(self._type, func, item) 41 except _TC_Exception, e: 42 raise _TC_IterationError(i, item, e)
43 44 @classmethod
45 - def __typesig__(cls, obj):
46 if isinstance(obj, cls): 47 return obj
48
49 - def __str__(self):
50 return "%s(%s)" % (self.__cls_name, str(self._type))
51 52 __repr__ = __str__
53
54 ### This is included in a class's parent-class section like so: 55 ### class MyClass(UnorderedIteratorMixin("MyClass")): 56 ### blah blah blah 57 ### 58 ### This serves as a class factory, whose produced classes 59 ### attempt to mask the fact they exist. Their purpose 60 ### is to redirect __typesig__ calls to appropriate 61 ### instances of _UnorderedIteratorMixin 62 -def UnorderedIteratorMixin(class_name):
63 class UIM(object): 64 @classmethod 65 def __typesig__(cls, obj): 66 if isinstance(obj, cls): 67 return _UnorderedIteratorMixin(class_name, obj)
68 69 def __repr__(self): 70 return "%s%s" % (class_name, str(tuple(e for e in self))) 71 72 # We register each produced class anew 73 # If someone needs to unregister these classes, they should 74 # save a copy of it before including it in the class-definition: 75 # 76 # my_UIM = UnorderedIteratorMixin("FooClass") 77 # class FooClass(my_UIM): 78 # ... 79 # 80 # Alternatively, you could just look in FooClass.__bases__ later; whatever 81 register_type(UIM) 82 return UIM 83 84 register_type(_UnorderedIteratorMixin) 85