On Sat, 2005-04-30 at 12:25 -0600, John Ehresman wrote: > Owen Taylor wrote: > > I think it should be possible to do basically the same thing in Python > > by creating the GObject out of GObject.__new__() rather than out of > > GObject.__init__(). > > This would break backwards compatibility. > > > __new__() calls g_object_new() calls ... ->init() which allocates > > the python object and binds it to the GObject > > > > This is not 101% compatible with the current system but all the > > incompatible cases I can come up with are pretty artificial (*) > > It would break this: > class MyButton(gtk.Button): > def __init__(self): > gtk.Button.__init__(self, 'My Default Text', True) > > This could be rewritten to use __new__, but it would need to be rewritten. I think this still works ... since the GObject is *always* created in the __new__ callback, GtkButton's __init__ looks like: def __init__(self, label=None): if label: self.set_label(label) Constructor arguments that set CONSTRUCT_ONLY properties may be a problem (when aren't they...) > > But in such cases all GObject additions would be would be a slightly > > cleaner version of John's technique of passing data to the constructor > > via magic properties... whether the constructor triggers GObject > > creation or whether GObject creation triggers the constructor is > > going to make a difference in how things are ordered. > > Yes, using a magic property is a bad idea -- there's a reason the patch > was never committed. It's better to use thread local storage, although > that depends on no callback occurring between the call to g_object_new > and the GType constructor. I don't think you can make that assumption ... the init() function of a superclass might result in the creation of another Python object. (It's a little contrived, but > For bindings that have the language specific > constructor trigger GObject creation (like pygtk), it would be better to > have a factory function that would get all the properties passed in and > be responsible for returning a valid GObject. That's basically what constructor() is ... all it seems you might want would be gpointer g_object_new_with_data (GType object_type, gpointer data const gchar *first_property_name, ...) G_GNUC_NULL_TERMINATED; and a hidden fourth parameter to constructor(). (Compatible by the "OK to call with more parameters" quasi-standard that we depend upon in various places. *Except* that any classes deriving from the class have to provide the fourth argument when chaining up. Not a problem here, really.) But while this would allow you to do the GObject/Python hookup to either a newly created or existing Python object it has certain ordering problems - - The naive implementation would try to set implemented-in-Python CONSTRUCT properties before the Python/GObject hookup was done. You'd have to strip them out from the list of construct properties before chaining up, chain up, do the hookup, then set the Python construct properties. - The problem with chaining up to the superclass's __init__ with parameters exists if you call __init__ at any point, since the __init__ function might attempt to chain up with parameters even if no parameters were passed in. Regards, Owen
Attachment:
signature.asc
Description: This is a digitally signed message part