docstr: For each key K in `candidate_kvs`, if K is found in
  self.input_types, perform the following:
  
  - check that candidate_kvs[K] is a Var and satisfies
  requirements in InputType (const, types)
  - Place K, candidate_kvs[K] in output (list of (name, var) pairs).
  
  Note that this does not ensure the presence of all required
  input_spec (optional == False).
  
  Parameters
  ----------
  - op_name: str
  
  - op_type: str
  
  - candidate_kvs: Dict[str, Var]
    Values cannot be None
  
  Return
  ------
  None
  
  Raise:
      ValueErrr if value type is incompatible
docstr_tok: ["For","each","key","K","in","`","candidate_kvs","`",",","if","K","is","found","in","self.input_types",",","perform","the","following",":","-","check","that","candidate_kvs","[","K","]","is","a","Var","and","satisfies","requirements","in","InputType","(","const",",","types",")","-","Place","K",",","candidate_kvs","[","K","]","in","output","(","list","of","(","name",",","var",")","pairs",")",".","Note","that","this","does","not","ensure","the","presence","of","all","required","input_spec","(","optional","==","False",")",".","Parameters","--","--","--","--","--","-","op_name",":","str","-","op_type",":","str","-","candidate_kvs",":","Dict","[","str",",","Var","]","Values","can","not","be","None","Return","--","--","--","None","Raise",":","ValueErrr","if","value","type","is","incompatible"]
code: def validate_inputs(self, op_name, op_type, candidate_kvs):
      """
      For each key K in `candidate_kvs`, if K is found in
      self.input_types, perform the following:
  
      - check that candidate_kvs[K] is a Var and satisfies
      requirements in InputType (const, types)
      - Place K, candidate_kvs[K] in output (list of (name, var) pairs).
  
      Note that this does not ensure the presence of all required
      input_spec (optional == False).
  
      Parameters
      ----------
      - op_name: str
  
      - op_type: str
  
      - candidate_kvs: Dict[str, Var]
        Values cannot be None
  
      Return
      ------
      None
  
      Raise:
          ValueErrr if value type is incompatible
      """
      msg_prefix = 'Op "{}" (op_type: {}) '.format(op_name, op_type)
  
      # check vars sharing the same type_domain_id have the same dtype
      type_domain_group = {}
      var_to_input_name = {}
      for name, var in candidate_kvs.items():
          input_type = self.input_types[name]
          if (
              isinstance(input_type, TensorInputType)
              and input_type.type_domain_id is not None
          ):
              type_domain_id = input_type.type_domain_id
              if type_domain_id in type_domain_group:
                  type_domain_group[type_domain_id].append(var)
              else:
                  type_domain_group[type_domain_id] = [var]
              var_to_input_name[var] = name
  
      for type_domain_id, vars in type_domain_group.items():
          expected_dtype = vars[0].dtype
          ref_name = var_to_input_name[vars[0]]
          for var in vars:
              name = var_to_input_name[var]
              if not var.dtype == expected_dtype:
                  msg = (
                      "In op, of type {}, named {}, the named input `{}` must have the same data type "
                      "as the named input `{}`. However, {} has dtype {} whereas {} has dtype {}."
                  ).format(
                      op_type,
                      op_name,
                      name,
                      ref_name,
                      name,
                      var.dtype.__type_info__(),
                      ref_name,
                      expected_dtype.__type_info__(),
                  )
                  raise ValueError(msg)
  
      # Ensure candidate_kvs doesn't contain None
      for name, var in candidate_kvs.items():
          if var is None:
              raise ValueError(
                  msg_prefix + "Input {} is None".format(name)
              )
  
          if name not in self.input_types:
              raise ValueError(
                  msg_prefix + "Unrecognized input {}".format(name)
              )
  
          input_type = self.input_types[name]
          # Check constness
          # Don't check InternalInputType (so _const_symbolic can work)
          if (
              input_type.const
              and not isinstance(input_type, InternalInputType)
              and not var.is_descendant_of_const
          ):
              msg = (
                  msg_prefix + "Input {} must be const at compile time"
              )
              raise ValueError(msg.format(name), name, var.name)
  
          if not isinstance(
              var, InternalVar
          ) and not input_type.is_compatible(var):
              msg = (
                  msg_prefix
                  + 'Input {}="{}" expects '
                  + "{} but got {}"
              )
              raise ValueError(
                  msg.format(
                      name,
                      var.name,
                      input_type.type_str,
                      var.sym_type.__type_info__(),
                  )
              )
  
imports: from collections import OrderedDict
  from coremltools.converters.mil.mil import types
  from coremltools.converters.mil.mil.var import InternalVar
label_desc: Use image node_id 4 for calling the InputSpec obj's underlying member method code with example usage: obj.validate_inputs(op_name, op_type, candidate_kvs) without return types