pyodide / pyodide/pyodide

Interrupting execution: doesn't work in `requests` or `time.sleep()`

Open
#6,082 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Python
Stars
14.8k
Forks
1k
Avg merge
20h 29m
Merged PRs (30d)
19

Description

## 🐛 Bug

https://pyodide.org/en/stable/usage/keyboard-interrupts.html describes a way to interrupt Pyodide code running in a web worker. This works for CPU / calculation loops, but appears broken in at least two "wait for event" cases:
- `time.sleep()`
- `requests.()`

### To Reproduce

The setup requires Pyodide running in a web worker + JS `SharedArrayBuffer` enabled by setting security headers for both the host page and the web worker script as mentioned in https://pyodide.org/en/stable/usage/keyboard-interrupts.html + https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements + `pyodide.setInterruptBuffer()`.

Then the code to run is simply
```
import time
time.sleep(600)
```
or
```
import requests
res = requests.get('http://some.backend/that/would/sleep/for/a/while/before/sending/response')
```

run via `pyodide.runPythonAsync()`. Sending an interrupt signal while it's in `time.sleep()` or `requests.get()` doesn't interrupt anything. When the blocking call exits, a message like
```
Exception ignored in: ._remove at 0xce6da8>
Traceback (most recent call last):
File "/lib/python313.zip/_weakrefset.py", line 39, in _remove
KeyboardInterrupt:
```
is sent to `stderr`, but otherwise the code continues to run.

### Expected behavior

- Ideally the signal should just interrupt the call (the aforementioned doc has a section of how to implement interruptable `sleep()`, is it a TODO for the future?)
- If the call is non-interruptable, I'd at least expect the signal to take effect after the call exits (as right now nothing stops at all, just that cryptic exception pops up)

### Environment

- Pyodide Version: 0.29.2
- Browser version: Chromium 143.0.7499.192
- Any other relevant information: a setup with a web worker + `SharedArrayBuffer` + `pyodide.setInterruptBuffer()`; the code is run via `pyodide.runPythonAsync()` (`fetch`-based `requests` implementation is being used under the hood)

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.