Open 8976c304-cef5-44be-ae86-411a622a09c4 opened 10 years ago
Hello,
I would like to propose a patch for the webbrowser module to actively suppress any output (both on stdout and stderr) from the module itself.
At the moment, doing a quick internet search, the best approximation to obtain this kind of behavior seems to be the ones described in [1] and [2].
In the patch attached I am proposing to add two optional arguments: stdout and stderr to webbroswer.open() (and to the related webbroswer.open_new() and webbroswer.open_new_tab())
Setting stdout and stderr to None effectively suppress any terminal output. The default (True), mimics the current behavior.
There are other minor modifications to clean the code (PEP-8).
I will send a similar patch for Python 2.7.X
Cristian
[1] https://stackoverflow.com/questions/2323080/how-can-i-disable-the-webbrowser-message-in-python [2] https://stackoverflow.com/questions/1352361/suppress-redirect-stderr-when-calling-python-webrowser
This seems like a good idea, based on the use case presented in the stackoverflow question.
This would be an enhancement, so it can only go in 3.5.
Please submit a patch without the PEP-8 changes, so we can easily see what the patch is actually changing. As far as the API goes, since the controls are passed to subprocess, might it be a good idea to make the API for these keywords the same as the one subprocess uses?
Hi David,
thanks for your feedback. The parameters' name are indeed stdout and stderr as the one used by subprocess.Popen().
Here's the patch file without the PEP-8 modifications.
Thanks,
Cristian
What I meant was the "any *other value follows the subprocess documentation" part. I think it would be better to have *all the values follow the subprocess documentation.
Hi David,
at the moment the other parameters used by the open()[1] - 'new' and 'autoraise' - have no direct mapping to other subprocess.Popen(), they are passed as options to the call for the specific browsers. (e.g. firefox -new-tab http://www.example.com)
So I am not really sure I understand your request in this respect.
Cristian
[1] https://docs.python.org/3/library/webbrowser.html#webbrowser.open
I think it is up to you motivate the reason why the new stdin and stderr parameters should have *different* semantics from the same parameters used with subprocess. Consistency is good, unless there is a specific reason to break consistency. That is, if the semantics are the same, a programmer can see stdin/stderr and know they work exactly like the equivalent subprocess args, instead of assuming they do and then getting bitten by the difference.
Unless there is some reason I'm not seeing why the difference in semantics is needed.
Hi David,
*now* I understand your point (!) and, yes, this is something I have thought about.
Basically, I was thinking that with this addition I wanted an easy way to suppress stdout/stderr output. I have thought about simply exposing subprocess.Popen's stderr and stdout parameters (i.e. passing stdout and stdout to subprocess.Popen as they are) but this would have meant that to suppress the output one should do the following:
import webbrowser
import subprocess
webbrowser.open('http://www.example.com', stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
This seems to be utterly complicated to me, also I don't like to have to import the subprocess module just to make use of subprocess.DEVNULL. (an alternative would be passing file(os.devnull, "r+") à la Python 2.7, but the problem of needing an additional module remains). Also, I find that *in the context of the webbrowser module* using subprocess.Popen semantics i.e.:
webbrowser.open('http://www.example.com', stdout=None, stderr=None)
to mean that the stderr and stdout file descriptors are inherited from the parent process is quite counter-intuitive.
That's why I have changed the semantics of the parameters the way I did.
A couple of possible alternatives were changing the name of the parameters: 1) suppress_stdout/suppress_stderr. In this case True (which is not a valid value for subprocess.Popen parameters) would suppress stdout/stderr and None would be meaningful to say 'inherit from parent process'. In this way this would be an addition to subprocess.Popen semantic, but it would be counter-intuitive to the possibility of redirecting to, say, another file. 2) redirect_stdout/redirect_stderr. Actually this was my first thinking when implementing this, but it has the same problems, IMHO, of the plain stdout/stderr and in the end this is why I chose the latter.
Does this make sense?
Cristian
After re-reading myself a couple of times I have to say that following subprocess.Popen and adding True and False with the meaning:
Consistency is a good thing is a good thing is a good thing.
Cristian
It makes sense, but I'm not sure avoiding the extra import is sufficient motivation. If you weren't allowing redirection it would be a different story, but allowing redirection seems logical.
We should get the opinion of some other developers. I've added some people to nosy who have worked on subprocess and/or webbrowser in the not too distant past.
Note: a third option is to import DEVNULL into the webbrowser namespace. That kind of redundancy feels suspect, but practicality might beat purity here.
open(url, stdout=DEVNULL) won't work on Windows (os.startfile()) and OS X (AppleScript) by default.
UnixBrowser already suppresses the output when it is safe, if self.redirect_stdout=True and self.background=True are set.
Also, open(url, stdout=DEVNULL) would probably break text-browsers such as elinks (e.g., they are run when $DISPLAY environment variable is not set).
What left: Unix browsers for which webbrowser doesn't think that it is safe to suppress the output. If webbrowser allows the output when it shouldn't then it could be fixed on case by case basis and/or maybe some mechanism could be provided to override the webbrowser choice e.g., BaseBrowser.suppress_output attribute that defaults to None (let webbrowser decide).
webbrowser is a high-level interface; stdout/stderr from subprocess are too low-level for open() function (inventing your own stdout/stderr values is even worse).
UnixBrowser already suppresses the output when it is safe, if self.redirect_stdout=True and self.background=True are set.
This isn't the case for BackgroundBrowser
though, nor for GenericBrowser
, which are the ones I keep getting when trying to use this on Linux.
Also this is undocumented, which means there's a number of browsers that neither get “case by case” support nor do the module users know of this mechanism to deal with the issue on “case by case” basis themselves (unless they delve into CPython code or search hard enough to stumble upon this comment).
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields: ```python assignee = None closed_at = None created_at =
labels = ['type-feature', 'library']
title = 'webbrowser.py add parameters to suppress output on stdout and stderr'
updated_at =
user = 'https://bugs.python.org/CristianCantoro'
```
bugs.python.org fields:
```python
activity =
actor = 'akira'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Library (Lib)']
creation =
creator = 'CristianCantoro'
dependencies = []
files = ['36477', '36478', '36490']
hgrepos = []
issue_num = 22277
keywords = ['patch']
message_count = 10.0
messages = ['225915', '225917', '225921', '225922', '225962', '225986', '225988', '225989', '225992', '226030']
nosy_count = 6.0
nosy_names = ['georg.brandl', 'pitrou', 'gps', 'r.david.murray', 'akira', 'CristianCantoro']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue22277'
versions = ['Python 3.5']
```