GNOME Bugzilla – Bug 667228
Deprecate GValueArray
Last modified: 2015-08-11 15:16:27 UTC
GValueArray is a redundant type that has several problems: - the API does not conform with the GArray, GPtrArray, and GByteArray types; - it's fully exposed on the stack, so we cannot add ref/unref; - there's no way to forcibly resize it. the reason why we have GValueArray in the first place is because when GObject was new, back in the Jurassic GArray didn't have a GType. GArray now does, and it's a better, more extensible API. GValueArray should just be deprecated in favor of GArray.
the missing bit in the GArray API to allow a full replacement of GValueArray is adding a way to unset the GValue when freeing the array. a simple g_array_set_free_func() function, modelled on the equivalent GPtrArray one, would fit the bill.
Sounds like a good idea to me
the array clear function is tracked in bug 667243. I'll attach the GValueArray deprecation patches here.
Created attachment 204552 [details] [review] Deprecate GValueArray The GValueArray type was added in a time, during the Jurassic era or so, when GArray did not have a representable GType. The GValueArray API has various issues as well: - it doesn't match the other GLib array types; - it is not reference counted; - the structure is fully exposed on the stack, so it cannot be extended to add reference counting; - it cannot be forcibly resized. The nice thing is that now we have a GArray type that can replace in full GValueArray, so we can deprecate the latter, and reduce the complexity in GLib, application code, and bindings.
Review of attachment 204552 [details] [review]: Presumably the boxed type and the paramspec should go with it ? (being deprecated, I mean)
Review of attachment 204552 [details] [review]: yes, good point.
(In reply to comment #1) > a simple g_array_set_free_func() function, modelled on the equivalent GPtrArray > one, would fit the bill. > One thing I noted on IRC: This should probably be named differently, because - as opposed to regular free funcs - you're not supposed to free the value, but only to clear the contents. So something like g_array_set_clear_func() sounds like a better idea to me.
The following fix has been pushed: 0ac9ab4 Deprecate GValueArray
Created attachment 206051 [details] [review] Deprecate GValueArray The GValueArray type was added in a time, during the Jurassic era or so, when GArray did not have a representable GType. The GValueArray API has various issues as well: - it doesn't match the other GLib array types; - it is not reference counted; - the structure is fully exposed on the stack, so it cannot be extended to add reference counting; - it cannot be forcibly resized. The nice thing is that now we have a GArray type that can replace in full GValueArray, so we can deprecate the latter, and reduce the complexity in GLib, application code, and bindings.
apparently, GStreamer is using GValueArray in one of their signals on a plugin, and special-casing GValueArray to do some introspection on it. switching to GArray would remove their ability to use the signal from other languages, given that the plugin cannot use the common gobject-introspection annotations. relevant discussion: 16:07 < slomo> ebassi: the deprecation of GValueArray is not really a good idea until GArray has something to specify the element type 16:07 < slomo> ebassi: the advatange of GValueArray was that it was introspectable at runtime and there's nothing to replace this 16:08 < ebassi> it doesn't even guarantee you're storing the same GType 16:08 < slomo> ebassi: with GValueArray you knew that the elements are GValues and that you can get the type of them. with GArray you don't know anything about the elements 16:08 < slomo> ebassi: GArray just points to random memory without any information about how to interprete it 16:09 < ebassi> slomo: that's just because you could special-case GValueArray 16:10 < ebassi> "introspecting" GArray is done using annotations 16:10 < ebassi> you can define the element type 16:10 < slomo> ebassi: yes but that's not possible in the case of plugins, like the gstreamer plugins 16:11 < tpm> ebassi, e.g. http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-decodebin2.html#GstDecodeBin2-autoplug-factories 16:17 < ebassi> is the GValueArray returned by that signal going to hold the same GType or any? 16:18 < tpm> it will be an array of GObjects options: - undeprecate GValueArray, with a huge caveat section, basically just for GStreamer; - GStreamer gets its own GstValueArray type and language bindings learn how tocope with that in the same way they cope with other Gst types; - we somehow add API to store the type of the contents of a GArray; - we add a GObjectArray to gobject, which "subclasses" GPtrArray but does a bunch of additional stuff, like type checks and correct ref/unref on the elements.
additional awfulness: 16:54 < slomo> ebassi: ok, same problem with a new type :) we have a GValueArray of doubles in a plugin too 16:54 < slomo> ebassi: i don't want a GObject that wraps a double :P
IMHO there should be a GObjectArray and a GNewAndBetterValueArray
I don't like adding special-cased array types much. What I'd like however is a function like g_ptr_array_set_value_type() - but I'm not sure how that fits into the glib/gobject split.
as I said, there's also the distinct path of GStreamer dealing with its own API issues by having a GstWhateverArray - as a refcounted, boxed type - and using it in place of GValueArray. there's also the option of allowing the signal to express the GType of the data stored inside the GArray returned by the signal, i.e. by adding a GType (out) parameter to the signal itself, or a GType property on the class that will emit those signals - i.e.: plugin.autoplug_factory_type = WhateverAwesomeObject factories = plugin.emit('autoplug-factory-create', args) there's also the chance of passing an ad hoc collection type to the signal itself, and leave it to the people connecting to the signal to fill that up. alternatively, GStreamer starts using the GIRepository API, and expects its plugins to expose a GIR/typelib describing their API (especially signals and properties), since the object introspection API is comically limited, and the GIRepository API was introduced exactly for this kind of stuff.
yes, special-casing array types is not great. this obviously brings up the whole "where does the type system live" issue; with a GType in GLib, we could have a proper array that does type checking. at this point, the idea of moving at least GType and GTypeInstance inside libglib, and leaving GObject inside libgobject, sounds to me more and more like the way forward.
There's an existing bug with patches by davidz for adding element-type stuff. Don't have the bug # at hand.
Please don't deprecate stuff in GLib without at least cleaning up GLib itself - it's not nice that master compiles with a bunch of deprecating warnings.
(In reply to comment #18) > Please don't deprecate stuff in GLib without at least cleaning up GLib itself - > it's not nice that master compiles with a bunch of deprecating warnings. which deprecation warnings? the only users in GLib of GValueArray have been protected by using GLIB_DISABLE_DEPRECATION_WARNINGS. if you mean the autogenerated test code, I guess it will have to be either ported or protected in the same way.
(In reply to comment #11) > options: > > - undeprecate GValueArray, with a huge caveat section, basically just for > GStreamer; libsoup uses GValueArray too, for XML-RPC, in its public API. And it also requires run-time introspectability. (You give the XML-RPC API some GValues, it serializes them into an XML-RPC request, takes the response, and gives it back to you as a GValue.) (At some point I want to port this to being GVariant-based, but it's low on the to-do list, and also slightly tricky in that GVariant doesn't have a datetime type.)
(In reply to comment #19) > (In reply to comment #18) > > Please don't deprecate stuff in GLib without at least cleaning up GLib itself - > > it's not nice that master compiles with a bunch of deprecating warnings. > > which deprecation warnings? the only users in GLib of GValueArray have been > protected by using GLIB_DISABLE_DEPRECATION_WARNINGS. > > if you mean the autogenerated test code, I guess it will have to be either > ported or protected in the same way. Yes, I meant the code generated by gdbus-codegen (used in more than just tests). Anyway, easily fixed by just using a plain C array, not exactly sure why I use GValueArray in the first place. Fix is here http://git.gnome.org/browse/glib/commit/?id=8e763aef43b951746662978c7c644365a92ecfa3
I think it's a valid argument to require to fix your own code to not use deprecated API before you deprecate API. And "your own code" should include tests that don't specifically target that API and code generators. I'm not a fan of people adding G_DEPRECATED_FOR(something_else) in front of functions without taking responsibility for the compiler warnings they create with that.
I don't really buy the arguments here - if you think gvalue is great, just stuff gvalues into a garray
(In reply to comment #22) > I think it's a valid argument to require to fix your own code to not use > deprecated API before you deprecate API. And "your own code" should include > tests that don't specifically target that API and code generators. > > I'm not a fan of people adding G_DEPRECATED_FOR(something_else) in front of > functions without taking responsibility for the compiler warnings they create > with that. I've committed the deprecations after a full build came up clean of warnings - not really my fault that tests aren't built unless you do an explicit make check.
> There's an existing bug with patches by davidz for adding element-type stuff. > Don't have the bug # at hand. > ... > I don't really buy the arguments here - if you think gvalue is great, just > stuff gvalues into a garray Emmanuele suggested this in the IRC discussion pasted earlier, but it doesn't really solve anything for us, because there is no way to introspect the element type at runtime, and there's no way to tell dynamic bindings about per-element annotations. The problem is that GStreamer elements don't have any public API beyond GObject/GSignal API. There are no header files or exported symbols for GStreamer elements, and there are no .gir files for GStreamer elements. Just to give some context, we're in the process of finalising the upcoming GStreamer 1.0 API, which we'd like to keep stable for a few years. We're going to depend on GLib 2.32 initially. We really need a solution that is workable for us, deliverable with GLib 2.32 and will be supported going forward.
(In reply to comment #25) > Emmanuele suggested this in the IRC discussion pasted earlier, but it doesn't > really solve anything for us, because there is no way to introspect the element > type at runtime I believe the suggestion is that gstreamer should assume that (for purposes of gstreamer elements) G_TYPE_ARRAY always means "GArray containing GValues". (This wouldn't conflict with any other uses of G_TYPE_ARRAY, since you couldn't be using it anyway since it's not introspectable.)
(In reply to comment #26) > (In reply to comment #25) > > Emmanuele suggested this in the IRC discussion pasted earlier, but it doesn't > > really solve anything for us, because there is no way to introspect the element > > type at runtime > > I believe the suggestion is that gstreamer should assume that (for purposes of > gstreamer elements) G_TYPE_ARRAY always means "GArray containing GValues". > (This wouldn't conflict with any other uses of G_TYPE_ARRAY, since you couldn't > be using it anyway since it's not introspectable.) The problem is not GStreamer assuming something or not, but bindings. Bindings would need to be able to know what the element type of a GArray is without having any GObject-Introspection annotations available. Of course you could define that a GArray without annotations should be treated as a GArray containing GValues by bindings but this decision would seem arbitrary.
ping?
Any updates on this? Any chance to get it 'un-deprecated' ?
No, I don't think we want to undeprecate it. Deprecated != dead, you can still use it until you have your bindings fixed to use something else.
"Having your bindings fixed" is not really a useful comment. There's no "your bindings" anymore as every GObject binding now uses (or soon uses) gobject-introspection and everything has to work with g-i now.
True we can still use the deprecated API, and I guess there is zero chance that it will ever go away in glib 2.x, but it still feels quite annoying to have an API you depend heavily on deprecated with no agreed/suitable alternative solution available. Also in regards to your comment about 'fixing our bindings' if it is the opinion of one of the main glib maintainers that making sure developers can use glib through gobject-inspection isn't a priority for glib development, then of course that is good feedback to have and we need to revise our bindings strategy for GStreamer accordingly.
Can we be more productive and less whiny please? I think we can all agree that the current usages of GValueArray are hacks, ie workarounds for missing functionality. I think we can also agree that because of that it makes sense to deprecated GValueArray. Do we have any idea how such a solution would look? Can we undo the deprecation of GValueArray until such a solution is implemented?
(In reply to comment #33) > Do we have any idea how such a solution would look? like dbus-glib's system for registering compound gtypes? http://dbus.freedesktop.org/doc/dbus-glib/dbus-glib-Specializable-GType-System.html#dbus-glib-Specializable-GType-System.description eg (from NM) #define DBUS_TYPE_G_ARRAY_OF_STRING (dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING)) #define DBUS_TYPE_G_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
GObject simply has no first-class collection support. Claiming that GValueArray somehow provided that is just misleading, imo.
(In reply to comment #33) > I think we can all agree that the current usages of GValueArray are hacks, ie > workarounds for missing functionality. I'm not sure that I agree that GValueArray is redundant with GArray. As I see it, a GVA is a heterogeneous tuple of dynamically-typed objects (like a Python tuple). If I remember correctly, it's also the internal representation of the "payload" of a signal? It seems a natural representation for that, anyway. Compare with GArray and GPtrArray, which are homogeneous arrays of statically-typed objects (each of the (element-type), in g-i terms) - if you have a GArray of GValues, it's not really a tuple of arbitrary objects, but more like a homogeneous array of GValue boxes (with those GValue boxes potentially containing heterogeneous dynamically-typed objects). Maybe GVA should have been called GTuple, but we already have that, and it does something else and is deprecated. (In reply to comment #11) > - undeprecate GValueArray, with a huge caveat section, basically just for > GStreamer ... and dbus-glib (which uses GVA to represent D-Bus "struct" types), and telepathy-glib, and anything else that was unwise enough to expose the types dbus-glib uses in its API. (Yes yes, we do intend to move from dbus-glib to GDBus, but it's sufficiently pervasive that it's a very disruptive change.) (In reply to comment #19) > it's not nice that master compiles with a bunch of deprecating warnings. We've turned off GLib deprecation warnings in telepathy-glib (and all projects that use it), because we treat deprecation warnings as fatal on development branches, and there's no way we're going to eradicate GValueArray from our API right now. Turning off *all* GLib deprecation warnings is a rather bigger hammer than we wanted. (The other option would be to make them warn non-fatally, i.e. constantly nag developers about something we/they can't do anything about in the short or medium term.) (In reply to comment #34) > like dbus-glib's system for registering compound gtypes? Have you looked at the implementation? It's pretty horrible (and I say that as a contributor to it). There's a reason GDBus uses GVariant instead... With modern support from the GLib types, it could be less bad (e.g. now you can refcount arrays and hash tables, and set their destructors), but I suspect it'd still be pretty bad. Note that dbus-glib uses GVA in its compound type system, both to represent D-Bus "structs" (tuples) and as its internal representation of an entire D-Bus message (which is basically also a tuple, and GDBus represents it as such). dbus-glib's use of GVA is pretty close to my mental model for GVA, actually: it doesn't represent a D-Bus 'av' (array of variant) as a GVA, but instead as a GPtrArray<GValue>. So, everywhere that it does use a GVA, it's using it as a tuple.
(In reply to comment #36) > dbus-glib's use of GVA is pretty close to my mental model for GVA, actually I would guess that dbus-glib *created* your mental model of GValueArray, since GValueArray is not actually any more inherently tuple-like than GArray or GPtrArray. Company suggested "g_array_set_element_type()" on IRC this morning, which would solve the problem from comment 27 (once bindings were updated to know about it), although such an API would have to involve weird collusion between libglib and libgobject. (Though no weirder than g_source_set_closure() really...) > Turning off *all* GLib deprecation warnings is a rather bigger > hammer than we wanted. see bug 669671 comment 10
Going back to the original motivation here - the original reporter is saying basically "Hey GArray is better" but honestly GValueArray wasn't a real problem before. Its usage wasn't creating a serious performance bottleneck, it isn't a huge amount of code that interacts with everything else, etc. So I'm really not sure it's worth the pain for GLib consumers to deprecate it versus the pretty small "gain" in GLib.
(In reply to comment #38) > Going back to the original motivation here - the original reporter is saying > basically "Hey GArray is better" no, what I was saying was: "hey, GValueArray is *broken*". my assessment did not cover GArray (which I consider, like the rest of the container types in GLib, just moderately broken by the lack of typing information of their contents). because it's fully public we cannot make it (compatibly) refcounted, and its API has a certain impedance mismatch with the API of the other array types in GLib, making it stand out. as I said two hundred comments ago, in comment 11, undeprecating ValueArray may be doable - but "obvious API wart is obvious", as those damn kids today say. I even outlined a couple of ways to work around it - at least, for GStreamer, which at least is about to break API. dbus-glib users will warrant something else entirely, for instance the macros that Dan wrote.
(In reply to comment #39) > (In reply to comment #38) > > Going back to the original motivation here - the original reporter is saying > > basically "Hey GArray is better" > > no, what I was saying was: "hey, GValueArray is *broken*". Mmm...we probably have different definitions of "broken". Or more precisely I think you're using "broken" where I would say "suboptimal" or "could be improved". - the API does not conform with the GArray, GPtrArray, and GByteArray types; The API not being consistent really isn't "broken", and we have to live with it forever anyways. - it's fully exposed on the stack, so we cannot add ref/unref; Current API consumers were using it without this functionality. Was there some sort of common pattern of e.g. people leaking memory while using it? Or is it more about enabling new functionality? - there's no way to forcibly resize it. Same as above.
(In reply to comment #40) > (In reply to comment #39) > > (In reply to comment #38) > > > Going back to the original motivation here - the original reporter is saying > > > basically "Hey GArray is better" > > > > no, what I was saying was: "hey, GValueArray is *broken*". > > Mmm...we probably have different definitions of "broken". Or more precisely I > think you're using "broken" where I would say "suboptimal" or "could be > improved". my definition of broken includes "if we cannot safely make it better, then it's broken". > - the API does not conform with the GArray, GPtrArray, and GByteArray types; > > The API not being consistent really isn't "broken", and we have to live with it > forever anyways. yes; hence the deprecation. > - it's fully exposed on the stack, so we cannot add ref/unref; > > Current API consumers were using it without this functionality. we cannot conceivably use a bigger allocation internall, and then just return a GValueArray to the constructor, without introducing an ABI break for the (possibly insane, but valid nonetheless) use case of people actually assuming that it's entirely possible to place a GValueArray on the stack and let another library consume it; if the other library is updated to use a ref/unref then we'd just have broken the ABI guarantees, as well as have introduced hard to debug crashers. > Was there some > sort of common pattern of e.g. people leaking memory while using it? Or is it > more about enabling new functionality? see above. the deprecation is a mechanism to cut our losses now, instead of introducing breakage when there are more than two moving parts. I don't have any horse in this race whatsoever; I ported my code using GValueArray to proper C arrays because GValueArray didn't buy me anything at all - and I never exposed GValueArray (or any other *Array type) in my API because the lack of typing and safety, as well as lack of support in language bindings. as far as I'm concerned, my interest in this bug was exhausted when g_array_set_clear_func() landed, and the deprecation of GValueArray was a nice way to reduce the array type redundancy in GLib.
Created attachment 207795 [details] [review] Revert deprecation This patch reverts the deprecation, but I kept the new documentation section which points to GArray + g_array_set_clear_func().
> I even outlined a couple of ways to work around it - at least, for GStreamer, > which at least is about to break API Unfortunately the suggestions made so far either don't cover all of our use-cases (signals, properties, data sent by elements to applications via GstMessage/GstStructure) or seem very unappealing from a platform point of view. We don't mind migrating away from GValueArray at all, but at the moment our best option seems to be to just stick to it, even if it stays deprecated. > there's also the distinct path of GStreamer dealing with its own > API issues by having a GstWhateverArray - as a refcounted, boxed > type - and using it in place of GValueArray. This would be a possibility, but it doesn't seem particularly appealing. If I'm not mistaken, it means that g-i-based binding can't implement automagic array conversions unless they link to gstreamer, or people implement some extra python/whatever module with gstreamer magic extensions. High-level language users will have to use GStreamer-specific API for those arrays instead of native language features, which feels a bit fail. > there's also the option of allowing the signal to express the GType of > the data stored inside the GArray returned by the signal, (...) This might work for signals, but we also need to cover properties and stuff sent in element messages (GValues in a dictionary, basically). > alternatively, GStreamer starts using the GIRepository API, and expects its > plugins to expose a GIR/typelib describing their API (especially signals and > properties), since the object introspection API is comically limited, and the > GIRepository API was introduced exactly for this kind of stuff. Adding GIR/typelib stuff for GStreamer elements would be possible, but that only solves part of the problem (signals and properties), not data sent in element messages. It's also a bit iffy for dynamically generated elements in wrapper plugins such as ffmpeg/libav, opencv, frei0r, ladspa etc. - we would have to generate the introspection data for those on the fly as well then. > the suggestion is that [bindings] should assume that (for purposes of > gstreamer elements) G_TYPE_ARRAY always means "GArray containing GValues". This would probably work technically, assuming GLib or gobject-introspection document this as official policy for bindings, but as Sebastian already mentioned, it seems a bit arbitrary, and I'm not convinced this is a step in the right direction. I think we would still prefer a deprecated GValueArray with explicit element types to this. There was mention of the handling of other GStreamer types (fundamental types such as fractions etc.) earlier. That is certainly a valid point and a problem of sorts as well, but in practice it's much less of a problem, because those types tend to be limited to caps, and caps can be created/manipulated differently, and most people prefer that route anyway (just create caps from a string, that is). =============== To re-cap, what we need is an array type of some sort that can hold GObjects or doubles or ints etc., where the GType of the content can be determined at run-time using GLib API, and given the type one knows how to extract the different values (that doesn't necessarily have to be via a GValue). In our case the GType is always the same for all elements in the array, for a given array. Refcounting would be nice too of course. Perhaps we could just come up with a GBetterValueArray ? I feel that this kind of functionality does belong into GObject, even if GStreamer is the only major user we are aware of. It's just where it belongs in the platform IMHO. (But perhaps I am mistaken to assume that GLib these days serves as the base library for our platform, and is no longer just a utility library for Gtk+, or that GStreamer is an important part of that same platform). A bunch of boxed GTypes such as G_TYPE_OBJECT_ARRAY, G_TYPE_DOUBLE_ARRAY, G_TYPE_BOXED_ARRAY, G_TYPE_INT_ARRAY etc. would work as well, but my impression was that no one's very keen on that, not least because we can't derive from G_TYPE_ARRAY, though I'm not sure if that's really necessary anyway (would anyone want to speculate how much effort it would be to add support for derived boxed types?)
I think this does not buy us anything, tbh. Either we want to use deprecations to inform api users of suboptimal apis that may eventually go away, or we deprecation is just too inconvenient because everybody is religious about immediate deprecation-freeness. I don't see any value in adding shades of gray between deprecated and non-deprecated.
(In reply to comment #44) > I think this does not buy us anything, tbh. > > Either we want to use deprecations to inform api users of suboptimal apis that > may eventually go away, I don't agree with "may eventually go away". > or we deprecation is just too inconvenient because > everybody is religious about immediate deprecation-freeness. Yeah, this does intersect with the whole issue of -Werror which is a mess. > I don't see any value in adding shades of gray between deprecated and > non-deprecated. There is no gray here - GValueArray isn't deprecated (after the patch). It's just that you can also use a GArray in some (possibly "most") circumstances.
So what's going to happen here now, AFAIK glib is supposed to be API frozen soon for 2.32 and GValueArray is still deprecated without having a complete replacement yet. We currently use GValueArray in public GStreamer API and would be happy to move to a better, non-deprecated alternative if one existed. But for using it in the public GStreamer 1.0 API we would need this to exist in GLib 2.32 already. The only alternative would be to stick with GValueArray until GStreamer 2.0.
> To re-cap, what we need is an array type of some sort that can hold GObjects or > doubles or ints etc., where the GType of the content can be determined at > run-time using GLib API, and given the type one knows how to extract the > different values (that doesn't necessarily have to be via a GValue). In our > case the GType is always the same for all elements in the array, for a given > array. Refcounting would be nice too of course. Sorry to be a bit dense, but I still don't understand what's wrong with GArray of GValue, i.e. with (element-type GObject.Value) annotation. IMHO bindings should support this construct 'natively', without any additional care, as an array of GValues, and the application (written on top of the binding) should take care of packing/unpacking the GValue array items.
(In reply to comment #47) > > To re-cap, what we need is an array type of some sort that can hold GObjects or > > doubles or ints etc., where the GType of the content can be determined at > > run-time using GLib API, and given the type one knows how to extract the > > different values (that doesn't necessarily have to be via a GValue). In our > > case the GType is always the same for all elements in the array, for a given > > array. Refcounting would be nice too of course. > > Sorry to be a bit dense, but I still don't understand what's wrong with GArray > of GValue, i.e. with (element-type GObject.Value) annotation. IMHO bindings > should support this construct 'natively', without any additional care, as an > array of GValues, and the application (written on top of the binding) should > take care of packing/unpacking the GValue array items. The problem with this is that the element type (i.e. GValue in your example) is not runtime-introspectable. You can't always add static introspection annotations, and in the case of GStreamer there are multiple places where you simply can't. The same is true for other highly-dynamic uses of the GObject type system.
(In reply to comment #48) > (In reply to comment #47) > > Sorry to be a bit dense, but I still don't understand what's wrong with GArray > > of GValue, i.e. with (element-type GObject.Value) annotation. IMHO bindings > > should support this construct 'natively', without any additional care, as an > > array of GValues, and the application (written on top of the binding) should > > take care of packing/unpacking the GValue array items. > > The problem with this is that the element type (i.e. GValue in your example) is > not runtime-introspectable. You can't always add static introspection > annotations, and in the case of GStreamer there are multiple places where you > simply can't. The same is true for other highly-dynamic uses of the GObject > type system. I apologize but I still don't get it. GValue is not runtime-introspectable? Runtime introspectability is the key feature of GValue, and any sane binding should IMHO somehow respect it - either automatically by transparent boxing/unboxing of values for dynamic languages, or allowing direct access to native g_value_xxx methods, or providing some target-language-friendly wrapper for querying type/value of the GValue, or some combination of above methods.
GArray's element type is not runtime-introspectable.
(In reply to comment #50) > GArray's element type is not runtime-introspectable. True, but GArray's element type will be (compile-time) annotated to be GValue, which is runtime introspectable.
Yes, and what you've written in the parenthesis is exactly the problem. It's a compile-time annotation that is necessary to specify the element type of a GArray. There's no runtime introspection for the element type.
(In reply to comment #52) > Yes, and what you've written in the parenthesis is exactly the problem. It's a > compile-time annotation that is necessary to specify the element type of a > GArray. There's no runtime introspection for the element type. Actually, it is GValue that provides the runtime introspection. To illustrate my point, I've tried adding following method to GI regress test suite (regress.c): /** * regress_test_array_gvalue_return: * Return value: (element-type GObject.Value) (transfer full): */ GArray *regress_test_array_gvalue_return (void) { GArray *array = g_array_sized_new (FALSE, TRUE, sizeof (GValue), 2); g_array_set_size (array, 2); g_value_init (&g_array_index (array, GValue, 0), G_TYPE_STRING); g_value_set_string (&g_array_index (array, GValue, 0), "Hello"); g_value_init (&g_array_index (array, GValue, 1), G_TYPE_INT); g_value_set_int (&g_array_index (array, GValue, 1), 42); return array; } And then from python: Python 2.6.7 (r267:88850, Feb 2 2012, 23:50:20) [GCC 4.5.3] on cygwin Type "help", "copyright", "credits" or "license" for more information. >>> from gi.repository import Regress >>> array = Regress.test_array_gvalue_return() >>> print(array) ['Hello', 42] The returned array is polymorphic, and python binding correctly unboxed the array elements according to the runtime GValue type.
(In reply to comment #53) > /** > * regress_test_array_gvalue_return: > * Return value: (element-type GObject.Value) (transfer full): > */ > GArray *regress_test_array_gvalue_return (void) No, that's not what we're talking about. We're talking about a function: GValue * regress_test_mystery_gvalue_return (void) { } The return value could be any type. Sometimes it's an array, sometimes it's not. If you have GValueArray, then it's possible to return an array whose element type can also be determined. But with just GArray you can't; you can know it's an array of 24-byte items, but you don't know (for sure) what those items are.
> GValue * > regress_test_mystery_gvalue_return (void) > { > } > > The return value could be any type. Sometimes it's an array, sometimes it's > not. If you have GValueArray, then it's possible to return an array whose > element type can also be determined. But with just GArray you can't; you can > know it's an array of 24-byte items, but you don't know (for sure) what those > items are. OK, finally I understand the issue. Thanks for your patience, and apologies for the noise.
Just as an update following an IRC discussion from last week: I think the current plan for GStreamer 0.11 is at this point still to stick with GValueArray for element API (properties, signals, messages), but not to use it in public annotatable API (I think there was only one interface that used it, and that was removed anyway). We believe we can do without a {py,whatever}-gstreamer bindings module in addition to the gir bindings, and doing such a thing just for, or mostly for, some GStreamer-internal GValueArray replacement doesn't seem worth it.
For the (late) record, this deprecation also means that API breaks will have to cascade into libgsf.
Recently I opened bug 706315 to track the removal of GValueArray, as I understood that it was deprecated. But this bug is still open. Something missing? Bug still open by error?
There still is no replacement for GValueArray for all use-cases.
Can we get undeprecation back on the radar, please? 1. A data structure library like this part of glib is full of redundant types. GSList, for example, is clearly redundant. That's just the nature of things, not a sign of anything wrong. 2. Deprecation has a cost. All the G_GNUC_BEGIN_IGNORE_DEPRECATIONS all over, say, gtk+ shows that the warning spam was painful because it hides more interesting warnings. I believe the cost-benefit analysis was done wrong for this deprecation: For a container type the cost seems much higher than the cost of keeping the code around. This is because this type is used in APIs of libraries so the cost cascades into library users. And with stable APIs it is really not obvious how to fix.
Don't hijack bugs by changing the summary -- it only serves to confuse people who may come to this bug later (from links in the commit logs, for example).
GValueArray was deprecated not because of redundancy, but because its implementation was duplicating (badly) existing API; since it was duplicating it badly, it was also impossible for us to fix it transparently for applications. I opened bug 753522 for a replacement convenience API to bridge GArray with GValue. I think this bug can be closed: GValueArray was deprecated, and all we're missing is some helper API.