Python 3.13.7 fixes a TLS socket deadlock
Python 3.13.7 is an expedited release for a regression in concurrent SSL socket operations. A blocked receive in one thread could prevent a second thread from sending on the same connection.
A connection can stop making progress when a blocked receive prevents the send that the peer needs before it can respond. The network may be healthy, and the TLS handshake may already have succeeded. Python 3.13.7 repairs a regression that made this kind of stall possible when separate threads used one SSL socket.
The August 14 release announcement describes an expedited maintenance release for a significant issue introduced in 3.13.6. Its purpose is more specific than the event record's generic description of an interpreter and standard-library update. The 3.13.7 changelog says a blocked ssl.SSLSocket.recv() in one thread could deadlock when another thread subsequently called another method, such as send(), on that object.
The reproducer needs simultaneous directions
The original issue, reported on August 9, includes a minimal TLS server and client. Its author compared working behavior on 3.13.5 with failure on 3.13.6. A background thread reads from the client's connection, while the main thread sends a request through it.
The background receive is the important condition. Removing that thread makes the failure disappear in the report. The server otherwise waits for a request that the client is attempting to send. Testing only a send followed by a receive would miss the concurrent sequence.
The reporter explains the architecture behind that arrangement. A background reader supplies bytes to a protocol parser whose state machine is separate from network I/O. That is a plausible use of a shared connection, with one direction waiting while another direction begins work.
I value Python's ability to give libraries familiar interfaces over complex implementations. An SSL socket retains the shape of a socket interface, but this regression shows how much application behavior depends on the synchronization beneath it. A maintenance change can break progress without changing a method signature.
Serialization can affect liveness
The linked repair is titled to distinguish locking the SSL context from locking the SSL socket. Together with the changelog, that identifies the relevant synchronization boundary. Protecting shared state is necessary, but holding exclusion across an operation that waits on external progress can prevent another operation from supplying that progress.
The failure condition is more precise than saying that TLS reads block. A blocking receive is expected when no application data is available. The defect is the interaction between that waiting receive and a second operation on the same object in another thread.
This distinction changes how a stalled application is interpreted. A waiting reader alone does not prove a runtime defect. A regression that appears only when the reader and sender overlap points toward a coordination problem. The version comparison in the report makes that observation concrete.
The release note does not establish that every multithreaded network operation is affected. It names SSL socket methods sharing one object after a blocking receive begins. Applications with different connection ownership or I/O arrangements may not exercise the same sequence.
TLS adds another state machine
The versioned SSL documentation explains why TLS behavior cannot be inferred solely from underlying socket readiness. An operation attempting to read application data may first need a network write. A write may similarly require a read.
In nonblocking mode, SSLWantReadError and SSLWantWriteError communicate those requirements. A socket reported readable by the operating system may contain only part of a TLS frame. Conversely, the SSL layer may already have decrypted data available when the operating system has no new readiness event to report.
Those details are separate from the blocking-thread regression, but they explain why a transparent-looking wrapper has additional coordination requirements. The library manages a protocol state machine as well as a network descriptor. Correct progress depends on respecting both.
The same documentation provides SSLObject for frameworks that separate TLS processing from network I/O through memory BIOs. That design lets a framework drive encrypted input and output explicitly. It is an alternative interface for a different integration requirement, not a change required to use the 3.13.7 repair.
What the expedited release changes
The release also includes fixes that would otherwise have waited. The changelog corrects large resource-limit values returned through resource.getrlimit() and accepted by setrlimit(). It also makes the multiprocessing resource tracker's send operation safe against re-entry. These remain maintenance repairs alongside the SSL regression.
A separate fix concerns a crash in the experimental free-threaded build when disabling tracing or profiling across all threads. That entry has a different execution context from the SSL socket failure. Conflating them would suggest that the network regression requires a free-threaded interpreter, which the report does not say.
My main interest in a release like this is preserving the behavior that libraries already depend on. The ecosystem is a principal reason I choose Python. Here the compatibility requirement includes a waiting receive coexisting with another operation on the same encrypted connection, and 3.13.7 supplies the specific repair for the regression introduced in 3.13.6.