case studies

Case Study: Pip Ships 18 Vendored Libraries With Their Licences, Except One NOTICE

pip, the tool that installs Python packages, can’t count on any other package being installed first. So it vendors what it needs: copies of 18 releases from PyPI, kept in src/pip/_vendor and listed in its vendor.txt. pip itself is MIT. Eight of the libraries it carries are MIT too and four are Apache-2.0. The rest are one each under BSD-3-Clause, BSD-2-Clause, ISC, MPL-2.0 and PSF-2.0, plus packaging, which offers a choice of Apache-2.0 or BSD-2-Clause.

We compared pip 26.2.2’s vendored folder with those 18 releases, downloaded from PyPI and checked against the SHA-256 sums PyPI publishes for them. Only the vendored folder was scanned, since the question here is whether the libraries pip ships carry their licences. The reports are in the Remixware repository, and every number below comes from them.

The 18 libraries in pip 26.2.2’s vendored folder: 17 credited by the licence files pip keeps next to them, and requests, whose NOTICE text is missing.

207 of 226 Copies Attributed

Remixware found 226 copies of the 18 releases in pip’s vendored folder, and 207 of them are attributed. pip keeps each library’s licence file in the library’s folder, such as _vendor/rich/LICENSE or _vendor/urllib3/LICENSE.txt, and Remixware 0.2.1 counts that as credit:

ATTRIBUTED           src/pip/_vendor/rich/console.py:1-2680
                     rich 14.2.0, rich/console.py:1-2680 (MIT), copied as is, 99% match
                     Credited in src/pip/_vendor/rich/LICENSE, kept with the copy. Keep its
                     copyright line and the MIT licence text with your copy, for example in a
                     third-party notices file.

certifi’s two copies come out as review, the status for MPL-2.0 code in a project under another licence. MPL-2.0 applies file by file: the copied files stay under MPL-2.0, and whoever gets them from you must be able to get their source, changes included. pip keeps certifi’s files in a folder of their own with certifi’s licence next to them, and pip’s source is public.

requests: The Licence Is There, the NOTICE Isn’t

The other 17 copies are requests, and Remixware reports them as attribution-missing:

ATTRIBUTION MISSING  src/pip/_vendor/requests/adapters.py:34-748
                     requests 2.34.2, adapters.py:34-748 (Apache-2.0), copied as is, 98% match
                     Keep its copyright line, the Apache-2.0 licence text and any NOTICE text the
                     project ships, and mark files you changed. Its licence text is kept with the
                     copy, in src/pip/_vendor/requests/LICENSE, but its NOTICE text isn't.

requests is under Apache-2.0, and its release ships a NOTICE file with two lines, “Requests” and “Copyright 2019 Kenneth Reitz”. Apache-2.0 asks, in section 4(d), that a changed version you pass on, as pip’s copy is, carries the attribution notices in the work’s NOTICE file. pip keeps requests’ licence, and the copyright lines inside requests’ own files, but the NOTICE text isn’t anywhere in pip. In the requests wheel, the licence and the NOTICE both sit in its .dist-info folder. pip’s vendoring setup drops .dist-info folders, and the licence file still reaches _vendor/requests while the NOTICE doesn’t. A copy of that two-line file in _vendor/requests would settle it.

What pip Changed in Remixware

Besides licence files kept with the code, running Remixware on pip turned up four more things to fix, and 0.2.1 has them all. packaging’s LICENSE is a short file that sends the reader to LICENSE.APACHE or LICENSE.BSD, and Remixware took it for a licence it didn’t recognise. pip’s tests hold wheel files with names that start like a licence file, such as license.dist-0.1-py2.py3-none-any.whl, and those were read as licence texts. A source release built with setuptools, as 7 of the 18 are, keeps its metadata in an .egg-info folder next to the package, and the package lost the release’s licence text and copyright lines in the index. And resolvelib gives its licence in words, “ISC License”, which Remixware now reads as ISC.

The reference lists everything Remixware counts as credit.