'Analyse buffer indexing and memoryview indexing/slicing'

def analyse_as_buffer_operation(self, env, getting):

    if isinstance(self.index, TupleNode):
        indices = self.index.args
    else:
        indices = [self.index]
    base_type = self.base.type
    replacement_node = None
    if base_type.is_memoryviewslice:
        from . import MemoryView
        (have_slices, indices, newaxes) = MemoryView.unellipsify(indices, base_type.ndim)
        if have_slices:
            replacement_node = MemoryViewSliceNode(self.pos, indices=indices, base=self.base)
        else:
            replacement_node = MemoryViewIndexNode(self.pos, indices=indices, base=self.base)
    elif (base_type.is_buffer or base_type.is_pythran_expr):
        if (base_type.is_pythran_expr or (len(indices) == base_type.ndim)):
            is_buffer_access = True
            indices = [index.analyse_types(env) for index in indices]
            if base_type.is_pythran_expr:
                do_replacement = all(((index.type.is_int or index.is_slice or index.type.is_pythran_expr) for index in indices))
                if do_replacement:
                    for (i, index) in enumerate(indices):
                        if index.is_slice:
                            index = SliceIntNode(index.pos, start=index.start, stop=index.stop, step=index.step)
                            index = index.analyse_types(env)
                            indices[i] = index
            else:
                do_replacement = all((index.type.is_int for index in indices))
            if do_replacement:
                replacement_node = BufferIndexNode(self.pos, indices=indices, base=self.base)
                assert (not isinstance(self.index, CloneNode))
    if (replacement_node is not None):
        replacement_node = replacement_node.analyse_types(env, getting)
    return replacement_node
