'MemoryViewSliceType(base, axes)
Base is the C base type; axes is a list of (access, packing) strings,
where access is one of \'full\', \'direct\' or \'ptr\' and packing is one of
\'contig\', \'strided\' or \'follow\'.  There is one (access, packing) tuple
for each dimension.
the access specifiers determine whether the array data contains
pointers that need to be dereferenced along that axis when
retrieving/setting:
\'direct\' -- No pointers stored in this dimension.
\'ptr\' -- Pointer stored in this dimension.
\'full\' -- Check along this dimension, don\'t assume either.
the packing specifiers specify how the array elements are layed-out
in memory.
\'contig\' -- The data are contiguous in memory along this dimension.
At most one dimension may be specified as \'contig\'.
\'strided\' -- The data aren\'t contiguous along this dimenison.
\'follow\' -- Used for C/Fortran contiguous arrays, a \'follow\' dimension
has its stride automatically computed from extents of the other
dimensions to ensure C or Fortran memory layout.
C-contiguous memory has \'direct\' as the access spec, \'contig\' as the
*last* axis\' packing spec and \'follow\' for all other packing specs.
Fortran-contiguous memory has \'direct\' as the access spec, \'contig\' as
the *first* axis\' packing spec and \'follow\' for all other packing
specs.'

def __init__(self, base_dtype, axes):

    from . import Buffer, MemoryView
    self.dtype = base_dtype
    self.axes = axes
    self.ndim = len(axes)
    self.flags = MemoryView.get_buf_flags(self.axes)
    (self.is_c_contig, self.is_f_contig) = MemoryView.is_cf_contig(self.axes)
    assert (not (self.is_c_contig and self.is_f_contig))
    self.mode = MemoryView.get_mode(axes)
    self.writable_needed = False
    if (not self.dtype.is_fused):
        self.dtype_name = Buffer.mangle_dtype_name(self.dtype)
