Re: making Python GStreamer plugins work



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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]