Python 2.7.15 prevents blocked filesystem calls from stopping every thread
Python 2.7.15 releases the interpreter lock around more file operations. Its maintenance fixes also address garbage collection during concurrent subprocess creation and compiler assumptions about memory alignment.
A blocked file operation can stop work that has no interest in that file when the interpreter retains its global lock during the underlying system call. Python 2.7.15 corrects such a case for file construction and reads. The release notes identify an inaccessible NFS server as the situation in which all threads could hang.
The May 1 release page describes 2.7.15 as a bugfix release. Its included candidate changelog explains bpo-32186, which releases the global interpreter lock while checking a file descriptor during construction of io.FileIO() and the built-in file() object. It also releases the lock while obtaining the file size in several reading methods.
I often choose Python because a library already handles the difficult part of a problem. That dependence extends into apparently ordinary operations such as opening and reading files. A maintenance correction at this level can determine whether unrelated application work continues while a remote filesystem is unavailable.
File metadata can involve waiting
The changelog names io.FileIO.readall(), io.FileIO.read() and file.read() as affected methods. The point is not simply whether the application explicitly requests a large read. Obtaining information needed to carry out that read can itself wait on a filesystem. The fix moves the interpreter-lock boundary around the descriptor and size checks described in the notes.
That distinction explains the NFS example. A call concerning a file can require interaction with a remote server, even when its purpose sounds like a local bookkeeping operation. Retaining an interpreter-wide lock during the wait makes the consequence wider than one file or one worker. Releasing it permits other Python threads to proceed while the system call remains blocked.
The correction does not promise that the filesystem call will finish or that the affected worker can recover immediately. Those are different questions. It removes the unnecessary coupling between that worker's wait and the ability of other threads to run. An application can still need its own policy for handling an unavailable filesystem.
This is also why describing the patch as a general speed improvement would miss the issue. The reported problem concerns progress under a failure condition. A program whose files respond promptly may never reveal the difference. The relevant behaviour appears when an external dependency stops responding and a lock retained by one operation affects everyone else.
Subprocess startup has shared state too
The same changelog describes bpo-27448, a race involving gc.disable() in the subprocess module. Multiple threads spawning subprocesses could leave garbage collection disabled. The patch works around that race, and the release notes explicitly recommend the subprocess32 package for Python 2.7 users on reliability grounds.
The defect concerns state shared across the interpreter. A thread launching a child process performs preparation that can affect other threads even after its immediate launch operation finishes. If garbage collection remains disabled, the effect outlives the call that caused it. The changelog does not say that every subprocess invocation suffers this problem; concurrency among launches is the condition it identifies.
Together, the file and subprocess fixes illustrate separate consequences of shared runtime state. In the file case, one operation retains a lock while waiting. In the subprocess case, interleaved operations leave a process-wide setting in the wrong state. Both are below the level of an application's ordinary call signatures, so unchanged application source can receive a meaningful correctness improvement.
My judgement is that these details deserve more attention than the size of the version increment suggests. Neither repair requires new syntax. Both concern whether a program retains the operating assumptions under which its existing threads were written.
Native build assumptions affect a mature branch
The final release changelog records a change to PyGC_Head. It prevents compilers from assuming that the structure is always aligned to 16 bytes on x86, addressing crashes with more aggressive GCC 8 optimizations.
This correction matters to people building the interpreter because compiler assumptions participate in runtime behaviour. A structure definition that produces working code under one optimization strategy can expose a mistaken assumption under another. Maintaining the language branch therefore includes adapting its native implementation to the tools used to compile it.
The release also changes official macOS packaging. The release page says all python.org macOS installers now include their own OpenSSL copy. An additional installer for macOS 10.9 and later includes Tcl/Tk 8.6. These are properties of the published installer variants, so they should not be generalized to every independently built Python installation.
Those distribution changes reinforce the distinction between the interpreter source and a delivered runtime. The same language version can arrive with different platform dependencies depending on its distributor. For 2.7.15, the source corrections establish specific improvements to thread progress and native compilation, while the installer announcement identifies the libraries supplied in the official macOS packages.