We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Inspect fails to retrieve module inside frozen app
# Description of the issue

when freezing playwright with [pyinstaller](https://github.com/pyinstaller/pyinstaller) the assertion in [`get_file_dirname`](https://github.com/microsoft/playwright-python/blob/master/playwright/path_utils.py#L19-L24) fails

```
  File "main.py", line 6, in <module>
    with sync_playwright() as p:
  File "playwright/__init__.py", line 34, in sync_playwright
  File "playwright/main.py", line 81, in __init__
  File "playwright/main.py", line 76, in run_driver
  File "asyncio/base_events.py", line 587, in run_until_complete
  File "playwright/main.py", line 44, in run_driver_async
  File "playwright/main.py", line 36, in compute_driver_executable
  File "playwright/path_utils.py", line 23, in get_file_dirname
AssertionError
```

The reason is that the inspect module fails to find the module on the following lines inside [`get_file_dirname`](https://github.com/microsoft/playwright-python/blob/master/playwright/path_utils.py#L19-L24)

```python
frame = inspect.stack()[1]
module = inspect.getmodule(frame[0])
```

# Context information

* version of python: 3.7.9
* version of pyinstaller: 4.1
* version of playwright-python: Version 0.162.1
* platform: GNU/Linux (Ubuntu 18.04 LTS)

# Reproducing the bug

install packages

    $ pip install playwright pyinstaller

install the browsers inside playwright

    $ PLAYWRIGHT_BROWSERS_PATH=0 python -m playwright install

create `main.py`

```python
# main.py
import sys
from pathlib import Path
from playwright import sync_playwright

with sync_playwright() as p:
    for browser_type in [p.chromium]:
        browser = browser_type.launch(
            headless=False,
            executablePath=Path(sys.modules['playwright'].__file__).parent / 'driver' / '.local-browsers' / 'chromium-827102' / 'chrome-linux' / 'chrome')
        page = browser.newPage()
        page.goto('http://whatsmyuseragent.org/')
        page.screenshot(path=f'example-{browser_type.name}.png')
        browser.close()
```

freeze into single binary file with pyinstaller

    $ pyinstaller -F main.py --add-data /path/to/lib/python3.7/site-packages/playwright/driver:playwright/driver

execute the binary file

```
$ ./dist/main 
Traceback (most recent call last):
  File "main.py", line 6, in <module>
    with sync_playwright() as p:
  File "playwright/__init__.py", line 34, in sync_playwright
  File "playwright/main.py", line 81, in __init__
  File "playwright/main.py", line 76, in run_driver
  File "asyncio/base_events.py", line 587, in run_until_complete
  File "playwright/main.py", line 44, in run_driver_async
  File "playwright/main.py", line 36, in compute_driver_executable
  File "playwright/path_utils.py", line 23, in get_file_dirname
AssertionError
```

# Proposed solution

The problem can be fixed by changing  [`get_file_dirname`](https://github.com/microsoft/playwright-python/blob/master/playwright/path_utils.py#L19-L24) with

```python
import inspect
import sys
from pathlib import Path

def get_file_dirname() -> Path:
    """Returns the callee (`__file__`) directory name"""
    module_name = inspect.currentframe().f_back.f_globals["__name__"]
    module = sys.modules[module_name]
    assert module
    return Path(module.__file__).parent.absolute()
```

--- 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/main.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 import asyncio
16 import os
17 import subprocess
18 import sys
19 from pathlib import Path
20 from typing import Any
21 
22 from greenlet import greenlet
23 
24 from playwright.async_api import Playwright as AsyncPlaywright
25 from playwright.connection import Connection
26 from playwright.helper import Error
27 from playwright.object_factory import create_remote_object
28 from playwright.path_utils import get_file_dirname
29 from playwright.playwright import Playwright
30 from playwright.sync_api import Playwright as SyncPlaywright
31 
32 
33 def compute_driver_executable() -> Path:
34     package_path = get_file_dirname()
35     platform = sys.platform
36     if platform == "win32":
37         return package_path / "driver" / "playwright-cli.exe"
38     return package_path / "driver" / "playwright-cli"
39 
40 
41 class SyncPlaywrightContextManager:
42     def __init__(self) -> None:
43         self._playwright: SyncPlaywright
44 
45     def __enter__(self) -> SyncPlaywright:
46         def greenlet_main() -> None:
47             loop = None
48             own_loop = None
49             try:
50                 loop = asyncio.get_running_loop()
51             except RuntimeError:
52                 loop = asyncio.new_event_loop()
53                 own_loop = loop
54 
55             if loop.is_running():
56                 raise Error("Can only run one Playwright at a time.")
57 
58             loop.run_until_complete(self._connection.run_as_sync())
59 
60             if own_loop:
61                 loop.run_until_complete(loop.shutdown_asyncgens())
62                 loop.close()
63 
64         dispatcher_fiber = greenlet(greenlet_main)
65         self._connection = Connection(
66             dispatcher_fiber, create_remote_object, compute_driver_executable()
67         )
68 
69         g_self = greenlet.getcurrent()
70 
71         def callback_wrapper(playwright_impl: Playwright) -> None:
72             self._playwright = SyncPlaywright(playwright_impl)
73             g_self.switch()
74 
75         self._connection.call_on_object_with_known_name("Playwright", callback_wrapper)
76 
77         dispatcher_fiber.switch()
78         playwright = self._playwright
79         playwright.stop = self.__exit__  # type: ignore
80         return playwright
81 
82     def start(self) -> SyncPlaywright:
83         return self.__enter__()
84 
85     def __exit__(self, *args: Any) -> None:
86         self._connection.stop_sync()
87 
88 
89 class AsyncPlaywrightContextManager:
90     def __init__(self) -> None:
91         self._connection: Connection
92 
93     async def __aenter__(self) -> AsyncPlaywright:
94         self._connection = Connection(
95             None, create_remote_object, compute_driver_executable()
96         )
97         loop = asyncio.get_running_loop()
98         self._connection._loop = loop
99         loop.create_task(self._connection.run())
100         playwright = AsyncPlaywright(
101             await self._connection.wait_for_object_with_known_name("Playwright")
102         )
103         playwright.stop = self.__aexit__  # type: ignore
104         return playwright
105 
106     async def start(self) -> AsyncPlaywright:
107         return await self.__aenter__()
108 
109     async def __aexit__(self, *args: Any) -> None:
110         self._connection.stop_async()
111 
112 
113 if sys.version_info.major == 3 and sys.version_info.minor == 7:
114     if sys.platform == "win32":
115         # Use ProactorEventLoop in 3.7, which is default in 3.8
116         asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
117     else:
118         # Prevent Python 3.7 from throwing on Linux:
119         # RuntimeError: Cannot add child handler, the child watcher does not have a loop attached
120         asyncio.get_event_loop()
121         asyncio.get_child_watcher()
122 
123 
124 def main() -> None:
125     driver_executable = compute_driver_executable()
126     my_env = os.environ.copy()
127     my_env["PW_CLI_TARGET_LANG"] = "python"
128     subprocess.run([str(driver_executable), *sys.argv[1:]], env=my_env)
129
```
--- 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()

```

diff --git a/playwright/main.py b/playwright/main.py
--- a/playwright/main.py
+++ b/playwright/main.py
@@ -13,6 +13,7 @@
 # limitations under the License.
 
 import asyncio
+import inspect
 import os
 import subprocess
 import sys
@@ -21,18 +22,18 @@
 
 from greenlet import greenlet
 
+import playwright
 from playwright.async_api import Playwright as AsyncPlaywright
 from playwright.connection import Connection
 from playwright.helper import Error
 from playwright.object_factory import create_remote_object
-from playwright.path_utils import get_file_dirname
 from playwright.playwright import Playwright
 from playwright.sync_api import Playwright as SyncPlaywright
 from playwright.sync_base import dispatcher_fiber, set_dispatcher_fiber
 
 
 def compute_driver_executable() -> Path:
-    package_path = get_file_dirname()
+    package_path = Path(inspect.getfile(playwright)).parent
     platform = sys.platform
     if platform == "win32":
         return package_path / "driver" / "playwright-cli.exe"

{"golden_diff": "diff --git a/playwright/main.py b/playwright/main.py\n--- a/playwright/main.py\n+++ b/playwright/main.py\n@@ -13,6 +13,7 @@\n # limitations under the License.\n \n import asyncio\n+import inspect\n import os\n import subprocess\n import sys\n@@ -21,18 +22,18 @@\n \n from greenlet import greenlet\n \n+import playwright\n from playwright.async_api import Playwright as AsyncPlaywright\n from playwright.connection import Connection\n from playwright.helper import Error\n from playwright.object_factory import create_remote_object\n-from playwright.path_utils import get_file_dirname\n from playwright.playwright import Playwright\n from playwright.sync_api import Playwright as SyncPlaywright\n from playwright.sync_base import dispatcher_fiber, set_dispatcher_fiber\n \n \n def compute_driver_executable() -> Path:\n-    package_path = get_file_dirname()\n+    package_path = Path(inspect.getfile(playwright)).parent\n     platform = sys.platform\n     if platform == \"win32\":\n         return package_path / \"driver\" / \"playwright-cli.exe\"\n", "issue": "Inspect fails to retrieve module inside frozen app\n# Description of the issue\r\n\r\nwhen freezing playwright with [pyinstaller](https://github.com/pyinstaller/pyinstaller) the assertion in [`get_file_dirname`](https://github.com/microsoft/playwright-python/blob/master/playwright/path_utils.py#L19-L24) fails\r\n\r\n```\r\n  File \"main.py\", line 6, in <module>\r\n    with sync_playwright() as p:\r\n  File \"playwright/__init__.py\", line 34, in sync_playwright\r\n  File \"playwright/main.py\", line 81, in __init__\r\n  File \"playwright/main.py\", line 76, in run_driver\r\n  File \"asyncio/base_events.py\", line 587, in run_until_complete\r\n  File \"playwright/main.py\", line 44, in run_driver_async\r\n  File \"playwright/main.py\", line 36, in compute_driver_executable\r\n  File \"playwright/path_utils.py\", line 23, in get_file_dirname\r\nAssertionError\r\n```\r\n\r\nThe reason is that the inspect module fails to find the module on the following lines inside [`get_file_dirname`](https://github.com/microsoft/playwright-python/blob/master/playwright/path_utils.py#L19-L24)\r\n\r\n```python\r\nframe = inspect.stack()[1]\r\nmodule = inspect.getmodule(frame[0])\r\n```\r\n\r\n# Context information\r\n\r\n* version of python: 3.7.9\r\n* version of pyinstaller: 4.1\r\n* version of playwright-python: Version 0.162.1\r\n* platform: GNU/Linux (Ubuntu 18.04 LTS)\r\n\r\n# Reproducing the bug\r\n\r\ninstall packages\r\n\r\n    $ pip install playwright pyinstaller\r\n\r\ninstall the browsers inside playwright\r\n\r\n    $ PLAYWRIGHT_BROWSERS_PATH=0 python -m playwright install\r\n\r\ncreate `main.py`\r\n\r\n```python\r\n# main.py\r\nimport sys\r\nfrom pathlib import Path\r\nfrom playwright import sync_playwright\r\n\r\nwith sync_playwright() as p:\r\n    for browser_type in [p.chromium]:\r\n        browser = browser_type.launch(\r\n            headless=False,\r\n            executablePath=Path(sys.modules['playwright'].__file__).parent / 'driver' / '.local-browsers' / 'chromium-827102' / 'chrome-linux' / 'chrome')\r\n        page = browser.newPage()\r\n        page.goto('http://whatsmyuseragent.org/')\r\n        page.screenshot(path=f'example-{browser_type.name}.png')\r\n        browser.close()\r\n```\r\n\r\nfreeze into single binary file with pyinstaller\r\n\r\n    $ pyinstaller -F main.py --add-data /path/to/lib/python3.7/site-packages/playwright/driver:playwright/driver\r\n\r\nexecute the binary file\r\n\r\n```\r\n$ ./dist/main \r\nTraceback (most recent call last):\r\n  File \"main.py\", line 6, in <module>\r\n    with sync_playwright() as p:\r\n  File \"playwright/__init__.py\", line 34, in sync_playwright\r\n  File \"playwright/main.py\", line 81, in __init__\r\n  File \"playwright/main.py\", line 76, in run_driver\r\n  File \"asyncio/base_events.py\", line 587, in run_until_complete\r\n  File \"playwright/main.py\", line 44, in run_driver_async\r\n  File \"playwright/main.py\", line 36, in compute_driver_executable\r\n  File \"playwright/path_utils.py\", line 23, in get_file_dirname\r\nAssertionError\r\n```\r\n\r\n# Proposed solution\r\n\r\nThe problem can be fixed by changing  [`get_file_dirname`](https://github.com/microsoft/playwright-python/blob/master/playwright/path_utils.py#L19-L24) with\r\n\r\n```python\r\nimport inspect\r\nimport sys\r\nfrom pathlib import Path\r\n\r\ndef get_file_dirname() -> Path:\r\n    \"\"\"Returns the callee (`__file__`) directory name\"\"\"\r\n    module_name = inspect.currentframe().f_back.f_globals[\"__name__\"]\r\n    module = sys.modules[module_name]\r\n    assert module\r\n    return Path(module.__file__).parent.absolute()\r\n```\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\nimport asyncio\nimport os\nimport subprocess\nimport sys\nfrom pathlib import Path\nfrom typing import Any\n\nfrom greenlet import greenlet\n\nfrom playwright.async_api import Playwright as AsyncPlaywright\nfrom playwright.connection import Connection\nfrom playwright.helper import Error\nfrom playwright.object_factory import create_remote_object\nfrom playwright.path_utils import get_file_dirname\nfrom playwright.playwright import Playwright\nfrom playwright.sync_api import Playwright as SyncPlaywright\n\n\ndef compute_driver_executable() -> Path:\n    package_path = get_file_dirname()\n    platform = sys.platform\n    if platform == \"win32\":\n        return package_path / \"driver\" / \"playwright-cli.exe\"\n    return package_path / \"driver\" / \"playwright-cli\"\n\n\nclass SyncPlaywrightContextManager:\n    def __init__(self) -> None:\n        self._playwright: SyncPlaywright\n\n    def __enter__(self) -> SyncPlaywright:\n        def greenlet_main() -> None:\n            loop = None\n            own_loop = None\n            try:\n                loop = asyncio.get_running_loop()\n            except RuntimeError:\n                loop = asyncio.new_event_loop()\n                own_loop = loop\n\n            if loop.is_running():\n                raise Error(\"Can only run one Playwright at a time.\")\n\n            loop.run_until_complete(self._connection.run_as_sync())\n\n            if own_loop:\n                loop.run_until_complete(loop.shutdown_asyncgens())\n                loop.close()\n\n        dispatcher_fiber = greenlet(greenlet_main)\n        self._connection = Connection(\n            dispatcher_fiber, create_remote_object, compute_driver_executable()\n        )\n\n        g_self = greenlet.getcurrent()\n\n        def callback_wrapper(playwright_impl: Playwright) -> None:\n            self._playwright = SyncPlaywright(playwright_impl)\n            g_self.switch()\n\n        self._connection.call_on_object_with_known_name(\"Playwright\", callback_wrapper)\n\n        dispatcher_fiber.switch()\n        playwright = self._playwright\n        playwright.stop = self.__exit__  # type: ignore\n        return playwright\n\n    def start(self) -> SyncPlaywright:\n        return self.__enter__()\n\n    def __exit__(self, *args: Any) -> None:\n        self._connection.stop_sync()\n\n\nclass AsyncPlaywrightContextManager:\n    def __init__(self) -> None:\n        self._connection: Connection\n\n    async def __aenter__(self) -> AsyncPlaywright:\n        self._connection = Connection(\n            None, create_remote_object, compute_driver_executable()\n        )\n        loop = asyncio.get_running_loop()\n        self._connection._loop = loop\n        loop.create_task(self._connection.run())\n        playwright = AsyncPlaywright(\n            await self._connection.wait_for_object_with_known_name(\"Playwright\")\n        )\n        playwright.stop = self.__aexit__  # type: ignore\n        return playwright\n\n    async def start(self) -> AsyncPlaywright:\n        return await self.__aenter__()\n\n    async def __aexit__(self, *args: Any) -> None:\n        self._connection.stop_async()\n\n\nif sys.version_info.major == 3 and sys.version_info.minor == 7:\n    if sys.platform == \"win32\":\n        # Use ProactorEventLoop in 3.7, which is default in 3.8\n        asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())\n    else:\n        # Prevent Python 3.7 from throwing on Linux:\n        # RuntimeError: Cannot add child handler, the child watcher does not have a loop attached\n        asyncio.get_event_loop()\n        asyncio.get_child_watcher()\n\n\ndef main() -> None:\n    driver_executable = compute_driver_executable()\n    my_env = os.environ.copy()\n    my_env[\"PW_CLI_TARGET_LANG\"] = \"python\"\n    subprocess.run([str(driver_executable), *sys.argv[1:]], env=my_env)\n", "path": "playwright/main.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\nimport asyncio\nimport inspect\nimport os\nimport subprocess\nimport sys\nfrom pathlib import Path\nfrom typing import Any\n\nfrom greenlet import greenlet\n\nimport playwright\nfrom playwright.async_api import Playwright as AsyncPlaywright\nfrom playwright.connection import Connection\nfrom playwright.helper import Error\nfrom playwright.object_factory import create_remote_object\nfrom playwright.playwright import Playwright\nfrom playwright.sync_api import Playwright as SyncPlaywright\nfrom playwright.sync_base import dispatcher_fiber, set_dispatcher_fiber\n\n\ndef compute_driver_executable() -> Path:\n    package_path = Path(inspect.getfile(playwright)).parent\n    platform = sys.platform\n    if platform == \"win32\":\n        return package_path / \"driver\" / \"playwright-cli.exe\"\n    return package_path / \"driver\" / \"playwright-cli\"\n\n\nasync def run_driver_async() -> Connection:\n    driver_executable = compute_driver_executable()\n\n    proc = await asyncio.create_subprocess_exec(\n        str(driver_executable),\n        \"run-driver\",\n        stdin=asyncio.subprocess.PIPE,\n        stdout=asyncio.subprocess.PIPE,\n        stderr=sys.stderr,\n        limit=32768,\n    )\n    assert proc.stdout\n    assert proc.stdin\n    connection = Connection(\n        proc.stdout, proc.stdin, create_remote_object, asyncio.get_event_loop()\n    )\n    return connection\n\n\ndef run_driver() -> Connection:\n    loop = asyncio.get_event_loop()\n    if loop.is_running():\n        raise Error(\"Can only run one Playwright at a time.\")\n    return loop.run_until_complete(run_driver_async())\n\n\nclass SyncPlaywrightContextManager:\n    def __init__(self) -> None:\n        self._connection = run_driver()\n        self._playwright: SyncPlaywright\n\n    def __enter__(self) -> SyncPlaywright:\n        g_self = greenlet.getcurrent()\n\n        def callback_wrapper(playwright_impl: Playwright) -> None:\n            self._playwright = SyncPlaywright(playwright_impl)\n            g_self.switch()\n\n        self._connection.call_on_object_with_known_name(\"Playwright\", callback_wrapper)\n        set_dispatcher_fiber(greenlet(lambda: self._connection.run_sync()))\n        dispatcher_fiber().switch()\n        playwright = self._playwright\n        playwright.stop = self.__exit__  # type: ignore\n        return playwright\n\n    def start(self) -> SyncPlaywright:\n        return self.__enter__()\n\n    def __exit__(self, *args: Any) -> None:\n        self._connection.stop_sync()\n\n\nclass AsyncPlaywrightContextManager:\n    def __init__(self) -> None:\n        self._connection: Connection\n\n    async def __aenter__(self) -> AsyncPlaywright:\n        self._connection = await run_driver_async()\n        self._connection.run_async()\n        playwright = AsyncPlaywright(\n            await self._connection.wait_for_object_with_known_name(\"Playwright\")\n        )\n        playwright.stop = self.__aexit__  # type: ignore\n        return playwright\n\n    async def start(self) -> AsyncPlaywright:\n        return await self.__aenter__()\n\n    async def __aexit__(self, *args: Any) -> None:\n        self._connection.stop_async()\n\n\nif sys.platform == \"win32\":\n    # Use ProactorEventLoop in 3.7, which is default in 3.8\n    loop = asyncio.ProactorEventLoop()\n    asyncio.set_event_loop(loop)\n\n\ndef main() -> None:\n    driver_executable = compute_driver_executable()\n    my_env = os.environ.copy()\n    my_env[\"PW_CLI_TARGET_LANG\"] = \"python\"\n    subprocess.run([str(driver_executable), *sys.argv[1:]], env=my_env)\n", "path": "playwright/main.py"}]}