1+ from asyncio import CancelledError
12from pathlib import Path
23from urllib .parse import urlparse
34
78
89try :
910 import pyodide_js
10- from js import Object
11+ from js import AbortController , Object
1112 from pyodide_js import loadedPackages , loadPackage
1213 from pyodide_js ._api import ( # type: ignore[import]
1314 loadBinaryFile ,
2122 raise
2223 # Otherwise, this is pytest test collection so let it go.
2324
25+ if IN_BROWSER :
26+
27+ async def _pyfetch (urls : str , ** kwargs ):
28+ if "signal" in kwargs :
29+ return await pyfetch (urls , ** kwargs )
30+
31+ controler = AbortController .new ()
32+ kwargs ["signal" ] = controler .signal
33+
34+ async def fetch_with_abort ():
35+ try :
36+ return await pyfetch (urls , ** kwargs )
37+ except CancelledError :
38+ controler .abort ()
39+ raise
40+
41+ return await fetch_with_abort ()
42+
43+ else :
44+ _pyfetch = pyfetch
45+
2446
2547async def fetch_bytes (url : str , kwargs : dict [str , str ]) -> bytes :
2648 parsed_url = urlparse (url )
@@ -29,13 +51,13 @@ async def fetch_bytes(url: str, kwargs: dict[str, str]) -> bytes:
2951 if parsed_url .scheme == "file" :
3052 return (await loadBinaryFile (parsed_url .path )).to_bytes ()
3153
32- return await (await pyfetch (url , ** kwargs )).bytes ()
54+ return await (await _pyfetch (url , ** kwargs )).bytes ()
3355
3456
3557async def fetch_string_and_headers (
3658 url : str , kwargs : dict [str , str ]
3759) -> tuple [str , dict [str , str ]]:
38- response = await pyfetch (url , ** kwargs )
60+ response = await _pyfetch (url , ** kwargs )
3961
4062 content = await response .string ()
4163 # TODO: replace with response.headers when pyodide>= 0.24 is released
0 commit comments