We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Nested attribute access in JS->Python type conversion
Currently the following code fails,
```js
>>> from js import window
>>> window.URL.createObjectURL
Error: Traceback (most recent call last):
  File "/lib/python3.7/site-packages/pyodide.py", line 45, in eval_code
    return eval(compile(expr, '<eval>', mode='eval'), ns, ns)
  File "<eval>", line 1, in <module>
AttributeError: 'JsBoundMethod' object has no attribute 'createObjectURL'
```
(while `window.URL.createObjectURL` is a valid JS object) because nested attributes (i.e. attribute of an attribute) don't seem to be supported. It would have been nice to make it work, though I have not looked at how difficult that would be.
from js import fetch treats fetch as a free function
`fetch` is a member function of `window`.
However, using `from js import fetch` doesn't realize that and leads to the error:

`TypeError: 'fetch' called on an object that does not implement interface Window.`

For Reproducing the Error:
```
%%py

from js import document, Request, fetch, URL
img_tag = document.createElement('img')
req = Request.new('https://i.ibb.co/3f4yJQS/face4.jpg')

def func(response):
    return response.blob()

def func2(blob):
    objURL = URL.createObjectURL(blob)
    img_tag.src = objURL

fetch(req).then(func).then(func2)

document.body.appendChild(img_tag)
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/pyodide-py/pyodide/_core.py`
Content:
```
1 # type: ignore
2 import platform
3 
4 if platform.system() == "Emscripten":
5     from _pyodide_core import JsProxy, JsBoundMethod, JsException
6 else:
7     # Can add shims here if we are so inclined.
8     class JsException(Exception):
9         """
10         A wrapper around a Javascript Error to allow the Error to be thrown in Python.
11         """
12 
13         # Defined in jsproxy.c
14 
15     class JsProxy:
16         """A proxy to make a Javascript object behave like a Python object"""
17 
18         # Defined in jsproxy.c
19 
20     class JsBoundMethod:
21         """A proxy to make it possible to call Javascript bound methods from Python."""
22 
23         # Defined in jsproxy.c
24 
25 
26 __all__ = [JsProxy, JsBoundMethod, JsException]
27
```
--- 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/src/pyodide-py/pyodide/_core.py b/src/pyodide-py/pyodide/_core.py
--- a/src/pyodide-py/pyodide/_core.py
+++ b/src/pyodide-py/pyodide/_core.py
@@ -2,7 +2,7 @@
 import platform
 
 if platform.system() == "Emscripten":
-    from _pyodide_core import JsProxy, JsBoundMethod, JsException
+    from _pyodide_core import JsProxy, JsMethod, JsException
 else:
     # Can add shims here if we are so inclined.
     class JsException(Exception):
@@ -17,10 +17,10 @@
 
         # Defined in jsproxy.c
 
-    class JsBoundMethod:
+    class JsMethod:
         """A proxy to make it possible to call Javascript bound methods from Python."""
 
         # Defined in jsproxy.c
 
 
-__all__ = [JsProxy, JsBoundMethod, JsException]
+__all__ = [JsProxy, JsMethod, JsException]

{"golden_diff": "diff --git a/src/pyodide-py/pyodide/_core.py b/src/pyodide-py/pyodide/_core.py\n--- a/src/pyodide-py/pyodide/_core.py\n+++ b/src/pyodide-py/pyodide/_core.py\n@@ -2,7 +2,7 @@\n import platform\n \n if platform.system() == \"Emscripten\":\n-    from _pyodide_core import JsProxy, JsBoundMethod, JsException\n+    from _pyodide_core import JsProxy, JsMethod, JsException\n else:\n     # Can add shims here if we are so inclined.\n     class JsException(Exception):\n@@ -17,10 +17,10 @@\n \n         # Defined in jsproxy.c\n \n-    class JsBoundMethod:\n+    class JsMethod:\n         \"\"\"A proxy to make it possible to call Javascript bound methods from Python.\"\"\"\n \n         # Defined in jsproxy.c\n \n \n-__all__ = [JsProxy, JsBoundMethod, JsException]\n+__all__ = [JsProxy, JsMethod, JsException]\n", "issue": "Nested attribute access in JS->Python type conversion\nCurrently the following code fails,\r\n```js\r\n>>> from js import window\r\n>>> window.URL.createObjectURL\r\nError: Traceback (most recent call last):\r\n  File \"/lib/python3.7/site-packages/pyodide.py\", line 45, in eval_code\r\n    return eval(compile(expr, '<eval>', mode='eval'), ns, ns)\r\n  File \"<eval>\", line 1, in <module>\r\nAttributeError: 'JsBoundMethod' object has no attribute 'createObjectURL'\r\n```\r\n(while `window.URL.createObjectURL` is a valid JS object) because nested attributes (i.e. attribute of an attribute) don't seem to be supported. It would have been nice to make it work, though I have not looked at how difficult that would be.\nfrom js import fetch treats fetch as a free function\n`fetch` is a member function of `window`.\r\nHowever, using `from js import fetch` doesn't realize that and leads to the error:\r\n\r\n`TypeError: 'fetch' called on an object that does not implement interface Window.`\r\n\r\nFor Reproducing the Error:\r\n```\r\n%%py\r\n\r\nfrom js import document, Request, fetch, URL\r\nimg_tag = document.createElement('img')\r\nreq = Request.new('https://i.ibb.co/3f4yJQS/face4.jpg')\r\n\r\ndef func(response):\r\n    return response.blob()\r\n\r\ndef func2(blob):\r\n    objURL = URL.createObjectURL(blob)\r\n    img_tag.src = objURL\r\n\r\nfetch(req).then(func).then(func2)\r\n\r\ndocument.body.appendChild(img_tag)\r\n```\n", "before_files": [{"content": "# type: ignore\nimport platform\n\nif platform.system() == \"Emscripten\":\n    from _pyodide_core import JsProxy, JsBoundMethod, JsException\nelse:\n    # Can add shims here if we are so inclined.\n    class JsException(Exception):\n        \"\"\"\n        A wrapper around a Javascript Error to allow the Error to be thrown in Python.\n        \"\"\"\n\n        # Defined in jsproxy.c\n\n    class JsProxy:\n        \"\"\"A proxy to make a Javascript object behave like a Python object\"\"\"\n\n        # Defined in jsproxy.c\n\n    class JsBoundMethod:\n        \"\"\"A proxy to make it possible to call Javascript bound methods from Python.\"\"\"\n\n        # Defined in jsproxy.c\n\n\n__all__ = [JsProxy, JsBoundMethod, JsException]\n", "path": "src/pyodide-py/pyodide/_core.py"}], "after_files": [{"content": "# type: ignore\nimport platform\n\nif platform.system() == \"Emscripten\":\n    from _pyodide_core import JsProxy, JsMethod, JsException\nelse:\n    # Can add shims here if we are so inclined.\n    class JsException(Exception):\n        \"\"\"\n        A wrapper around a Javascript Error to allow the Error to be thrown in Python.\n        \"\"\"\n\n        # Defined in jsproxy.c\n\n    class JsProxy:\n        \"\"\"A proxy to make a Javascript object behave like a Python object\"\"\"\n\n        # Defined in jsproxy.c\n\n    class JsMethod:\n        \"\"\"A proxy to make it possible to call Javascript bound methods from Python.\"\"\"\n\n        # Defined in jsproxy.c\n\n\n__all__ = [JsProxy, JsMethod, JsException]\n", "path": "src/pyodide-py/pyodide/_core.py"}]}