 except IndexError:
            debug.warning('No param #%s found for annotation %s', index, self)
            return NO_VALUES

    def get_type_hint(self):
        return '[%s]' % ', '.join(t.get_type_hint(add_class_info=False) for t in self.to_tuple())


class LazyGenericManager(_AbstractGenericManager):
    def __init__(self, context_of_index, index_value):
        self._context_of_index = context_of_index
        self._index_value = index_value

    @memoize_method
    def __getitem__(self, index):
        return self._tuple()[index]()

    def __len__(self):
        return len(self._tuple())

    @memoize_method
    @to_tuple
    def _tuple(self):
        def lambda_scoping_in_for_loop_sucks(lazy_value):
            return lambda: ValueSet(_resolve_forward_references(
                self._context_of_index,
                lazy_value.infer()
            ))

        if isinstance(self._index_value, SequenceLiteralValue):
            for lazy_value in self._index_value.py__iter__(contextualized_node=None):
                yield lambda_scoping_in_for_loop_sucks(lazy_value)
        else:
            yield lambda: ValueSet(_resolve_forward_references(
                self._context_of_index,
                ValueSet([self._index_value])
            ))

    @to_tuple
    def to_tuple(self):
        for callable_ in self._tuple():
            yield callable_()

    def is_homogenous_tuple(self):
        if isinstance(self._index_value, SequenceLiteralValue):
            entries = self._index_value.get_tree_entries()
            if len(entries) == 2 and entries[1] == '...':
                return True
        return False

    def __repr__(self):
        return '<LazyG>[%s]' % (', '.join(repr(x) for x in self.to_tuple()))


class TupleGenericManager(_AbstractGenericManager):
    def __init__(self, tup):
        self._tuple = tup

    def __getitem__(self, index):
        return self._tuple[index]

    def __len__(self):
        return len(self._tuple)

    def to_tuple(self):
        return self._tuple

    def is_homogenous_tuple(self):
        return False

    def __repr__(self):
        return '<TupG>[%s]' % (', '.join(repr(x) for x in self.to_tuple()))
PK