mirror of
https://github.com/pypa/pip
synced 2023-12-13 21:30:23 +01:00
Lint src/pip/_vendor/README.rst
This commit is contained in:
parent
17608c43d1
commit
da9c7c7f69
0
news/348f5c72-1c55-4c74-9d23-295563e7a7e7.trivial
Normal file
0
news/348f5c72-1c55-4c74-9d23-295563e7a7e7.trivial
Normal file
|
@ -4,26 +4,19 @@ Vendoring Policy
|
|||
|
||||
* Vendored libraries **MUST** not be modified except as required to
|
||||
successfully vendor them.
|
||||
|
||||
* Vendored libraries **MUST** be released copies of libraries available on
|
||||
PyPI.
|
||||
|
||||
* Vendored libraries **MUST** be available under a license that allows
|
||||
them to be integrated into ``pip``, which is released under the MIT license.
|
||||
|
||||
* Vendored libraries **MUST** be accompanied with LICENSE files.
|
||||
|
||||
* The versions of libraries vendored in pip **MUST** be reflected in
|
||||
``pip/_vendor/vendor.txt``.
|
||||
|
||||
* Vendored libraries **MUST** function without any build steps such as ``2to3`` or
|
||||
compilation of C code, practically this limits to single source 2.x/3.x and
|
||||
* Vendored libraries **MUST** function without any build steps such as ``2to3``
|
||||
or compilation of C code, practically this limits to single source 2.x/3.x and
|
||||
pure Python.
|
||||
|
||||
* Any modifications made to libraries **MUST** be noted in
|
||||
``pip/_vendor/README.rst`` and their corresponding patches **MUST** be
|
||||
included ``tools/automation/vendoring/patches``.
|
||||
|
||||
* Vendored libraries should have corresponding ``vendored()`` entries in
|
||||
``pip/_vendor/__init__.py``.
|
||||
|
||||
|
@ -41,41 +34,46 @@ higher quality and more battle tested code, centralization of bug fixes
|
|||
However, there are several issues with having dependencies in the traditional
|
||||
way (via ``install_requires``) for pip. These issues are:
|
||||
|
||||
* **Fragility.** When pip depends on another library to function then if for
|
||||
whatever reason that library either isn't installed or an incompatible
|
||||
version is installed then pip ceases to function. This is of course true for
|
||||
all Python applications, however for every application *except* for pip the
|
||||
way you fix it is by re-running pip. Obviously, when pip can't run, you can't
|
||||
use pip to fix pip, so you're left having to manually resolve dependencies and
|
||||
installing them by hand.
|
||||
**Fragility**
|
||||
When pip depends on another library to function then if for whatever reason
|
||||
that library either isn't installed or an incompatible version is installed
|
||||
then pip ceases to function. This is of course true for all Python
|
||||
applications, however for every application *except* for pip the way you fix
|
||||
it is by re-running pip. Obviously, when pip can't run, you can't use pip to
|
||||
fix pip, so you're left having to manually resolve dependencies and
|
||||
installing them by hand.
|
||||
|
||||
* **Making other libraries uninstallable.** One of pip's current dependencies is
|
||||
the ``requests`` library, for which pip requires a fairly recent version to run.
|
||||
If pip depended on ``requests`` in the traditional manner, then we'd either
|
||||
have to maintain compatibility with every ``requests`` version that has ever
|
||||
existed (and ever will), OR allow pip to render certain versions of ``requests``
|
||||
uninstallable. (The second issue, although technically true for any Python
|
||||
application, is magnified by pip's ubiquity; pip is installed by default in
|
||||
Python, in ``pyvenv``, and in ``virtualenv``.)
|
||||
**Making other libraries uninstallable**
|
||||
One of pip's current dependencies is the ``requests`` library, for which pip
|
||||
requires a fairly recent version to run. If pip depended on ``requests`` in
|
||||
the traditional manner, then we'd either have to maintain compatibility with
|
||||
every ``requests`` version that has ever existed (and ever will), OR allow
|
||||
pip to render certain versions of ``requests`` uninstallable. (The second
|
||||
issue, although technically true for any Python application, is magnified by
|
||||
pip's ubiquity; pip is installed by default in Python, in ``pyvenv``, and in
|
||||
``virtualenv``.)
|
||||
|
||||
* **Security.** This might seem puzzling at first glance, since vendoring
|
||||
has a tendency to complicate updating dependencies for security updates,
|
||||
and that holds true for pip. However, given the *other* reasons for avoiding
|
||||
dependencies, the alternative is for pip to reinvent the wheel itself.
|
||||
This is what pip did historically. It forced pip to re-implement its own
|
||||
HTTPS verification routines as a workaround for the Python standard library's
|
||||
lack of SSL validation, which resulted in similar bugs in the validation routine
|
||||
in ``requests`` and ``urllib3``, except that they had to be discovered and
|
||||
fixed independently. Even though we're vendoring, reusing libraries keeps pip
|
||||
more secure by relying on the great work of our dependencies, *and* allowing for
|
||||
faster, easier security fixes by simply pulling in newer versions of dependencies.
|
||||
**Security**
|
||||
This might seem puzzling at first glance, since vendoring has a tendency to
|
||||
complicate updating dependencies for security updates, and that holds true
|
||||
for pip. However, given the *other* reasons for avoiding dependencies, the
|
||||
alternative is for pip to reinvent the wheel itself. This is what pip did
|
||||
historically. It forced pip to re-implement its own HTTPS verification
|
||||
routines as a workaround for the Python standard library's lack of SSL
|
||||
validation, which resulted in similar bugs in the validation routine in
|
||||
``requests`` and ``urllib3``, except that they had to be discovered and
|
||||
fixed independently. Even though we're vendoring, reusing libraries keeps
|
||||
pip more secure by relying on the great work of our dependencies, *and*
|
||||
allowing for faster, easier security fixes by simply pulling in newer
|
||||
versions of dependencies.
|
||||
|
||||
* **Bootstrapping.** Currently most popular methods of installing pip rely
|
||||
on pip's self-contained nature to install pip itself. These tools work by bundling
|
||||
a copy of pip, adding it to ``sys.path``, and then executing that copy of pip.
|
||||
This is done instead of implementing a "mini installer" (to reduce duplication);
|
||||
pip already knows how to install a Python package, and is far more battle-tested
|
||||
than any "mini installer" could ever possibly be.
|
||||
**Bootstrapping**
|
||||
Currently most popular methods of installing pip rely on pip's
|
||||
self-contained nature to install pip itself. These tools work by bundling a
|
||||
copy of pip, adding it to ``sys.path``, and then executing that copy of pip.
|
||||
This is done instead of implementing a "mini installer" (to reduce
|
||||
duplication); pip already knows how to install a Python package, and is far
|
||||
more battle-tested than any "mini installer" could ever possibly be.
|
||||
|
||||
Many downstream redistributors have policies against this kind of bundling, and
|
||||
instead opt to patch the software they distribute to debundle it and make it
|
||||
|
@ -100,15 +98,19 @@ such as OS packages.
|
|||
Modifications
|
||||
=============
|
||||
|
||||
* ``setuptools`` is completely stripped to only keep ``pkg_resources``
|
||||
* ``pkg_resources`` has been modified to import its dependencies from ``pip._vendor``
|
||||
* ``packaging`` has been modified to import its dependencies from ``pip._vendor``
|
||||
* ``setuptools`` is completely stripped to only keep ``pkg_resources``.
|
||||
* ``pkg_resources`` has been modified to import its dependencies from
|
||||
``pip._vendor``.
|
||||
* ``packaging`` has been modified to import its dependencies from
|
||||
``pip._vendor``.
|
||||
* ``html5lib`` has been modified to import six from ``pip._vendor``, to prefer
|
||||
importing from ``collections.abc`` instead of ``collections`` and does not import
|
||||
``xml.etree.cElementTree`` on Python 3.
|
||||
* ``CacheControl`` has been modified to import its dependencies from ``pip._vendor``
|
||||
* ``requests`` has been modified to import its other dependencies from ``pip._vendor``
|
||||
and to *not* load ``simplejson`` (all platforms) and ``pyopenssl`` (Windows).
|
||||
importing from ``collections.abc`` instead of ``collections`` and does not
|
||||
import ``xml.etree.cElementTree`` on Python 3.
|
||||
* ``CacheControl`` has been modified to import its dependencies from
|
||||
``pip._vendor``.
|
||||
* ``requests`` has been modified to import its other dependencies from
|
||||
``pip._vendor`` and to *not* load ``simplejson`` (all platforms) and
|
||||
``pyopenssl`` (Windows).
|
||||
|
||||
|
||||
Automatic Vendoring
|
||||
|
@ -131,23 +133,18 @@ extra work on your end in order to solve the problems described above.
|
|||
|
||||
1. Delete everything in ``pip/_vendor/`` **except** for
|
||||
``pip/_vendor/__init__.py``.
|
||||
|
||||
2. Generate wheels for each of pip's dependencies (and any of their
|
||||
dependencies) using your patched copies of these libraries. These must be
|
||||
placed somewhere on the filesystem that pip can access (``pip/_vendor`` is
|
||||
the default assumption).
|
||||
|
||||
3. Modify ``pip/_vendor/__init__.py`` so that the ``DEBUNDLED`` variable is
|
||||
``True``.
|
||||
|
||||
4. Upon installation, the ``INSTALLER`` file in pip's own ``dist-info``
|
||||
directory should be set to something other than ``pip``, so that pip
|
||||
can detect that it wasn't installed using itself.
|
||||
|
||||
5. *(optional)* If you've placed the wheels in a location other than
|
||||
``pip/_vendor/``, then modify ``pip/_vendor/__init__.py`` so that the
|
||||
``WHEEL_DIR`` variable points to the location you've placed them.
|
||||
|
||||
6. *(optional)* Update the ``pip_self_version_check`` logic to use the
|
||||
appropriate logic for determining the latest available version of pip and
|
||||
prompt the user with the correct upgrade message.
|
||||
|
|
Loading…
Reference in a new issue