code: def fingerprint(self, option_type, option_val):
      
      if option_val is None:
        return None
  
      # Wrapping all other values in a list here allows us to easily handle single-valued and
      # list-valued options uniformly. For non-list-valued options, this will be a singleton list
      # (with the exception of dict, which is not modified). This dict exception works because we do
      # not currently have any "list of dict" type, so there is no ambiguity.
      if not isinstance(option_val, (list, tuple, dict)):
        option_val = [option_val]
  
      if option_type == target_option:
        return self._fingerprint_target_specs(option_val)
      elif option_type == dir_option:
        return self._fingerprint_dirs(option_val)
      elif option_type == file_option:
        return self._fingerprint_files(option_val)
      elif option_type == dict_with_files_option:
        return self._fingerprint_dict_with_files(option_val)
      else:
        return self._fingerprint_primitives(option_val)
docs: Returns a hash of the given option_val based on the option_type.
  
      :API: public
  
      Returns None if option_val is None.