GNOME Bugzilla – Bug 549879
gst-python managing sys.argv while it shouldn't
Last modified: 2013-02-09 21:31:57 UTC
Please describe the problem: As soon as the gst module is imported, it will check sys.argv and if it finds --help in there it will print its own help message and then exit the application. This is not proper, the user should be able to choose what to print. I have attached a very simple example showing this problem. Steps to reproduce: 1. Launch the attached example.py with the --help option Actual results: Only the first message will be printed. Expected results: Both messages should be printed and maybe gst shouldn't print anything at all (unless the user has chosen otherwise, so it may be good to become an option but printing its message shouldn't be enabled by default in my opinion) Does this happen every time? Yes Other information:
Created attachment 117607 [details] An example application revealing the bug.
This is a known problem, I could swear that there was already a bug open about that but I cannot find it. I remember the Jokosher guys hit this... You can work around it if you del sys.argv[1:] before importing. Fixing this issue is not entirely trivial, for compatibility reasons.
(In reply to comment #2) > This is a known problem, I could swear that there was already a bug open about > that but I cannot find it. I remember the Jokosher guys hit this... > I searched before posting this bug and I couldn't find another one about this. > You can work around it if you del sys.argv[1:] before importing. > Yes I am conserned about this workaround but I find it too ugly... Just removing --help from sys.argv is less ugly but it still is ugly... > Fixing this issue is not entirely trivial, for compatibility reasons. > Too bad :( . Anyway, thank you for taking the time to reply!
Shall we move this to a '0.11' feature request ?
Hey Edward. This bug is NEEDINFO for quite some time now. Could do initiate any further steps to have this bug closed sooner or later? :) I'd also set this bug to NEW as it's clearly identified as being a bug which needs to be fixed.
The workaround is straight forward : parse sys.argv before calling import gst. sys.argv parsing should, after all, be the first thing you do in your application/loader. We're then left with two options in gst-python: * Leave it as it is now (parses the existing sys.argv when 'import gst' is called). * Don't pass any arguments to gst_init() ... but then (1) it causes a regression for existing applications relying on that behaviour, (2) we no longer have a way to pass arguments to gst_init(). the sys.argv arguments *NEED* to be parsed when calling gst_init(). There's no way around that, since they will modify the gstreamer initialization. marking as WONTFIX.
Hey Edward. I don't know gstreamer or it's python bindings at all, but I see a way around it: Couldn't you make the call to gst_init() mandatory for the client using the bindings? Many modules do such a thing, take pyGTK for example. The user then could decide which parameter to pass and which not. Having gstreamer handling sys.argv is ugly and will cause trouble for many people. In fact, I would expect that the imported module handles arguments to my program. It simply shouldn't unless I explicitly ask it to. Also, it is very common to organize imports at the beginning of a python module. With the current behaviour, you force programs to have their code restructured in a ugly way, because gst being the only module which behaves strangely.
Tobias, as I said, we can't do this without introducing a regression (all current applications expect sys.argv to be parsed when doing 'import gst'). Furthermore, we currently can't split up the gstreamer initialisation from the argument parsing. Let's suppose we were to pass no argv to gst_init() (ex: gst_init(NULL, NULL)).... well we can't call that method again with the proper argv (using an explicit call after the gst import) because gstreamer will already be initialized and gst_init() will return straight away. The problem is that we *need* to call gst_init() before using anything GStreamer related (else you won't have any types registered, etc...). So basically... the problem is in core. We need to be able to split up the initialization from the argument parsing.
You could add a method to pygst like "pygst.will_handle_init()" or whatever. Then when the user imports gst, they're required to call gst.init(...) themselves. Preserves backwards compat and allows more flexibility.
Mike, your suggestion would mean that 'import gst' would have no effect apart from giving you a blank module with only one symbol : init (since everything else requires GTypes and crack to be initialized... which is done through gst_init()). That means you can't do *ANYTHING* with that module until you've called init... including mentionning any symbols from that module since it's empty and the parser will fail. So yeah it would allow you to do something like this: """ import pygst pygst.require('0.10') pygst.will_handle_init import gst <do your arg parsing BUT YOU CAN NOT DO ANYTHING ELSE> gst.init <start using/mentionning the gst module symbols> """ Is it really that much more flexible than: """ import pygst pygst.require('0.10') <do your arg parsing> import gst <start using/mentionning the gst module symbols> """
Sure, obviously. I thought that was what this bug wanted? But whatever; I don't actually care.
Heya, (In reply to comment #10) > So yeah it would allow you to do something like this: > """ > import pygst > pygst.require('0.10') > pygst.will_handle_init > import gst > <do your arg parsing BUT YOU CAN NOT DO ANYTHING ELSE> > gst.init > <start using/mentionning the gst module symbols> > """ > > Is it really that much more flexible than: > """ > import pygst > pygst.require('0.10') > <do your arg parsing> > import gst > <start using/mentionning the gst module symbols> > """ > Yes. For various reasons, the most important one being that many python programs organize their imports on the top. You wouldn't force them to change that. Another one, that it's not very pythonic to have modules implicitly use sys.argv when importing. If I programmed with pygst, it'd annoy me pretty much :) But also: I don't really care.
(In reply to comment #6) > The workaround is straight forward : parse sys.argv before calling import gst. > sys.argv parsing should, after all, be the first thing you do in your > application/loader. That is not always true. When we are talking about a simple, one-file application, what is usually done is modules imported at the start, then go all the classes and functions and at the end of the file in if __main__ ... goes the argument parsing and everything else required for initialization. > the sys.argv arguments *NEED* to be parsed when calling gst_init(). There's no > way around that, since they will modify the gstreamer initialization. Is it a must for the application's sys.argv to be parsed? Can't it be skipped somehow? Replacing it with what is needed, not including the app's sys.argv, before initializing gstreamer and after initialization, restoring it or something like that? What I am saying might be really crazy, I have never looked at gst-python/gstreamer's source code to see how all this is handled, I am just throwing some ideas. (In reply to comment #7) > Couldn't you make the call to gst_init() mandatory for the client using the > bindings? Many modules do such a thing, take pyGTK for example. That could be a way to resolve the case mentioned above in a proper way. Especially the way Michael Smith proposed so there is no backwards compatibility breakage. As of the other points of Michael Smith and Tobias Mueller, I agree with all of them. Anyway, I think you have made your point of view clear, so maybe this bug should be marked wontfix?
Although I don't care very much, I urge the gst guys to not close it as WONTFIX. I don't think, it is necessary to parse *sys.argv* at all. Instead, it should parse a *given* array of arguments, maybe even a more sophisticated data structure such as a dictionary. I've made my points already, but I'll add PEP-008 which clearly states: - Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. I wouldn't ship a Python module which clearly makes the programmer violate this rules. But still: In order to get this issue resolved, someone who's responsible should set this bug either to NEW or to WONTFIX.
FWIW, I've posted a patch [1] that temporarily removes --help, -h, --version from sys.argv when initializing gstreamer, but I hadn't noticed this bug and the arguments therein before doing so. [1] https://bugzilla.gnome.org/show_bug.cgi?id=625211
So what should happen here now?
Breaks compatibility, but how about removing any options that don't start with --gst- ? The user would then be responsible for adding a little blurb to the program's own --help along the lines of: "use --gst-help for gstreamer specific help". It would then not be surprising that --gst-help would short out user code.
Still ugly but way less ugly than occupying --help. If a mandatory __init__ is not achievable, then prefixing all GStreamer arguments with --gst- sounds reasonable to me.
Closing this bug now, gst-python is only an extension module to pygi now and this bug doesn't make much sense anymore in this context.
As the bug still do exists in Ubuntu 12.10, I'm putting a safe workaround here, just for the record: """ import sys, copy __argv = copy.copy(sys.argv) sys.argv = filter(lambda arg: arg not in ('-h', '--help'), sys.argv) import gst sys.argv = __argv """