Are all descriptions of the "caveats", listed near the end of _thread module's docs, up to date?

The fact that the statement is in the _thread documentation means that it only occurs when the main thread starts any threads. This is how I understand it:

  • If the main thread exits while other threads it spawned are still running, it doesn’t perform its usual cleanup tasks. This includes flushing standard I/O files, which can lead to lost or incomplete output. The spawned threads are also typically terminated abruptly without executing any remaining try…finally clauses or object destructors.

Also, since _thread is a private module, I believe its documentation is intended for CPython developers rather than Python developers. These caveats do not apply to threading.

The statement as it’s written is incorrect for the current design of CPython. If the main thread exits normally – as opposed to a low-level exit or termination via C exit(), _exit() or an unhandled signal (or unhandled OS exception on Windows) – then Py_FinalizeEx() is called, which implements a clean shutdown.

The following statement is also no longer true without qualification:

  • It is not possible to interrupt the acquire() method on a lock — the KeyboardInterrupt exception will happen after the lock has been acquired.

This still applies on Windows, but for quite some time the lock implementation on POSIX that’s based on the pthread API has supported interrupting PyThread_acquire_lock_timed(), in which case it returns the value PY_LOCK_INTR. In turn, PyThread_acquire_lock_timed_with_retries() calls _PyEval_MakePendingCalls(), which calls the signal handlers if it’s the main thread. If a signal handler raised an exception (e.g. KeyboardInterrupt), then PY_LOCK_INTR is returned to the caller. The C implementation of the method _thread.lock.acquire() returns NULL for this case, so the call stack can handle the exception.

1 Like

We need tests on every platform CPython supports before we can edit or remove these statements. It is safer to assume the worst rather than hope for the best.