docs: def get_value(self, source):
      """Apply self.convert to the source. The parameter passed to convert depends on
      self.source_name. If source_name is given, self.convert(getattr(source, source_name)) is called,
      otherwise self.convert(source) is called.
      """
      if self.source_name is None:
        present, value = True, self.convert(source)
        converted = True
      else:
        present, value = has_value(source, self.source_name)
        converted = False
  
      if not present or value is None:
        if self.is_required:
          raise ValueError("required value not present")
        else:
          return None
      else:
        if converted:
          return value
        else:
          return self.convert(value)