Hi All,

In an effort to cleanup the Python bindings, I have been auditing the
plethora of overrides to see what can be removed [1]. There are a handful
of cases where the binding machinery could handle things given more
information from GI as opposed to binding overrides. Specifically,
overridden methods like constructors (__new__ in Python).

The proposal is to add meta data attributes to various classes which
describe what to use for default construction. This would be particularly
useful in cases where g_object_new is invalid and may even crash
(singletons and GBinding for example). These problems definitely threw me
off when I first started learning GI and I have dealt with a number of
related tickets since, hence this proposal. I attempted some analysis by
following classes without public constructors [2] and created a tracking
ticket for related issues [3].

The idea is to introduce two annotations for classes: "factory" and
"constructor", either as first class annotations or as generic attribute
annotations. The concept of a "factory" applies to object creation for an
entire class hierarchy and requires a type as the first argument for
dispatching. The "constructor" annotation can then override the factory for
class specific creation where needed.

The primary usage of the factory annotation is to fix problems related to
GInitiallyUnowned class hierarchies used with g_object_new (which is marked
as transfer-full but may return a floating reference). Example annotation
as follows:

/**
 * GObject:
 * Attributes: (meta.factory GObject.Object.new)
 **/

/**
 * GInitiallyUnowned:
 * Attributes: (meta.factory GObject.InitiallyUnowned.new)
 **/

This introduces a new factory function designed for GInitiallyUnowned and
any sub-classes. g_initially_unowned_newv would wrap g_object_newv but with
the return marked as transfer-none (or transfer-floating). This gives
bindings the correct information to use g_object_ref_sink on the result.
This would allow us to remove the special case hacks in bindings which use
g_object_newv for generically creating all objects (checking if the class
is GInitiallyUnowned or is floating and sinking accordingly). While the
hacks really aren't such a big deal, this gives a concise way bindings
should interpret GI and allow for purer GI bindings.

Default constructor annotations hint that the class should not use the
factory, but instead use the specified class constructor (overrides the
class hierarchies factory for this specific class):

/**
 * GVolumeMonitor:
 * ...
 * Attributes: (meta.constructor GObject.VolumeMonitor.get)
 *  ...or to not allow construction...
 * Attributes: (meta.constructor GObject.private_constructor_error)
 **/

Note that this must be restricted to the class it is called on (cannot be
used for sub-classes). For this reason, it is important to distinguish the
annotations for factory and constructor creation. For Python, standard
object creation of Gio.VolumeMonitor() would then give back the singleton
instance (the machinery will call "get"). Or as noted in the example,
marking construction private which would give an error.
private_constructor_error being a function which takes and fills out a
GError resulting in an exception for interpreted languages. So in this
case, calling Gio.VolumeMonitor() would raise an exception with something
like: "direct creation of class is not allowed, please read the class
documentation." This will help relieve support tickets.

Classes which have required constructor arguments but no way to specify
this [4] can use a default constructor annotation with an explicit function
that requires the arguments:

 /**
 * GtkTreeModelFilter:
 * Attributes: (meta.constructor Gtk.TreeModelFilter.new)    ...requires
child_model and root arguments...
 **/

Additional Thoughts:
* The names used for the attribute annotations are initial suggestions.
* I am a little biased towards using "Attributes:" as opposed to adding
first class annotations because:
** It will be easier.
** Bindings don't have to rely on new GI API and can still work with older
versions of GLIb/GTK+ as they always have.
* We should not add default constructor annotations to classes which are
already working with g_object_new because it might break things. Only add
constructor annotations to classes which are already broken or require
overrides to dispatch to the appropriate constructor.

Feedback appreciated.
-Simon

[1] https://bugzilla.gnome.org/show_bug.cgi?id=705810
[2] https://wiki.gnome.org/PyGObject/Analysis/Bug675581
[3] https://bugzilla.gnome.org/showdependencytree.cgi?id=708060
[4] https://bugzilla.gnome.org/show_bug.cgi?id=649662
_______________________________________________
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list

Reply via email to