docs: def set(self, value):
          """Set a GValue.
  
          The value is converted to the type of the GValue, if possible, and
          assigned.
  
          """
  
          # logger.debug('GValue.set: value = %s', value)
  
          gtype = self.gvalue.g_type
          fundamental = gobject_lib.g_type_fundamental(gtype)
  
          if gtype == GValue.gbool_type:
              gobject_lib.g_value_set_boolean(self.gvalue, value)
          elif gtype == GValue.gint_type:
              gobject_lib.g_value_set_int(self.gvalue, int(value))
          elif gtype == GValue.guint64_type:
              gobject_lib.g_value_set_uint64(self.gvalue, value)
          elif gtype == GValue.gdouble_type:
              gobject_lib.g_value_set_double(self.gvalue, value)
          elif fundamental == GValue.genum_type:
              gobject_lib.g_value_set_enum(self.gvalue,
                                           GValue.to_enum(gtype, value))
          elif fundamental == GValue.gflags_type:
              gobject_lib.g_value_set_flags(self.gvalue, value)
          elif gtype == GValue.gstr_type:
              gobject_lib.g_value_set_string(self.gvalue, _to_bytes(value))
          elif gtype == GValue.refstr_type:
              vips_lib.vips_value_set_ref_string(self.gvalue, _to_bytes(value))
          elif fundamental == GValue.gobject_type:
              gobject_lib.g_value_set_object(self.gvalue, value.pointer)
          elif gtype == GValue.array_int_type:
              if isinstance(value, numbers.Number):
                  value = [value]
  
              array = ffi.new('int[]', value)
              vips_lib.vips_value_set_array_int(self.gvalue, array, len(value))
          elif gtype == GValue.array_double_type:
              if isinstance(value, numbers.Number):
                  value = [value]
  
              array = ffi.new('double[]', value)
              vips_lib.vips_value_set_array_double(self.gvalue, array,
                                                   len(value))
          elif gtype == GValue.array_image_type:
              if isinstance(value, pyvips.Image):
                  value = [value]
  
              vips_lib.vips_value_set_array_image(self.gvalue, len(value))
              array = vips_lib.vips_value_get_array_image(self.gvalue, ffi.NULL)
              for i, image in enumerate(value):
                  gobject_lib.g_object_ref(image.pointer)
                  array[i] = image.pointer
          elif gtype == GValue.blob_type:
              # we need to set the blob to a copy of the string that vips_lib
              # can own
              memory = glib_lib.g_malloc(len(value))
              ffi.memmove(memory, value, len(value))
  
              # this is horrible!
              #
              # * in API mode, we must have 8.6+ and use set_blob_free to
              #   attach the metadata to avoid leaks
              # * pre-8.6, we just pass a NULL free pointer and live with the
              #   leak
              #
              # this is because in API mode you can't pass a builtin (what
              # vips_lib.g_free() becomes) as a parameter to ffi.callback(), and
              # vips_value_set_blob() needs a callback for arg 2
              #
              # additionally, you can't make a py def which calls g_free() and
              # then use the py def in the callback, since libvips will trigger
              # these functions during cleanup, and py will have shut down by
              # then and you'll get a segv
  
              if at_least_libvips(8, 6):
                  vips_lib.vips_value_set_blob_free(self.gvalue,
                                                    memory, len(value))
              else:
                  if pyvips.API_mode:
                      vips_lib.vips_value_set_blob(self.gvalue,
                                                   ffi.NULL, memory, len(value))
                  else:
                      vips_lib.vips_value_set_blob(self.gvalue,
                                                   glib_lib.g_free,
                                                   memory, len(value))
          else:
              raise Error('unsupported gtype for set {0}, fundamental {1}'.
                          format(type_name(gtype), type_name(fundamental)))