This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: webbrowser.open incomplete on Windows
Type: behavior Stage: patch review
Components: Library (Lib), Windows Versions: Python 3.10
process
Status: open Resolution:
Dependencies: 43538 Superseder:
Assigned To: Nosy List: Arfrever, Mariatta, PedanticHacker, devplayer, eryksun, jbmilam, joncwchao, paul.moore, python-dev, r.david.murray, steve.dower, tim.golden, zach.ware
Priority: normal Keywords: patch

Created on 2010-03-25 18:32 by joncwchao, last changed 2022-04-11 14:56 by admin.

Files
File name Uploaded Description Edit
webbrowserdebug.py jbmilam, 2014-07-26 14:38
webbrowserfix.patch jbmilam, 2014-08-05 02:58 review
webbrowserfix2.patch jbmilam, 2015-05-27 21:23 review
webbrowserfix3.patch jbmilam, 2015-05-28 13:25 review
webbrowserfix3.patch jbmilam, 2015-05-28 13:36 review
webbrowserfix4.patch jbmilam, 2015-06-01 18:45 review
webbrowserfix5.patch jbmilam, 2015-06-04 21:02 review
webbrowserfix6.patch jbmilam, 2015-06-07 16:26 review
25005_1.patch steve.dower, 2015-09-07 05:49
8232_1.patch steve.dower, 2015-09-07 15:40 review
Messages (55)
msg101725 - (view) Author: Jonathan Chao (joncwchao) Date: 2010-03-25 18:32
webbrowser.open(), webbrowser.open_new(), and webbrowser.open_new_tab() all do the exact same thing, regardless of the flags that I set. In Firefox, open('www.google.com', new=0), open_new('www.google.com'), and open_new_tab('www.google.com') all open either three new www.google.com tabs (if "Open new windows in a new tab instead" is selected in FF options) or three new www.google.com windows (if "Open new windows in a new tab instead" is not selected in FF options). In Internet Explorer, three new www.google.com tabs are created.

The issue exhibits itself the same way whether or not I have the browser open before running the script.

Environment was a Windows Vista 32-bit machine, running Python 3.1.2.

Example script reads:
import webbrowser
import time
ff = webbrowser.get('firefox')
ff.open('www.google.com', new=0)
time.sleep(3)
ff.open_new('www.google.com')
time.sleep(3)
ff.open_new_tab('www.google.com')
msg101728 - (view) Author: Brian Curtin (brian.curtin) * (Python committer) Date: 2010-03-25 19:26
On Windows, the WindowsDefault class gets used and it doesn't make use of anything other than the URL (no 'new' or 'autoraise'). All it does is pass the URL onto os.startfile.

It should make a better attempt at running the URL. Patches welcome, or I'll try to come up with one shortly.
msg101732 - (view) Author: Brian Curtin (brian.curtin) * (Python committer) Date: 2010-03-25 21:06
Minor correction: BackgroundBrowser gets used in this case, but it still lacks in the same area and causes what you are seeing.
msg126265 - (view) Author: Dev Player (devplayer) Date: 2011-01-14 14:35
Don't forget to check if the MS Internet Explorer's advanced option to open new URLS in a seperate windows effects this.  Users can have this advanced setting set differently on different computers(or even accounts). Also different browser versions call that option by different names. And I think there may even be a way to turn off tabs altogether, so check that too.
msg224057 - (view) Author: Brandon Milam (jbmilam) * Date: 2014-07-26 14:38
In order to fix the issue I added on to the WindowsDefault class so that it is the main browser class for windows platforms as opposed to being a default when no other browser is given. I gave the class an init where it specifies specific flags for firefox, chrome, and internet explorer (from what I could find there aren't really new window or new tab flags for internet explorer). If the flags for other browsers are known they should be easy to add to this section.

        def __init__(self,browser = "windows-default"):
            # Grab the different flags for the different browser types
            browser.lower()
            self.browsername = browser
            # If get() is used without arguments browser will be passed None
            if browser == "windows_default" or browser == None:
                self.cmd = "start"
            elif browser == 'iexplore' or browser == 'internet explorer':
                self.cmd = "start iexplore"
                self.newwindow = ""
                self.newtab = ""
            elif browser == "chrome":
                self.cmd = "start chrome.exe"
                self.newwindow = "-new-window"
                self.newtab = "-new-tab"
            elif browser == "firefox":
                self.cmd = "start firefox.exe"
                self.newwindow = "-new-window"
                self.newtab = "-new-tab"
            else:
                raise Error('The browser you entered (%s) is not currently supported on windows' % browser)

In the open method of the WindowsDefault class I changed how the browser is opened by building a command from the flags and the cmd for the specific browser and used subprocess,call.

            # Format the command for optional arguments and add the url
            if new == 1:
                self.cmd += " " + self.newwindow
            elif new == 2:
                self.cmd += " " + self.newtab
            self.cmd += " " + url

            subprocess.call(self.cmd,shell = True)

This allows the user to input different new arguments to open a new window or new tab like the documentation says they should be able to do. I added a little bit to the beginning of the get function so that it passes its argument to the WindowsDefault class and returns that object on Windows systems.

    # Let the windows default class handle different browsers on windows
    if sys.platform[:3] == "win":
        return WindowsDefault(using)

This adds some of the desired compatibility but does not completely address the module's issues. I did not see a way to open a web page in a currently open page on any of the browsers, just new windows and new tabs (when no flags are passed the browsers default to one of these two options). Also the _isexecutable function's attempt at windows compatibility is still not working because I was unsure of how to use just a string of a browser name like 'chrome' to determine if a file is on a system. This leaves _tryorder not properly containing the browsers on the system. This leaves the module's open, open_new and open_new_tab not properly working either just the WindowsDefault open method.
Any feed back and direction from here is most welcome.
msg224060 - (view) Author: Brandon Milam (jbmilam) * Date: 2014-07-26 14:50
How the _isexecutable function is set up now it would require a full path name in order to be able to tell if a specific browser is on the system. The area under platform support for windows checks for multiple browsers using this function but only passes it browser names and so it always returns false and does not add any browsers to _tryorder. I found a way to fix this using os.walk so that the simple strings of the browser names like "firefox.exe" is able to actually able to be found on the system. This method is rather slow though and the module wants to check for 8 browsers when imported.
msg224796 - (view) Author: Brandon Milam (jbmilam) * Date: 2014-08-05 02:58
I got rid of the __init__ for the WindowsDefault class that I asked about earlier and changed it to match the sub-classing model that the Unix browsers use. This caused some changes in the get function too. Due to the _isexecutable still not completely working, the get function is hard coded for chrome, internet explorer and firefox for windows systems. This is my first attempt at making a patch file so if it is incorrect please bear with me.
msg241047 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2015-04-14 22:30
Some hints about finding browsers on Windows.

When browsers are installed, they should register themselves in HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet so that users can change their default browser through the OS.

On 64-bit systems, this is always in the 64-bit registry, so to open it you need OpenKeyEx and the KEY_WOW64_64KEY flag.

Each subkey of the key represents one browser, and the key name is a moniker while the default value of each subkey is a user-friendly name.

Under each subkey is a shell\open\command key that has the path for the browser in the default value. As far as I can tell this must be the path and cannot contain command-line arguments, and it may optionally have quotes (to handle spaces in the path).

I'd expect browsers to provide command-line arguments for opening in an existing window or a new one, but they will differ between browsers. and will require individual research (though it looks like the attached patch has some of them).
msg241057 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2015-04-14 23:28
> register themselves in HKEY_LOCAL_MACHINE\SOFTWARE\
> Clients\StartMenuInternet so that users can change their 
> default browser through the OS. On 64-bit systems, this 
> is always in the 64-bit registry

According to "Registry Keys Affected by WOW64", the "Clients" key is redirected in Vista and shared in Windows 7.

https://msdn.microsoft.com/en-us/library/aa384253

    import winreg

    HKLM = winreg.HKEY_LOCAL_MACHINE
    subkey = r'Software\Clients\StartMenuInternet'
    read32 = winreg.KEY_READ | winreg.KEY_WOW64_32KEY
    read64 = winreg.KEY_READ | winreg.KEY_WOW64_64KEY

    key32 = winreg.OpenKey(HKLM, subkey, access=read32)
    key64 = winreg.OpenKey(HKLM, subkey, access=read64)
    # This should be true in Windows 7.
    assert winreg.QueryInfoKey(key32) == winreg.QueryInfoKey(key64)

I don't have a Vista installation to confirm that it's really redirected. If so, it's important to enumerate the WOW64 redirected key as well, since 32-bit browsers are still common on Windows.
msg244219 - (view) Author: Brandon Milam (jbmilam) * Date: 2015-05-27 21:23
I kept the changes to the WindowsDefault.open() method and used and extended eryksun's code to build the browser list using the registry. Also I added support for a few more browsers. Some of the browsers I could not find ways to differentiate between opening a new window or new tab using command line flags. This also removed the hardcoding I had put in the get function.
msg244298 - (view) Author: Brandon Milam (jbmilam) * Date: 2015-05-28 13:25
I went ahead and took the assert statement out and added support for vista using a union of sets for both the 32 bit and 64 bit locations.
msg244299 - (view) Author: Brandon Milam (jbmilam) * Date: 2015-05-28 13:36
On second thought no type testing is required if sets are used because the union will take out duplicates anyways and so I removed the type testing and left in the set union code.
msg244606 - (view) Author: Brandon Milam (jbmilam) * Date: 2015-06-01 18:45
Forgive me the excessive number of patch submissions as I am still getting my feet wet in contributing to Python. I'm posting another patch that is not functionally different from the last patch but should better adhere to the PEP8 style guide.

Please let me know of any additional changes that need to be made or if a different functionality is preferred.
msg244769 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2015-06-03 16:34
I do like this fix, and I'm sorry I didn't get to reviewing it before beta 1 was released - can we consider this something to fix for 3.5 or do we need to slip it until 3.6?
msg244784 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-06-03 18:28
I haven't reviewed the patch, but if it only makes the existing API actually work for Windows, I think it would be fair game for 3.5.  Larry would need to make the call, though.
msg244843 - (view) Author: Brandon Milam (jbmilam) * Date: 2015-06-04 21:02
Here's a patch addressing all of the comments in the review. Changing the browsers from a set to a list though resulted in duplicates in the _tryorder list that were not present before because the set had filtered the duplicates before the partial string comparisons. The _browsers dictionary did not contain the duplicates so I don't think this will have any functional changes.
msg244851 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2015-06-05 00:53
Go ahead for beta 3.
msg244959 - (view) Author: Brandon Milam (jbmilam) * Date: 2015-06-07 16:26
Moved the 64 bit browser list to its own loop and switched to browsers.append rather than +=.
msg244968 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2015-06-07 19:03
That looks good to me, I'll get it merged in when I'm at my desk.
msg244986 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2015-06-08 04:38
New changeset b75c600e1614 by Steve Dower in branch '3.5':
Issue #8232: webbrowser support incomplete on Windows. Patch by Brandon Milam
https://hg.python.org/cpython/rev/b75c600e1614

New changeset 63b6e150b635 by Steve Dower in branch 'default':
Issue #8232: webbrowser support incomplete on Windows. Patch by Brandon Milam
https://hg.python.org/cpython/rev/63b6e150b635
msg245364 - (view) Author: Arfrever Frehtes Taifersar Arahesis (Arfrever) * (Python triager) Date: 2015-06-15 05:01
Official spelling of name of one of these browsers is "Firefox", not "FireFox". I suggest to rename WinFireFox class accordingly.
msg245372 - (view) Author: Boštjan Mejak (PedanticHacker) * Date: 2015-06-15 09:43
I agree with Arfrever Frehtes Taifersar Arahesis (oh my god, you have the longest name, dude!) to rename the class WinFireFox() to WinFirefox().

Okay, so since the branch '3.5' already got its patch webbrowserfix6 applied -- are you, Brandon Milam, willing to make a new webbrowserfix7 patch with the added WinFireFox() -> WinFirefox() classname change and then apply this new patch to the '3.4' branch as well as to the '3.5' branch?
msg245374 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2015-06-15 13:05
If it existed in 3.4 then we can only alias it now and not fix it. 3.5 and 3.6 can have the fix.
msg245377 - (view) Author: Arfrever Frehtes Taifersar Arahesis (Arfrever) * (Python triager) Date: 2015-06-15 14:34
Steve Dower: Maybe thou hast already forgotten, but WinFireFox class was added by thee (only in 3.5 and 3.6) just 7 days ago :) .
msg245382 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2015-06-15 15:39
That's what I thought, but I wasn't 100% sure it wasn't moved/rewritten in the patch and was on my phone so I didn't check :)
msg245385 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2015-06-15 16:11
New changeset 0d54a78861cf by Steve Dower in branch '3.5':
Issue #8232: Renamed WinFireFox to WinFirefox
https://hg.python.org/cpython/rev/0d54a78861cf

New changeset 8667c26e2bec by Steve Dower in branch 'default':
Issue #8232: Renamed WinFireFox to WinFirefox
https://hg.python.org/cpython/rev/8667c26e2bec
msg245386 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2015-06-15 16:12
I'll close this as fixed, but feel free to speak up if you spot anything else that needs fixing.
msg245387 - (view) Author: Boštjan Mejak (PedanticHacker) * Date: 2015-06-15 16:20
Now that this bug is completely fixed, can you backport this to the '3.4' branch, so that we'll be able to use webbrowser. get() in Python 3.4.4 when it becomes available?
msg245388 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2015-06-15 16:30
The 3.4 RM is already nosied - what say you, sir?
msg245389 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2015-06-15 16:33
Sorry, but I think this is more accurately described as a "new feature" than a "bugfix".  Please don't backport this to 3.4.
msg245390 - (view) Author: Boštjan Mejak (PedanticHacker) * Date: 2015-06-15 16:37
No, Larry, this is not a new feature. The feature, as it stands, is broken in Python 3.4, so we need to fix it.
msg245391 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2015-06-15 16:38
This is not a bugfix to existing code.  This is new code to implement a missing feature.
msg245392 - (view) Author: Boštjan Mejak (PedanticHacker) * Date: 2015-06-15 16:41
Sure, let's have a broken feature in Python 3.4, who cares.
msg245393 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2015-06-15 16:44
Rules like this are there for a reason.  People rely on Python being consistent.  We've added harmless new features to point releases in the past and broken people's code.  So, we don't do it anymore.

It's not because we don't care, it's because stability is more important than new features.
msg245394 - (view) Author: Boštjan Mejak (PedanticHacker) * Date: 2015-06-15 17:09
I understand. I know that Python 3.4 is way past feature freeze.

But if we document the new stuff in the documentation, saying "Added to Python 3.4.4", people would know about and be able to use the new stuff. And we won't break people's code. In fact, people might benefit from this particular new feature.

People's Python 3.4 code like  webbrowser.get("chrome")  would then start to work, plus they'd benefit from this new stuff added by Brandon Milam.

Don't you find that a great thing to be?
msg245396 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2015-06-15 17:18
Yes, which is why I permitted a feature freeze exception for it for 3.5.  But it's simply far, far too late to add a feature like this to 3.4.
msg245398 - (view) Author: Boštjan Mejak (PedanticHacker) * Date: 2015-06-15 17:36
I understand. But then  webbrowser.get("chrome") won't ever work in Python 3.4. Is there no other way to fix this bug in Python 3.4 without adding the new feature?
msg245399 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2015-06-15 17:38
Fairly sure webbrowser.py is stand-alone enough that you could redist it with your package easily enough. None of the rest of the stdlib should depend on the internals, AFAIK.
msg245400 - (view) Author: Boštjan Mejak (PedanticHacker) * Date: 2015-06-15 17:55
Steve, I know. But it's a hassle for a newcomer to fix Python first before he/she uses it. I'm not a newcomer, but even I don't know how to fix webbrowser.py, more specifically the webbrowser.get() method,  to be able to use it.

Maybe I should copy webbrowser.py from Python 3.5 and paste it to my Python 3.4.3. Sounds good, right?
msg245401 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2015-06-15 18:10
Sure, you can do that. You can also copy-paste it into your project to get the same effect.
msg245404 - (view) Author: Boštjan Mejak (PedanticHacker) * Date: 2015-06-15 19:41
Ah, interesting! But which webbrowser module would Python import if I have one webbrowser.py in my interpreter's directory and one webbrowser.py in the directory of my application?
msg245405 - (view) Author: Boštjan Mejak (PedanticHacker) * Date: 2015-06-15 20:31
No need to answer. Python used the  webbrowser  module that was located in the directory of my application and not the one from the interpreter's directory. That's great!
msg250067 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2015-09-07 05:36
This was backed out of 3.5, as we discovered it introduced a security hole just before 3.5.0 shipped.  (See issue 25005 for more.)

Since it's been backed out, I've reopened the issue.  However I've moved it forward to 3.6, as it's no longer viable to accept for 3.5.
msg250072 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2015-09-07 05:38
New changeset aa60b34d5200 by Steve Dower in branch '3.5':
Issue #25005: Backout fix for #8232 because of use of unsafe subprocess.call(shell=True)
https://hg.python.org/cpython/rev/aa60b34d5200

New changeset 7d320c3bf9c6 by Larry Hastings in branch '3.5':
Merged in stevedower/cpython350 (pull request #20)
https://hg.python.org/cpython/rev/7d320c3bf9c6
msg250074 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2015-09-07 05:49
Here's an alternate patch I proposed on #25005 before we decided to back out the change.

The problem is that subprocess.call() with shell=True is unsafe because we don't escape shell operators (such as &, <, >, |).

The fix in this patch is to allow passing arguments to os.startfile so we can use that instead. Arguments do not need to be escaped in this case.
msg250112 - (view) Author: Brandon Milam (jbmilam) * Date: 2015-09-07 15:00
applying 25005_1.patch
patching file Lib/webbrowser.py
Hunk #1 FAILED at 498
Hunk #2 FAILED at 524
Hunk #3 FAILED at 532
Hunk #4 FAILED at 540
Hunk #5 FAILED at 548
I'm trying to apply your patch after applying webbrowserfix6.patch but I am encountering problems. I first tried "hg import --no-commit file.patch" for both patches but it wouldn't let me use the command two times in a row without committing the changes for the first one so I tried committing the webbrowserfix6.patch changes and then using the import command and I get this error message. I would like to try to make sure the code still does what it is supposed to but I can't check until I can get both patches in.

Hunk #6 FAILED at 556
6 out of 6 hunks FAILED -- saving rejects to file Lib/webbrowser.py.rej
patching file Modules/posixmodule.c
Hunk #1 FAILED at 10522
Hunk #2 FAILED at 10578
Hunk #3 FAILED at 10590
Hunk #4 FAILED at 10606
Hunk #5 FAILED at 10616
5 out of 5 hunks FAILED -- saving rejects to file Modules/posixmodule.c.rej
abort: patch failed to apply
msg250114 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2015-09-07 15:38
Try doing:

hg up -r 4e329892817c1eed81aafd14e82b8ef23b45a6e6
hg import --no-commit http://bugs.python.org/file40384/25005_1.patch

That *should* apply it where I originally made it from. I'll do the same and rebase the patch against tip.
msg250115 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2015-09-07 15:40
New patch against 3.6.
msg250117 - (view) Author: Brandon Milam (jbmilam) * Date: 2015-09-07 16:57
Ok I've been able to test the new patch now and I'm not sure that os.startfile is going to work. I've been able to get os.startfile() to open a specified browser (>>> os.startfile("chrome.exe", "open")), however, the function does not allow additional arguments(>>> os.startfile("chrome.exe", "open", "www.yahoo.com")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: startfile() takes at most 2 arguments (3 given))) so not even a url will be allowed to be specified as the code is written in the patch let alone specifying new window or new tab. Is this an error on os.startfile's part? The documentation for it seems to indicate that it should take multiple inputs. I don't have much experience with C to be able to find out figure out what the rest of your patch accomplished.
msg250121 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2015-09-07 17:38
The C part of the patch adds an extra argument to startfile to accept the arguments. You'll need to rebuild Python to test the change completely - it's no longer just a pure Python change.
msg250135 - (view) Author: Brandon Milam (jbmilam) * Date: 2015-09-07 22:56
Finally got it rebuilt after having trouble with visual studio for awhile. I've tested the new patch and it is still able to properly find both chrome and firefox and is able to differentiate between new window and new tab for those two browsers so it appears to still be working.
msg261704 - (view) Author: Brandon Milam (jbmilam) * Date: 2016-03-13 19:03
I've tested the new patch and it is still able to properly find both chrome and firefox and is able to differentiate between new window and new tab for those two browsers so it is still working. Would someone review the patch?
msg290930 - (view) Author: Mariatta (Mariatta) * (Python committer) Date: 2017-03-31 17:22
Steve, would you like to create a PR based on your patch here?

Also, what versions should this be targeted to now?
 
Thanks.
msg290935 - (view) Author: Boštjan Mejak (PedanticHacker) * Date: 2017-03-31 18:01
I have Windows 10, 64-bit, and Python 3.6.1, 64-bit, and the code still does not work!

>>> import webbrowser
>>> webbrowser.get("chrome")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files\Python 3.6\lib\webbrowser.py", line 51, in get
    raise Error("could not locate runnable browser")
webbrowser.Error: could not locate runnable browser

Note: Yes, my Google Chrome browser was running when this command was executed.
msg388993 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2021-03-18 07:42
Windows Vista is no longer a concern, so find_windows_browsers() doesn't have to worry about the KEY_WOW64_* flags. IMO, it should get the browser's real name (the default value of the key) and the fully-qualified path of the executable, instead of depending solely on an "App Paths" entry being configured for the base executable name. For example:

    def find_windows_browsers():
        """ Read the installed browsers from the Windows registry."""
        import winreg
        browsers = []
        with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
                r"Software\Clients\StartMenuInternet") as hkey:
            i = 0
            while True:
                try:
                    subkey = winreg.EnumKey(hkey, i)
                    i += 1
                except OSError as e:
                    if e.winerror != 259: # ERROR_NO_MORE_ITEMS
                        raise
                    break
                try:
                    name = winreg.QueryValue(hkey, subkey)
                    if not name or not isinstance(name, str):
                        name = subkey
                except OSError:
                    name = subkey
                try:
                    cmd = winreg.QueryValue(hkey, rf"{subkey}\shell\open\command")
                    cmd = cmd.strip('"')
                    os.stat(cmd)
                except (OSError, AttributeError, TypeError, ValueError):
                    cmd = ""
                browsers.append((name, cmd))
        return browsers

The loop over the result would change to `for browser, cmd in find_windows_browsers()`. The string to match for Internet Explorer, using the real name instead of the registry key name, would be "internet explorer". A class for Microsoft Edge ("msedge") should be added.

The browser would get instantiated with the cmd value, which ideally is the fully-qualified path of the executable. The fallback behavior wouldn't change for the case where self.cmd is an empty string. For example:

    class WindowsDefault(BaseBrowser):
        cmd = newwindow = newtab = ""

        def __init__(self, name="", cmd=""):
            super().__init__(name)
            if cmd:
                self.cmd = cmd
        ...
History
Date User Action Args
2022-04-11 14:56:59adminsetgithub: 52479
2021-03-18 07:42:50eryksunsetmessages: + msg388993
2021-03-18 07:25:52eryksunsetnosy: + paul.moore, tim.golden, zach.ware
dependencies: + [Windows] support args and cwd in os.startfile()

components: + Windows
versions: + Python 3.10, - Python 3.6
2017-03-31 18:01:40PedanticHackersetmessages: + msg290935
2017-03-31 17:22:26Mariattasetnosy: + Mariatta
messages: + msg290930
2016-06-20 13:42:12willingcsetstage: needs patch -> patch review
2016-03-13 19:03:10jbmilamsetmessages: + msg261704
2015-09-07 22:56:13jbmilamsetmessages: + msg250135
2015-09-07 17:38:14steve.dowersetmessages: + msg250121
2015-09-07 16:57:40jbmilamsetmessages: + msg250117
2015-09-07 15:40:12steve.dowersetfiles: + 8232_1.patch

messages: + msg250115
2015-09-07 15:38:15steve.dowersetmessages: + msg250114
2015-09-07 15:00:32jbmilamsetmessages: + msg250112
2015-09-07 05:49:54steve.dowersetfiles: + 25005_1.patch

messages: + msg250074
2015-09-07 05:38:06python-devsetmessages: + msg250072
2015-09-07 05:36:44larrysetnosy: - larry
2015-09-07 05:36:25larrysetstatus: closed -> open
versions: + Python 3.6, - Python 3.5
messages: + msg250067

resolution: fixed ->
stage: resolved -> needs patch
2015-06-15 20:31:17PedanticHackersetmessages: + msg245405
2015-06-15 19:41:31PedanticHackersetmessages: + msg245404
2015-06-15 18:10:06steve.dowersetmessages: + msg245401
2015-06-15 17:55:21PedanticHackersetmessages: + msg245400
2015-06-15 17:38:24steve.dowersetmessages: + msg245399
2015-06-15 17:36:05PedanticHackersetmessages: + msg245398
2015-06-15 17:18:02larrysetmessages: + msg245396
2015-06-15 17:09:25PedanticHackersetmessages: + msg245394
2015-06-15 16:44:32larrysetmessages: + msg245393
2015-06-15 16:41:16PedanticHackersetmessages: + msg245392
2015-06-15 16:38:32larrysetmessages: + msg245391
2015-06-15 16:37:22PedanticHackersetmessages: + msg245390
2015-06-15 16:33:51larrysetmessages: + msg245389
2015-06-15 16:30:56steve.dowersetmessages: + msg245388
2015-06-15 16:20:43PedanticHackersetmessages: + msg245387
2015-06-15 16:12:47steve.dowersetstatus: open -> closed
resolution: fixed
messages: + msg245386

stage: patch review -> resolved
2015-06-15 16:11:56python-devsetmessages: + msg245385
2015-06-15 15:39:12steve.dowersetmessages: + msg245382
2015-06-15 14:34:27Arfreversetmessages: + msg245377
2015-06-15 13:05:38steve.dowersetmessages: + msg245374
2015-06-15 09:43:12PedanticHackersetnosy: + PedanticHacker
messages: + msg245372
2015-06-15 05:01:39Arfreversetnosy: + Arfrever
messages: + msg245364
2015-06-08 04:38:13python-devsetnosy: + python-dev
messages: + msg244986
2015-06-07 19:03:26steve.dowersetmessages: + msg244968
2015-06-07 16:26:25jbmilamsetfiles: + webbrowserfix6.patch

messages: + msg244959
2015-06-05 00:53:00larrysetmessages: + msg244851
2015-06-04 21:02:51jbmilamsetfiles: + webbrowserfix5.patch

messages: + msg244843
2015-06-03 18:28:29r.david.murraysetnosy: + larry, r.david.murray
messages: + msg244784
2015-06-03 16:34:06steve.dowersetmessages: + msg244769
2015-06-01 18:45:28jbmilamsetfiles: + webbrowserfix4.patch

messages: + msg244606
2015-05-28 13:36:01jbmilamsetfiles: + webbrowserfix3.patch

messages: + msg244299
2015-05-28 13:25:49jbmilamsetfiles: + webbrowserfix3.patch

messages: + msg244298
2015-05-27 21:23:48jbmilamsetfiles: + webbrowserfix2.patch

messages: + msg244219
2015-04-14 23:28:28eryksunsetnosy: + eryksun
messages: + msg241057
2015-04-14 22:30:46steve.dowersetnosy: + steve.dower
messages: + msg241047
2014-08-05 03:08:02zach.waresetstage: needs patch -> patch review
versions: + Python 3.5, - Python 3.1
2014-08-05 02:58:57jbmilamsetfiles: + webbrowserfix.patch
keywords: + patch
messages: + msg224796
2014-07-28 15:39:15brian.curtinsetnosy: - brian.curtin
2014-07-26 14:50:12jbmilamsetmessages: + msg224060
2014-07-26 14:38:33jbmilamsetfiles: + webbrowserdebug.py
nosy: + jbmilam
messages: + msg224057

2011-01-14 14:35:26devplayersetnosy: + devplayer
messages: + msg126265
2010-03-25 21:06:50brian.curtinsetmessages: + msg101732
2010-03-25 19:26:42brian.curtinsettitle: webbrowser open(), open_new(), and open_new_tab() Broken Functionality -> webbrowser.open incomplete on Windows
2010-03-25 19:26:05brian.curtinsetpriority: normal

nosy: + brian.curtin
messages: + msg101728

stage: needs patch
2010-03-25 18:32:39joncwchaocreate