Lighthouse

Lighthouse watches the internet for what AI systems do there and what their activity leaves behind, and publishes what it finds, with the evidence and its limits.

Studies LH012

After a new release of one of the most downloaded Python libraries, what keeps older versions downloaded, and which explanations can the public record rule out: other libraries' version bounds, Pythons the new release no longer supports, or environments rebuilt from frozen lists?

The answer so far. Pythons the newer releases no longer support are ruled out as the main reason for older downloads as a rule: for 32 of the 37 projects (86.5 per cent, project-resampled 95 per cent interval 75.7 to 97.3), less than half of the downloads on versions older than the release of a month before came from a Python that every newer release excludes, even counting downloads with no Python reported as excluded (derived measurement, on the Python the installer reports). For three projects such downloads are most of the older downloads, the brief's class "accounts for most": boto3 (76.3 to 77.0 per cent), aiobotocore (63.0 to 63.5) and numpy (62.5 to 66.7); the question stays open for pandas and urllib3. That class counts fetches that could not have been of R or later; it does not say why they were of the versions they were. For boto3 and aiobotocore few were at the highest version their Python admits, where a fresh install lands (6.7 and 0.6 per cent; numpy 56.7). Read after version 0.2 was released (post hoc, below), their count-by-version profiles are flat for long runs of versions below each Python's edge (for boto3 on Python 3.9, about a hundred at one level and several hundred at the next), the shape an installer's resolution walk leaves when it fetches each version it tries and rejects; on that reading most of those downloads were versions inspected and discarded, not installed (interpretation, untested). Identified bounds, the requirements that the 500 most downloaded projects declare, are in the brief's class "accounts for most" for four tightly coupled projects: pydantic-core (held by pydantic's exact pin), fsspec (by s3fs), and botocore and s3transfer (by boto3). B is an estimate under the co-fetch assumption, that each fetch of a held dependent version brings one fetch of the project, and the log does not observe that, since it counts each project's fetches separately; so the class says what identified bounds could account for, not what they did. The log's own ratios strain the assumption for botocore and s3transfer, boto3 being fetched 2.94 and 3.88 times as often as they are (7.51 times botocore on Python 3.9), and are most consistent with it for pydantic-core, whose dependent is fetched about as often (1.05 times) and whose older fetches sit largely at the one version pydantic's newest releases pin. Only for pydantic-core do the dependent's current versions carry a large part of the hold (53.2 per cent); for fsspec, botocore and s3transfer the hold comes from s3fs's and boto3's older versions, which moves the question to why those are fetched. On the same assumption, identified bounds are ruled out as the main reason for seven projects; they are undetermined for 26, mostly because requirements the log cannot resolve (extras, platform markers, versions not read) leave the upper estimate near one. Environments rebuilt from frozen lists cannot be counted in the log, as the brief said in advance; 18 of the 37 projects show their trace (most older downloads off every version a fresh install on the identified constraints would land on, and more often flagged CI than new downloads). So for most projects the public record rules out the Python explanation, cannot rule identified bounds in or out, and leaves what remains unmeasured, consistent with frozen lists but not shown to be them.

Study, version 0.4, 29 September 2026 studies/LH012/LH012.md

From studies/LH012/ in the repository, last changed 9 November 2026.