code: def valid_memslice_dtype(dtype, i=0):
      """
      Return whether type dtype can be used as the base type of a
      memoryview slice.
  
      We support structs, numeric types and objects
      """
      if dtype.is_complex and dtype.real_type.is_int:
          return False
  
      if dtype is PyrexTypes.c_bint_type:
          return False
  
      if dtype.is_struct and dtype.kind == "struct":
          for member in dtype.scope.var_entries:
              if not valid_memslice_dtype(member.type):
                  return False
  
          return True
  
      return (
          dtype.is_error
          or
          # Pointers are not valid (yet)
          # (dtype.is_ptr and valid_memslice_dtype(dtype.base_type)) or
          (
              dtype.is_array
              and i < 8
              and valid_memslice_dtype(dtype.base_type, i + 1)
          )
          or dtype.is_numeric
          or dtype.is_pyobject
          or dtype.is_fused
          or (  # accept this as it will be replaced by specializations later
              dtype.is_typedef
              and valid_memslice_dtype(dtype.typedef_base_type)
          )
      )
  
imports: from __future__ import absolute_import
  from .Errors import CompileError, error
  from .None import ExprNodes
  from .ExprNodes import IntNode, NameNode, AttributeNode
  from .None import Options
  from .Code import UtilityCode, TempitaUtilityCode
  from .UtilityCode import CythonUtilityCode
  from .None import Buffer
  from .None import PyrexTypes
  from .None import ModuleNode
label_desc: Use image node_id 8 for calling a global function with example usage: valid_memslice_dtype(dtype, i) and returns: unknown, False, False, True, False