translate.misc.typecheck.mixins

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