prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  [Question]: How to get the right BrowserType from a device name? 
  ### Your question
  
  I noticed that the CLI is able to figure out the right `BrowserType` to use when it is launched from the command line:
  
  ```
  playwright open --device="Desktop Safari" wikipedia.org  # Webkit
  playwright open --device="Desktop Firefox" wikipedia.org  # Firefox
  playwright open --device="Desktop Chrome" wikipedia.org  # Chrome
  ``` 
  
  But [the documentation](https://playwright.dev/python/docs/api/class-playwright#playwright-devices) seems to say that I have to initialize a `BrowserType` before I can pass the settings to the context, which partially defeats the purpose of the device settings.
  
  I can implement my own logic do initialize the right `BrowserType` for each device, but as `playwright open` can already do that, that seems superfluous.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `playwright/_impl/_playwright.py`
  Content:
  ```
  1 # Copyright (c) Microsoft Corporation.
  2 #
  3 # Licensed under the Apache License, Version 2.0 (the "License");
  4 # you may not use this file except in compliance with the License.
  5 # You may obtain a copy of the License at
  6 #
  7 # http://www.apache.org/licenses/LICENSE-2.0
  8 #
  9 # Unless required by applicable law or agreed to in writing, software
  10 # distributed under the License is distributed on an "AS IS" BASIS,
  11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12 # See the License for the specific language governing permissions and
  13 # limitations under the License.
  14 
  15 from typing import Dict
  16 
  17 from playwright._impl._browser_type import BrowserType
  18 from playwright._impl._connection import ChannelOwner, from_channel
  19 from playwright._impl._fetch import APIRequest
  20 from playwright._impl._local_utils import LocalUtils
  21 from playwright._impl._selectors import Selectors, SelectorsOwner
  22 
  23 
  24 class Playwright(ChannelOwner):
  25     devices: Dict
  26     selectors: Selectors
  27     chromium: BrowserType
  28     firefox: BrowserType
  29     webkit: BrowserType
  30     request: APIRequest
  31 
  32     def __init__(
  33         self, parent: ChannelOwner, type: str, guid: str, initializer: Dict
  34     ) -> None:
  35         super().__init__(parent, type, guid, initializer)
  36         self.request = APIRequest(self)
  37         self.chromium = from_channel(initializer["chromium"])
  38         self.chromium._playwright = self
  39         self.firefox = from_channel(initializer["firefox"])
  40         self.firefox._playwright = self
  41         self.webkit = from_channel(initializer["webkit"])
  42         self.webkit._playwright = self
  43 
  44         self.selectors = Selectors(self._loop, self._dispatcher_fiber)
  45         selectors_owner: SelectorsOwner = from_channel(initializer["selectors"])
  46         self.selectors._add_channel(selectors_owner)
  47 
  48         self._connection.on(
  49             "close", lambda: self.selectors._remove_channel(selectors_owner)
  50         )
  51         self.devices = {}
  52         self.devices = {
  53             device["name"]: parse_device_descriptor(device["descriptor"])
  54             for device in initializer["deviceDescriptors"]
  55         }
  56         self._utils: LocalUtils = from_channel(initializer["utils"])
  57 
  58     def __getitem__(self, value: str) -> "BrowserType":
  59         if value == "chromium":
  60             return self.chromium
  61         elif value == "firefox":
  62             return self.firefox
  63         elif value == "webkit":
  64             return self.webkit
  65         raise ValueError("Invalid browser " + value)
  66 
  67     def _set_selectors(self, selectors: SelectorsOwner) -> None:
  68         selectors_owner = from_channel(self._initializer["selectors"])
  69         self.selectors._remove_channel(selectors_owner)
  70         self.selectors = selectors
  71         self.selectors._add_channel(selectors_owner)
  72 
  73     def stop(self) -> None:
  74         pass
  75 
  76 
  77 def parse_device_descriptor(dict: Dict) -> Dict:
  78     return {
  79         "user_agent": dict["userAgent"],
  80         "viewport": dict["viewport"],
  81         "device_scale_factor": dict["deviceScaleFactor"],
  82         "is_mobile": dict["isMobile"],
  83         "has_touch": dict["hasTouch"],
  84     }
  85
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/playwright/_impl/_playwright.py b/playwright/_impl/_playwright.py
  --- a/playwright/_impl/_playwright.py
  +++ b/playwright/_impl/_playwright.py
  @@ -81,4 +81,5 @@
           "device_scale_factor": dict["deviceScaleFactor"],
           "is_mobile": dict["isMobile"],
           "has_touch": dict["hasTouch"],
  +        "default_browser_type": dict["defaultBrowserType"],
       }
  
verification_info: {"golden_diff": "diff --git a/playwright/_impl/_playwright.py b/playwright/_impl/_playwright.py\n--- a/playwright/_impl/_playwright.py\n+++ b/playwright/_impl/_playwright.py\n@@ -81,4 +81,5 @@\n         \"device_scale_factor\": dict[\"deviceScaleFactor\"],\n         \"is_mobile\": dict[\"isMobile\"],\n         \"has_touch\": dict[\"hasTouch\"],\n+        \"default_browser_type\": dict[\"defaultBrowserType\"],\n     }\n", "issue": "[Question]: How to get the right BrowserType from a device name? \n### Your question\n\nI noticed that the CLI is able to figure out the right `BrowserType` to use when it is launched from the command line:\r\n\r\n```\r\nplaywright open --device=\"Desktop Safari\" wikipedia.org  # Webkit\r\nplaywright open --device=\"Desktop Firefox\" wikipedia.org  # Firefox\r\nplaywright open --device=\"Desktop Chrome\" wikipedia.org  # Chrome\r\n``` \r\n\r\nBut [the documentation](https://playwright.dev/python/docs/api/class-playwright#playwright-devices) seems to say that I have to initialize a `BrowserType` before I can pass the settings to the context, which partially defeats the purpose of the device settings.\r\n\r\nI can implement my own logic do initialize the right `BrowserType` for each device, but as `playwright open` can already do that, that seems superfluous.\n", "before_files": [{"content": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom typing import Dict\n\nfrom playwright._impl._browser_type import BrowserType\nfrom playwright._impl._connection import ChannelOwner, from_channel\nfrom playwright._impl._fetch import APIRequest\nfrom playwright._impl._local_utils import LocalUtils\nfrom playwright._impl._selectors import Selectors, SelectorsOwner\n\n\nclass Playwright(ChannelOwner):\n    devices: Dict\n    selectors: Selectors\n    chromium: BrowserType\n    firefox: BrowserType\n    webkit: BrowserType\n    request: APIRequest\n\n    def __init__(\n        self, parent: ChannelOwner, type: str, guid: str, initializer: Dict\n    ) -> None:\n        super().__init__(parent, type, guid, initializer)\n        self.request = APIRequest(self)\n        self.chromium = from_channel(initializer[\"chromium\"])\n        self.chromium._playwright = self\n        self.firefox = from_channel(initializer[\"firefox\"])\n        self.firefox._playwright = self\n        self.webkit = from_channel(initializer[\"webkit\"])\n        self.webkit._playwright = self\n\n        self.selectors = Selectors(self._loop, self._dispatcher_fiber)\n        selectors_owner: SelectorsOwner = from_channel(initializer[\"selectors\"])\n        self.selectors._add_channel(selectors_owner)\n\n        self._connection.on(\n            \"close\", lambda: self.selectors._remove_channel(selectors_owner)\n        )\n        self.devices = {}\n        self.devices = {\n            device[\"name\"]: parse_device_descriptor(device[\"descriptor\"])\n            for device in initializer[\"deviceDescriptors\"]\n        }\n        self._utils: LocalUtils = from_channel(initializer[\"utils\"])\n\n    def __getitem__(self, value: str) -> \"BrowserType\":\n        if value == \"chromium\":\n            return self.chromium\n        elif value == \"firefox\":\n            return self.firefox\n        elif value == \"webkit\":\n            return self.webkit\n        raise ValueError(\"Invalid browser \" + value)\n\n    def _set_selectors(self, selectors: SelectorsOwner) -> None:\n        selectors_owner = from_channel(self._initializer[\"selectors\"])\n        self.selectors._remove_channel(selectors_owner)\n        self.selectors = selectors\n        self.selectors._add_channel(selectors_owner)\n\n    def stop(self) -> None:\n        pass\n\n\ndef parse_device_descriptor(dict: Dict) -> Dict:\n    return {\n        \"user_agent\": dict[\"userAgent\"],\n        \"viewport\": dict[\"viewport\"],\n        \"device_scale_factor\": dict[\"deviceScaleFactor\"],\n        \"is_mobile\": dict[\"isMobile\"],\n        \"has_touch\": dict[\"hasTouch\"],\n    }\n", "path": "playwright/_impl/_playwright.py"}], "after_files": [{"content": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom typing import Dict\n\nfrom playwright._impl._browser_type import BrowserType\nfrom playwright._impl._connection import ChannelOwner, from_channel\nfrom playwright._impl._fetch import APIRequest\nfrom playwright._impl._local_utils import LocalUtils\nfrom playwright._impl._selectors import Selectors, SelectorsOwner\n\n\nclass Playwright(ChannelOwner):\n    devices: Dict\n    selectors: Selectors\n    chromium: BrowserType\n    firefox: BrowserType\n    webkit: BrowserType\n    request: APIRequest\n\n    def __init__(\n        self, parent: ChannelOwner, type: str, guid: str, initializer: Dict\n    ) -> None:\n        super().__init__(parent, type, guid, initializer)\n        self.request = APIRequest(self)\n        self.chromium = from_channel(initializer[\"chromium\"])\n        self.chromium._playwright = self\n        self.firefox = from_channel(initializer[\"firefox\"])\n        self.firefox._playwright = self\n        self.webkit = from_channel(initializer[\"webkit\"])\n        self.webkit._playwright = self\n\n        self.selectors = Selectors(self._loop, self._dispatcher_fiber)\n        selectors_owner: SelectorsOwner = from_channel(initializer[\"selectors\"])\n        self.selectors._add_channel(selectors_owner)\n\n        self._connection.on(\n            \"close\", lambda: self.selectors._remove_channel(selectors_owner)\n        )\n        self.devices = {}\n        self.devices = {\n            device[\"name\"]: parse_device_descriptor(device[\"descriptor\"])\n            for device in initializer[\"deviceDescriptors\"]\n        }\n        self._utils: LocalUtils = from_channel(initializer[\"utils\"])\n\n    def __getitem__(self, value: str) -> \"BrowserType\":\n        if value == \"chromium\":\n            return self.chromium\n        elif value == \"firefox\":\n            return self.firefox\n        elif value == \"webkit\":\n            return self.webkit\n        raise ValueError(\"Invalid browser \" + value)\n\n    def _set_selectors(self, selectors: SelectorsOwner) -> None:\n        selectors_owner = from_channel(self._initializer[\"selectors\"])\n        self.selectors._remove_channel(selectors_owner)\n        self.selectors = selectors\n        self.selectors._add_channel(selectors_owner)\n\n    def stop(self) -> None:\n        pass\n\n\ndef parse_device_descriptor(dict: Dict) -> Dict:\n    return {\n        \"user_agent\": dict[\"userAgent\"],\n        \"viewport\": dict[\"viewport\"],\n        \"device_scale_factor\": dict[\"deviceScaleFactor\"],\n        \"is_mobile\": dict[\"isMobile\"],\n        \"has_touch\": dict[\"hasTouch\"],\n        \"default_browser_type\": dict[\"defaultBrowserType\"],\n    }\n", "path": "playwright/_impl/_playwright.py"}]}