After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 610863 - add GParamSpecVariant
add GParamSpecVariant
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: gobject
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2010-02-23 17:50 UTC by Christian Persch
Modified: 2010-06-17 19:10 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
patch series (28.83 KB, patch)
2010-02-23 17:50 UTC, Christian Persch
none Details | Review
updated patch (11.01 KB, patch)
2010-03-07 13:19 UTC, Christian Persch
none Details | Review
complete patch (11.67 KB, patch)
2010-03-07 14:11 UTC, Christian Persch
needs-work Details | Review
Add GParamSpecVariant (11.18 KB, patch)
2010-06-16 17:23 UTC, Christian Persch
none Details | Review
rebase (11.67 KB, patch)
2010-06-16 20:21 UTC, Allison Karlitskaya (desrt)
none Details | Review
Add fundamental type for GVariant (16.30 KB, patch)
2010-06-17 13:33 UTC, Christian Persch
none Details | Review
Add fundamental type and pspec for GVariant (23.70 KB, patch)
2010-06-17 16:12 UTC, Christian Persch
none Details | Review
Add fundamental type and pspec for GVariant (25.44 KB, patch)
2010-06-17 17:41 UTC, Christian Persch
none Details | Review

Description Christian Persch 2010-02-23 17:50:53 UTC
Created attachment 154527 [details] [review]
patch series

Need a GParamSpec for GVariants of a given GVariantType.

Question: should it also support an extra validation function when just checking the type isn't enough? (For example, when you expect array variants to always have a specific length, etc.)

To implement the values_cmp vfunc of GParamSpec, I also added g_variant_compare[0].
Comment 1 Allison Karlitskaya (desrt) 2010-03-05 07:42:59 UTC
Sorry for the delay.  The size of the patch scared me.

Generally, I feel this way:

I like the paramspec.  I particularly like that you added a GVariantType constraint.  This should go in but I don't feel as though I have the authority to ACK the patch (or, honestly the understanding of GParamSpec to properly review it).


I'm uncomfortable about the compare stuff.  The ordering you have picked seems a little bit arbitrary.  I'd actually probably prefer an ordering closer to how Python does it.

Really, though, I'd prefer for no defined ordering at all.

It seems like the only reason for having compare at all would be for GParamSpec -- and it's not really needed there.  I did some grepping around glib and gtk and it looks this this feature is really totally unused.  From a practical standpoint, I'm not sure the GVariant compare function would ever end up being called...


Some small nit-picks about the gobject patch:

  - your unrelated whitespace change should be separated out
  - it looks like you have some whitespace errors yourself (tabs vs. spaces) in the header
Comment 2 Allison Karlitskaya (desrt) 2010-03-05 07:50:06 UTC
Another more substantial nit-pick: not sure if I like that you can have a NULL in the ParamSpec.  Might make sense to force the user to give a non-NULL default value.  Or maybe that's asking too much.
Comment 3 Christian Persch 2010-03-07 12:58:52 UTC
Thanks for the feedback!

(In reply to comment #1)
> I like the paramspec.  I particularly like that you added a GVariantType
> constraint. 

Any thoughts on whether an extra validation func should be supported, to check extra constraints that cannot be expressed merely by the GVariantType ?

> I'm uncomfortable about the compare stuff.  The ordering you have picked seems
> a little bit arbitrary.  I'd actually probably prefer an ordering closer to how
> Python does it.

I thought the order I defined was quite natural, at least the one for same-type variants. strcmp()-comparing the type strings for non-same-type variants is admittedly arbitrary.

> Really, though, I'd prefer for no defined ordering at all.
> 
> It seems like the only reason for having compare at all would be for GParamSpec
> -- and it's not really needed there.  I did some grepping around glib and gtk
> and it looks this this feature is really totally unused.  From a practical
> standpoint, I'm not sure the GVariant compare function would ever end up being
> called...

You're right, I just wrote the compare func for use in the param spec impl. I think I'll just make the paramspec cmp func simply compare the pointers, and drop the compare function.

>   - your unrelated whitespace change should be separated out

Hmm, I don't see any of these?

>   - it looks like you have some whitespace errors yourself (tabs vs. spaces) in
> the header

I'll fix the header.

(In reply to comment #2)
> Another more substantial nit-pick: not sure if I like that you can have a NULL
> in the ParamSpec.  Might make sense to force the user to give a non-NULL
> default value.  Or maybe that's asking too much.

Right, I wasn't sure either. In my use case, I think I'll always use a non-NULL default, but I don't know if there might be other uses that could use NULL... I'll change it to force non-NULL for now, with a g_return_if_fail(). It's always possible to drop this constraint later, whereas the opposite way to add it later isn't A[BP]I compatible.
Comment 4 Christian Persch 2010-03-07 13:19:09 UTC
Created attachment 155472 [details] [review]
updated patch
Comment 5 Christian Persch 2010-03-07 14:11:44 UTC
Created attachment 155473 [details] [review]
complete patch
Comment 6 Allison Karlitskaya (desrt) 2010-03-07 18:10:24 UTC
(In reply to comment #3)
> Any thoughts on whether an extra validation func should be supported, to check
> extra constraints that cannot be expressed merely by the GVariantType ?

The only thing we could do here that would make everyone happy would be to provide a callback function that the user could use to provide their own validation checks.  That's a little bit unprecedented in terms of other GParamSpecs.


> >   - your unrelated whitespace change should be separated out
> Hmm, I don't see any of these?

Sorry.  Not whitespace -- spelling error. :)

- * @owner_type: #GType type that uses (introduces) this paremeter
+ * @owner_type: #GType type that uses (introduces) this parameter

I'm going to commit this tiny little piece now just to get it out of the way.

> Right, I wasn't sure either. In my use case, I think I'll always use a non-NULL
> default, but I don't know if there might be other uses that could use NULL...
> I'll change it to force non-NULL for now, with a g_return_if_fail(). It's
> always possible to drop this constraint later, whereas the opposite way to add
> it later isn't A[BP]I compatible.

I'm happy enough with this.  Glad you used ref_sink(), btw :)

One possibility for relaxing the API in the future for those creating the ParamSpec without violating the (non-NULL) expectations of those consuming the ParamSpec would be to have some support for getting the 'default value' for a given GVariant.  This notion is already well-defined internally in GVariant: it's what you get in the case of errors during deserialisation.  For numeric types it's zero.  For maybes, Nothing.  For arrays, the empty array.  For tuples or dictionary entries of a given type, it is the tuple where each of the values is equal to the default for its type.  For variants, it is equal to the variant containing triv -- the instance of the unit type: ().  This value is probably actually pretty close to what you want anyway...
Comment 7 Christian Persch 2010-05-01 12:56:41 UTC
Ping? Can this go in for 2.26 ?
Comment 8 Matthias Clasen 2010-06-16 16:09:37 UTC
Review of attachment 155473 [details] [review]:

Looks fine to me in general, once the few things below are fixed.

::: gobject/gparam.h
@@ +192,3 @@
  * @flags: #GParamFlags flags for this parameter
  * @value_type: the #GValue type for this parameter
+ * @owner_type: #GType type that uses (introduces) this parameter

Irrelevant hunk ?

::: gobject/gparamspecs.c
@@ +1115,3 @@
+  GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VARIANT));
+
+  g_variant_unref (vspec->default_value);

Need an "if (vspec->default_value)" here ?

@@ +1153,3 @@
+  GVariant *v1 = value1->data[0].v_pointer;
+  GVariant *v2 = value2->data[0].v_pointer;
+

Could use g_variant_compare here ?

@@ +2478,3 @@
+ * @blurb: description of the property specified
+ * @type: a #GVariantType, or %NULL
+ * @default:value: a #GVariant of type @type to use as the default value

Did you mean 'or NULL' to go the next line here ? The code certainly looks like it is trying to handle default_value == NULL, but not type == NULL.

Also, needs an (allow-non): annotation here, I guess.

@@ +2509,3 @@
+
+  vspec->type = g_variant_type_copy (type);
+  vspec->default_value = g_variant_ref_sink (default_value);

Needs a "if (default_value)" here, probably
Comment 9 Christian Persch 2010-06-16 17:06:02 UTC
(In reply to comment #8)
> Review of attachment 155473 [details] [review]:
> 
> Looks fine to me in general, once the few things below are fixed.
> 
> ::: gobject/gparam.h
> @@ +192,3 @@
>   * @flags: #GParamFlags flags for this parameter
>   * @value_type: the #GValue type for this parameter
> + * @owner_type: #GType type that uses (introduces) this parameter
> 
> Irrelevant hunk ?

That was just a typo fix that found its way into this commit. I just committed it independently.

> ::: gobject/gparamspecs.c
> @@ +1115,3 @@
> +  GParamSpecClass *parent_class = g_type_class_peek (g_type_parent
> (G_TYPE_PARAM_VARIANT));
> +
> +  g_variant_unref (vspec->default_value);
> 
> Need an "if (vspec->default_value)" here ?

Ryan seemed to prefer default_value to be guaranteed non-NULL (comment 2, comment 6), but after thinking about this a bit more, I think I lean towards allowing NULL.

> @@ +1153,3 @@
> +  GVariant *v1 = value1->data[0].v_pointer;
> +  GVariant *v2 = value2->data[0].v_pointer;
> +
> 
> Could use g_variant_compare here ?

Not possible, no. g_variant_compare only compares basic variants of the same type; it explicitly disallows comparing container types or variants of different types.
As comment 2 says, the compare feature of GParamSpec seems mostly unused in practise, so it should be ok to do strict pointer comparision here.
Comment 10 Christian Persch 2010-06-16 17:23:25 UTC
Created attachment 163853 [details] [review]
Add GParamSpecVariant

Bug #610863.
Comment 11 Allison Karlitskaya (desrt) 2010-06-16 20:21:09 UTC
Created attachment 163870 [details] [review]
rebase

remove NULL as a default value.

The reason that I don't like that if you're giving a GVariantType (say uint32), the value should have that type.  NULL doesn't have a type of uint32.

Talking with Christian on IRC -- he is wondering if maybe this should have been a new fundamental type instead of a boxed type.  We're in a bit of a weird situation here with the type constraint.  That's somewhat odd for plain boxed types...
Comment 12 Matthias Clasen 2010-06-17 06:46:21 UTC
A fundamental type might be slightly more elegant, but is certainly a bit more work. You can't use g_value_set/get_boxed, then, and have to add new api for that, I guess: g_value_set/get_variant ?
Comment 13 Christian Persch 2010-06-17 11:22:09 UTC
Yes, you'd have to add g_value_set/get/take_variant. However, since G_TYPE_VARIANT is boxed in 2.24, I'm not sure if we can change this now; there might be code out there already doing g_value_init(&value, G_TYPE_VARIANT); g_value_set_boxed(&value, variant). (although google codesearch doens't return any hits for this pattern).
Comment 14 Christian Persch 2010-06-17 11:25:50 UTC
Actually, looking at gboxed.c code, I guess it _would_ be possible to fix this by cheating a little for G_TYPE_VARIANT :)
Comment 15 Christian Persch 2010-06-17 13:33:05 UTC
Created attachment 163912 [details] [review]
Add fundamental type for GVariant

Named G_TYPE_GVARIANT as to not clash with the to-be-deprecated
G_TYPE_VARIANT boxed type.

Add g_value_{set,take,get,dup}_variant.

Bug #610863.
Comment 16 Matthias Clasen 2010-06-17 14:06:23 UTC
Review of attachment 163912 [details] [review]:

::: gobject/gboxed.h
@@ -219,3 @@
- * Returns: %TRUE on success.
- *
- * Since: 2.26

Should this be deprecated, then ? together with the boxed type ?

::: gobject/gparamspecs.c
@@ -1582,3 @@
       param_variant_values_cmp,   /* values_cmp */
     };
-    pspec_info.value_type = G_TYPE_VARIANT;

VARIANT or GVARIANT here ?

::: gobject/gtype.h
@@ +186,3 @@
+ * 
+ * Since: 2.24
+ */

Again, mismatch with the docs

::: gobject/gvaluetypes.h
@@ +174,3 @@
+ * Since: 2.26
+ */
+#define G_VALUE_HOLDS_GVARIANT(value)    (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_GVARIANT))

What is it now, HOLDS_VARIANT or HOLDS_GVARIANT ?
Mismatch with the docs
Comment 17 Christian Persch 2010-06-17 16:01:50 UTC
(In reply to comment #16)
> Should this be deprecated, then ? together with the boxed type ?

This was actually new (in the pspec patch), and just removed. The new patch will deprecate G_TYPE_VARIANT boxed type.

As to GVARIANT vs. VARIANT: I _have_to_ use GVARIANT for the new type, but I'm wondering if all the others (esp. the pspec) should be GVARIANT too for consistency, or VARIANT for simplicity...
Comment 18 Christian Persch 2010-06-17 16:12:51 UTC
Created attachment 163933 [details] [review]
Add fundamental type and pspec for GVariant

Add G_TYPE_GVARIANT as fundamental type for GVariant, and
g_variant_{set,get,dup}_variant.
Deprecate the boxed type G_TYPE_VARIANT.

Add GParamSpecVariant.

Bug #610863.
Comment 19 Christian Persch 2010-06-17 17:41:19 UTC
Created attachment 163945 [details] [review]
Add fundamental type and pspec for GVariant

Make G_TYPE_VARIANT a fundamental type instead of boxed, and add
g_variant_{set,get,dup}_variant.

Add GParamSpecVariant.

Bug #610863.
Comment 20 Christian Persch 2010-06-17 17:46:52 UTC
I changed the G_TYPE_VARIANT type from boxed to fundamental, but kept the g_variant_get_gtype symbol as a deprecated function. I also changed the pspec back to allow NULL default values.

For the record, the advantages of a fundamental as opposed to a boxed type for GVariant are that pspec with a non-NULL default value, and with constraints seems very odd for a boxed type, but fits with what the other fundamental pspecs are doing; and also by adding the g_value_[sg]et_variant functions it allows for nice handling of floating variants.
Comment 21 Matthias Clasen 2010-06-17 18:21:27 UTC
Looks good to commit to me. But the changes will still go into .9, so ditch the extra NEWS section. It would be nice to mention the change from boxed to fundamental somewhere in the docs. Something like "Note that GLib 2.24 did include a boxed type with this name. It has been replaced by this type..."
Comment 22 Christian Persch 2010-06-17 19:10:32 UTC
Pushed to master with these changes, and a last-minute fix for NULL values in the pspec validation func.