docs: def _MI_init(self, *args, **kw):
      '''
      Separate __init__ function of MIMapping
      '''
  
      items, names = [], None
  
      n_args = len(args)
  
      if n_args >= 1:
          items = args[0]
  
          if isinstance(items, Mapping):  # copy from dict
              if isinstance(items, MIMapping):
                  names = force_list(items.indices.keys())  # names may be overwritten by second arg
              items = force_list(items.items())
          else:  # try to get data from items() or keys() method
              if hasattr(items, 'items'):
                  try:
                      items = force_list(items.items())
                  except TypeError:  # items() may be not callalbe
                      pass
              else:
                  items = cvt_iter(items)
  
      if n_args >= 2:
          names = args[1] # may be None
          names = cvt_iter(names)
  
      if n_args >= 3:
          raise TypeError('At most 2 positional arguments allowed (%s given)' % n_args)
  
      if items:  # check item length
          n_index = len(items[0])
          for item in items[1:]:
              if len(item) != n_index:
                  raise ValueError('Length of all items must equal')
      else:
          n_index = 0
  
      if kw:
          if n_index == 0:
              n_index = 2
          else:
              if n_index != 2:
                  raise ValueError('Number of indices must be 2 (got %s) '
                                   'when keyword arguments are used' % n_index)
          items.extend(kw.items())
  
      if n_index > 0:
          if names is not None:
              if len(names) != n_index:
                  raise ValueError('Length of names (%s) does not match '
                                   'length of items (%s)' % (len(names), n_index))
  
      if names is None:  # generate default names
          names = ['index_%s' % (i+1) for i in range(n_index)] # starts from index_1
      else:
          map(MI_check_index_name, names)
  
      self.indices = d = IdxOrdDict() # the internal dict
      for index in names:
          if index in d:
              raise ValueError('Duplicate index name: %s in %s' % (index, names))
          d[index] = AttrOrdDict()
  
      if n_index > 0:
          d[0] = self
          for item in items:
              primary_key = item[0]
              if n_index == 1:
                  value = primary_key
              elif n_index == 2:
                  value = item[1]
              else:
                  value = list(item[1:]) # copy
              # will handle duplicate
              _MI_setitem(self, primary_key, value)