Upgrade to Python v3.11.2. Upgrade to Python v3.11.2
* https://docs.python.org/3/whatsnew/changelog.html#python-3-11-2-final
* https://docs.python.org/3/whatsnew/3.11.html

% `shasum -a 256 downloads/Python-3.11.2.tgz > cpython/checksums`

<!-- Thank you for contributing to Pyodide! All improvements are welcome,
     so don't be afraid to make a PR. -->

### Description

<!-- Please explain what your PR is about:
     - the reasoning for the change
     - some details of updated code
     - any noteworthy choices to be aware of
	Please refer to any related issues by #<issue_id> -->

### Checklists

<!-- Note:
     If you think some of these steps are not necessary for your PR,
     remove those checkboxes, or mark them as checked. If you keep unchecked checkboxes,
     we will assume that your PR is not ready to be merged  -->

- [ ] Add a [CHANGELOG](https://github.com/pyodide/pyodide/blob/main/docs/project/changelog.md) entry
- [ ] Add / update tests
- [ ] Add new / update outdated documentation

(interrupting_execution)=

# Interrupting execution

The native Python interrupt system is based on preemptive multitasking but Web
Assembly has no support for preemptive multitasking. Because of this,
interrupting execution in Pyodide must be achieved via a different mechanism
which takes some effort to set up.

## Setting up interrupts

In order to use interrupts you must be using Pyodide in a webworker.
You also will need to use a {js:class}`SharedArrayBuffer`, which means that your
server
must set appropriate security headers. See [the MDN
docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements)
for more information.

To use the interrupt system, you should create a {js:class}`SharedArrayBuffer`
on either the main thread or the worker thread and share it with the other
thread. You should use {js:func}`pyodide.setInterruptBuffer` to set the
interrupt buffer on the Pyodide thread. When you want to indicate an interrupt,
write a `2` into the interrupt buffer. When the interrupt signal is processed,
Pyodide will set the value of the interrupt buffer back to `0`.

By default, when the interrupt fires, a {py:exc}`KeyboardInterrupt` is raised.
Using the {py:mod}`signal` module, it is possible to register a custom Python
function to handle {py:data}`~signal.SIGINT`. If you register a custom handler
function it will be called instead.

Here is a very basic example. Main thread code:

```js
let pyodideWorker = new Worker("pyodideWorker.js");
let interruptBuffer = new Uint8Array(new SharedArrayBuffer(1));
pyodideWorker.postMessage({ cmd: "setInterruptBuffer", interruptBuffer });
function interruptExecution() {
  // 2 stands for SIGINT.
  interruptBuffer[0] = 2;
}
// imagine that interruptButton is a button we want to trigger an interrupt.
interruptButton.addEventListener("click", interruptExecution);
async function runCode(code) {
  // Clear interruptBuffer in case it was accidentally left set after previous code completed.
  interruptBuffer[0] = 0;
  pyodideWorker.postMessage({ cmd: "runCode", code });
}
```

Worker code:

```js
self.addEventListener("message", (msg) => {
  if (msg.data.cmd === "setInterruptBuffer") {
    pyodide.setInterruptBuffer(msg.data.interruptBuffer);
    return;
  }
  if (msg.data.cmd === "runCode") {
    pyodide.runPython(msg.data.code);
    return;
  }
});
```

## Allowing JavaScript code to be interrupted

The interrupt system above allows interruption of Python code and also of C code
that allows itself to be interrupted by periodically calling
{c:func}`PyErr_CheckSignals`. There is also a function
{js:func}`pyodide.checkInterrupt` that allows JavaScript functions called from
Python to check for an interrupt. As a simple example, we can implement an
interruptible sleep function using {js:func}`Atomics.wait`:

```js
let blockingSleepBuffer = new Int32Array(new SharedArrayBuffer(4));
function blockingSleep(t) {
  for (let i = 0; i < t * 20; i++) {
    // This Atomics.wait call blocks the thread until the buffer changes or a 50ms timeout elapses.
    // Since we won't change the value in the buffer, this blocks for 50ms.
    Atomics.wait(blockingSleepBuffer, 0, 0, 50);
    // Periodically check for an interrupt to allow a KeyboardInterrupt.
    pyodide.checkInterrupt();
  }
}
```

(interrupting_execution)=

# Interrupting execution

The native Python interrupt system is based on preemptive multitasking but Web
Assembly has no support for preemptive multitasking. Because of this,
interrupting execution in Pyodide must be achieved via a different mechanism
which takes some effort to set up.

## Setting up interrupts

In order to use interrupts you must be using Pyodide in a webworker.
You also will need to use a {js:class}`SharedArrayBuffer`, which means that your
server
must set appropriate security headers. See [the MDN
docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements)
for more information.

To use the interrupt system, you should create a {js:class}`SharedArrayBuffer`
on either the main thread or the worker thread and share it with the other
thread. You should use {js:func}`pyodide.setInterruptBuffer` to set the
interrupt buffer on the Pyodide thread. When you want to indicate an interrupt,
write a `2` into the interrupt buffer. When the interrupt signal is processed,
Pyodide will set the value of the interrupt buffer back to `0`.

By default, when the interrupt fires, a {py:exc}`KeyboardInterrupt` is raised.
Using the {py:mod}`signal` module, it is possible to register a custom Python
function to handle {py:data}`~signal.SIGINT`. If you register a custom handler
function it will be called instead.

Here is a very basic example. Main thread code:

```js
let pyodideWorker = new Worker("pyodideWorker.js");
let interruptBuffer = new Uint8Array(new SharedArrayBuffer(1));
pyodideWorker.postMessage({ cmd: "setInterruptBuffer", interruptBuffer });
function interruptExecution() {
  // 2 stands for SIGINT.
  interruptBuffer[0] = 2;
}
// imagine that interruptButton is a button we want to trigger an interrupt.
interruptButton.addEventListener("click", interruptExecution);
async function runCode(code) {
  // Clear interruptBuffer in case it was accidentally left set after previous code completed.
  interruptBuffer[0] = 0;
  pyodideWorker.postMessage({ cmd: "runCode", code });
}
```

Worker code:

```js
self.addEventListener("message", (msg) => {
  if (msg.data.cmd === "setInterruptBuffer") {
    pyodide.setInterruptBuffer(msg.data.interruptBuffer);
    return;
  }
  if (msg.data.cmd === "runCode") {
    pyodide.runPython(msg.data.code);
    return;
  }
});
```

## Allowing JavaScript code to be interrupted

The interrupt system above allows interruption of Python code and also of C code
that allows itself to be interrupted by periodically calling
{c:func}`PyErr_CheckSignals`. There is also a function
{js:func}`pyodide.checkInterrupt` that allows JavaScript functions called from
Python to check for an interrupt. As a simple example, we can implement an
interruptible sleep function using {js:func}`Atomics.wait`:

```js
let blockingSleepBuffer = new Int32Array(new SharedArrayBuffer(4));
function blockingSleep(t) {
  for (let i = 0; i < t * 20; i++) {
    // This Atomics.wait call blocks the thread until the buffer changes or a 50ms timeout elapses.
    // Since we won't change the value in the buffer, this blocks for 50ms.
    Atomics.wait(blockingSleepBuffer, 0, 0, 50);
    // Periodically check for an interrupt to allow a KeyboardInterrupt.
    pyodide.checkInterrupt();
  }
}
```
