docs: def _deserialize(
          self, data, fields_dict, error_store, many=False, partial=False,
          unknown=RAISE, dict_class=dict, index_errors=True, index=None,
      ):
          """Deserialize ``data`` based on the schema defined by ``fields_dict``.
  
          :param dict data: The data to deserialize.
          :param dict fields_dict: Mapping of field names to :class:`Field` objects.
          :param ErrorStore error_store: Structure to store errors.
          :param bool many: Set to `True` if ``data`` should be deserialized as
              a collection.
          :param bool|tuple partial: Whether to ignore missing fields and not require
              any fields declared. Propagates down to ``Nested`` fields as well. If
              its value is an iterable, only missing fields listed in that iterable
              will be ignored. Use dot delimiters to specify nested fields.
          :param unknown: Whether to exclude, include, or raise an error for unknown
              fields in the data. Use `EXCLUDE`, `INCLUDE` or `RAISE`.
          :param type dict_class: Dictionary class used to construct the output.
          :param bool index_errors: Whether to store the index of invalid items in
              ``self.errors`` when ``many=True``.
          :param int index: Index of the item being serialized (for storing errors) if
              serializing a collection, otherwise `None`.
          :return: A dictionary of the deserialized data.
          """
          index = index if index_errors else None
          if many:
              if not is_collection(data):
                  error_store.store_error([self.error_messages['type']], index=index)
                  ret = []
              else:
                  self._pending = True
                  ret = [
                      self._deserialize(
                          d, fields_dict, error_store, many=False,
                          partial=partial, unknown=unknown,
                          dict_class=dict_class, index=idx,
                          index_errors=index_errors,
                      )
                      for idx, d in enumerate(data)
                  ]
                  self._pending = False
              return ret
          ret = dict_class()
          # Check data is a dict
          if not isinstance(data, Mapping):
              error_store.store_error([self.error_messages['type']], index=index)
          else:
              partial_is_collection = is_collection(partial)
              for attr_name, field_obj in iteritems(fields_dict):
                  if field_obj.dump_only:
                      continue
                  field_name = attr_name
                  if field_obj.data_key:
                      field_name = field_obj.data_key
                  raw_value = data.get(field_name, missing)
                  if raw_value is missing:
                      # Ignore missing field if we're allowed to.
                      if (
                          partial is True or
                          (partial_is_collection and attr_name in partial)
                      ):
                          continue
                  d_kwargs = {}
                  if isinstance(field_obj, Nested):
                      # Allow partial loading of nested schemas.
                      if partial_is_collection:
                          prefix = field_name + '.'
                          len_prefix = len(prefix)
                          sub_partial = [f[len_prefix:]
                                         for f in partial if f.startswith(prefix)]
                      else:
                          sub_partial = partial
                      d_kwargs['partial'] = sub_partial
                  getter = lambda val: field_obj.deserialize(
                      val, field_name,
                      data, **d_kwargs
                  )
                  value = self._call_and_store(
                      getter_func=getter,
                      data=raw_value,
                      field_name=field_name,
                      error_store=error_store,
                      index=index,
                  )
                  if value is not missing:
                      key = fields_dict[attr_name].attribute or attr_name
                      set_value(ret, key, value)
              if unknown != EXCLUDE:
                  fields = {
                      field_obj.data_key or field_name
                      for field_name, field_obj in fields_dict.items()
                      if not field_obj.dump_only
                  }
                  for key in set(data) - fields:
                      value = data[key]
                      if unknown == INCLUDE:
                          set_value(ret, key, value)
                      elif unknown == RAISE:
                          error_store.store_error(
                              [self.error_messages['unknown']],
                              key,
                              (index if index_errors else None),
                          )
          return ret