GNOME Bugzilla – Bug 339279
[gst.URIHandler] interfaces with class-global virtual methods
Last modified: 2007-10-25 16:20:15 UTC
I get this warning when trying to subclass gst.URIHandler: RuntimeWarning: Interface type gst.URIHandler has no python implementation support
The problem is the virtual methods for interfaces aren't defined in the .defs files, so the codegenerator doesn't allow interfaces subclassing. Steps to do : 1/ (optional) Add needed vtable argument to the interface definition 2/ Define interfaces virtual methods 3/ Write overrides
Created attachment 64026 [details] [review] Defines vtable and virtual methods for GstURIHandler and GstImplementsInterface This patch does step 1 and 2 of the above comment.
Created attachment 64037 [details] [review] Updated version I also noticed we had the same problem with the gst.interface interfaces. This new patch adds fixes for those.
Created attachment 64079 [details] [review] first attempt at virtual overrides I took a stab at step 3, but I ran into problems. 1) GstURIHandler has two methods (get_protocols and get_type) which don't take any arguments according to: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstUriHandler.html#GstURIHandlerInterface which makes it difficult to implement an override. 2) codegen appears to ignore GstURIHandler.get_type overrides. The generated code looks like this: static void __GstURIHandler__interface_init(GstURIHandlerInterface *iface) { iface->get_protocols = _wrap_GstURIHandler__proxy_do_get_protocols; iface->get_uri = _wrap_GstURIHandler__proxy_do_get_uri; iface->set_uri = _wrap_GstURIHandler__proxy_do_set_uri; } notice iface->get_type is missing. i tried changing the names in gst.defs and gst.overrides to get_uri_type and that worked besides the obvious fact that GstURIHandler doesn't have a get_uri_type function.
several of those overrides only need proper argument type overrides in gst/arg-types.py to have the codegenerator write it automatically.
Created attachment 64097 [details] [review] Parameter and Return types for gulong, GType and const-gchar* This patch adds overrides for Parameter and Return (used in virtual methods) for gulong, GType and const-gchar*. It helps have more virtual methods auto-generated.
the get_type method is not generated because there is an ignore for all *_get_type functions/methods in gst.override. This ignore should go and all _get_type() definitions (the ones to get the corresponding GType for a class) in gst.defs should go. But then another problem will hit the fan : the get_type() method doesn't take any argument, which is going to make it really hard to figure out the python wrapper for that class... since there isn't any. This needs more thinking.
I've done some thinking and the only solution I can come up with that doesn't involve changing GstURIHandlerInterface is pretty ugly. Basically all python URIHandlers are fake and never registered with gstreamer in the traditional sense. Instead a global python GstURIHandler is registered only once for each uri type (GST_URI_SINK, GST_URI_SRC) and gst-python keeps its own registery of python URIHandlers. When Gstreamer calls get_protocols for the global GstURIHandlerInterface, it returns a list of all protocols handled by every python URIHandler. When set_uri is called, it associates that instance of GstURIHandler with the real python GstElement which handles the protocol so it is able to proxy the function calls. # gst code class URIHandler(object): type = gst.URI_UNKNOWN protocols = [] def get_uri(self): raise UnimplementedError def set_uri(self, uri): raise UnimplementedError def register_uri_handler(klass): assert issubclass(klass, URIHandler): _register_uri_handler(klass, klass.type) # _register_uri_handler is the C function which maintains the global # list of src and sink uri handlers and takes care of registering # the two real GstURIHandler proxies with gstreamer. # application code class DaapSrc(gst.Element, gst.URIHandler): type = gst.URI_SRC protocols = ['daap'] def get_uri(self): return 'daap' def set_uri(self, uri): pass gst.register_uri_handler(DaapSrc)
2006-04-28 Edward Hervey <edward@fluendo.com> * gst/arg-types.py: GstMiniObject used as virtual methods parameters should be unreffed before calling the method and the ref-ed. Added Params and Returns for const-gchar*, GType and gulong so the code generator can generate more virtual methods handlers/proxys. * gst/gst-types.defs: * gst/gst.defs: * gst/interfaces.defs: Added vtable and virtual method definition for interfaces so we can properly use virtual methods from those interfaces in python.
The only problem is for interface methods that don't take the instance as their first parameter (which make them class-specific methods in fact, and not instance-specific). Changing title accordingly
How does pyGObject handle implementing class functions? It would be easy enough to add new URIHandler vmethods get_type_full/get_protocols_full that take the GType as a parameter, for example. As you mentioned, they can't take the instance, because GstElementFactory needs to call them before there is actually an instance of the type, so they are definitely class methods.
Created attachment 96961 [details] [review] core patch
Created attachment 96962 [details] [review] gst-python patch
In the core patch, the precedence is given to iface->get_type, if it's missing iface->get_type_full is used. The same goes for get_protocols. This is just a trivial implementation that came to my mind, maybe we should do something different. To make iface->get_protocols_full wrappable from python, the function must return a new gchar**, as we have to create one from python. This would be a little odd if we decide to make get_protocols_full public API. IMO we should add get_type_full and get_protocols_full but leave them private. I don't think they would add much value to the current C API. Of course the patches are not meant to be committed like this, I just want input.
I'm leaving the final call on this to bilboed, because he's the gst-python guy and knows stuff about things. It looks good to me though.
Created attachment 97735 [details] [review] core patch Make the _full vfuncs private
Created attachment 97736 [details] [review] gst-python patch Remove the codegen diff that although useful is not needed for this specific case. Terminate GStrv with a NULL element.
I updated the patches. I also made the _full funcs private as I think we don't need them in C.
Edward, any feedback on this before we commit ?
Since Edward said OK, committing. I made the get_type_full and get_protocols_full vfuncs public again, like the previous patch, and added some docs. Otherwise, they don't appear in the docs, and then how will other bindings know to implement them? 2007-10-25 Jan Schmidt <Jan.Schmidt@sun.com> * gst/gstelementfactory.c: (gst_element_register): * gst/gsturi.h: Patch from Alessandro Decina adding get_type_full and get_protocols_full private vfuncs to the URIHandler interface to allow bindings to support creating URI handlers. Partially fixes: #339279 API: GstURIHandlerInterface::get_type_full API: GstURIHandlerInterface::get_protocols_full And the python patch: 2007-10-25 Jan Schmidt <Jan.Schmidt@sun.com> * gst/gst.defs: * gst/gst.override: Patch from Alessandro Decina adding get_type_full and get_protocols_full private vfuncs to the URIHandler interface to allow bindings to support creating URI handlers. Partially fixes: #339279