code: def _resource_source_for_data(self, data):
      data_copy = copy.copy(data)
      type_vals = [
          data_copy.pop(attr, None) for attr in self.source_types
      ]
      type_items = zip(self.source_types, type_vals)
      type_count = sum((bool(val) for val in type_vals))
      if type_count == 0:
          types_desc = ", ".join(self.source_types)
          raise ResourceFormatError(
              f"invalid source {data} in resource '{self.fullname}': "
              f"missing required attribute (one of {types_desc})"
          )
      if type_count > 1:
          conflicting = ", ".join(
              [item[0] for item in type_items if item[1]]
          )
          raise ResourceFormatError(
              f"invalid source {pprint.pformat(data)} in resource "
              f"'{self.fullname}': conflicting attributes ({conflicting})"
          )
      type_name, type_val = next(item for item in type_items if item[1])
      return self._source_for_type(type_name, type_val, data_copy)
  
imports: import collections
  import copy
  import logging
  import operator
  import pprint
  from guild import util
label_desc: Use image node_id 6 for calling the ResourceDef obj's underlying member method code with example usage: obj._resource_source_for_data(data) and returns: self