Skip to content

Commit d0cf063

Browse files
committed
Close #19406: Initial implementation of ensurepip
Patch by Donald Stufft and Nick Coghlan
1 parent 020af2a commit d0cf063

16 files changed

Lines changed: 488 additions & 2 deletions

.hgeol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
**.psd = BIN
2727
**.tar = BIN
2828
**.wav = BIN
29+
**.whl = BIN
2930
**.xar = BIN
3031
**.zip = BIN
3132

Doc/library/development.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,3 @@ The list of modules described in this chapter is:
2323
unittest.mock-examples.rst
2424
2to3.rst
2525
test.rst
26-
venv.rst

Doc/library/distribution.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
***********************************
2+
Software Packaging and Distribution
3+
***********************************
4+
5+
These libraries help you with publishing and installing Python software.
6+
While these modules are designed to work in conjunction with the
7+
`Python Package Index <https://pypi.python.org>`__, they can also be used
8+
with a local index server, or without any index server at all.
9+
10+
.. toctree::
11+
12+
distutils.rst
13+
ensurepip.rst
14+
venv.rst

Doc/library/ensurepip.rst

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
:mod:`ensurepip` --- Bootstrapping the ``pip`` installer
2+
========================================================
3+
4+
.. module:: ensurepip
5+
:synopsis: Bootstrapping the ``pip`` installer into an existing Python
6+
installation or virtual environment.
7+
8+
The :mod:`ensurepip` package provides support for bootstrapping the ``pip``
9+
installer into an existing Python installation or virtual environment. This
10+
bootstrapping approach reflects the fact that ``pip`` is an independent
11+
project with its own release cycle, and the latest available stable version
12+
is bundled with maintenance and feature releases of the CPython reference
13+
interpreter.
14+
15+
In most cases, end users of Python shouldn't need to invoke this module
16+
directly (as ``pip`` should be bootstrapped by default), but it may be
17+
needed if installing ``pip`` was skipped when installing Python (or
18+
when creating a virtual environment) or after explicitly uninstalling
19+
``pip``.
20+
21+
.. versionadded:: 3.4
22+
23+
.. note::
24+
25+
This module *does not* access the internet. All of the components
26+
needed to bootstrap ``pip`` are included as internal parts of the
27+
package.
28+
29+
.. seealso::
30+
31+
:ref:`install-index`
32+
The end user guide for installing Python packages
33+
34+
:pep:`453`: Explicit bootstrapping of pip in Python installations
35+
The original rationale and specification for this module.
36+
37+
38+
Command line interface
39+
----------------------
40+
41+
The command line interface is invoked using the interpreter's ``-m`` switch.
42+
43+
The simplest possible invocation is::
44+
45+
python -m ensurepip
46+
47+
This invocation will install ``pip`` if it is not already installed,
48+
but otherwise does nothing. To ensure the installed version of ``pip``
49+
is at least as recent as the one bundled with ``ensurepip``, pass the
50+
``--upgrade`` option::
51+
52+
python -m ensurepip --upgrade
53+
54+
By default, ``pip`` is installed into the current virtual environment
55+
(if one is active) or into the system site packages (if there is no
56+
active virtual environment). The installation location can be controlled
57+
through two additional command line options:
58+
59+
* ``--root <dir>``: Installs ``pip`` relative to the given root directory
60+
rather than the root of the currently active virtual environment (if any)
61+
or the default root for the current Python installation.
62+
* ``--user``: Installs ``pip`` into the user site packages directory rather
63+
than globally for the current Python installation (this option is not
64+
permitted inside an active virtual environment).
65+
66+
By default, the scripts ``pipX`` and ``pipX.Y`` will be installed (where
67+
X.Y stands for the version of Python used to invoke ``ensurepip``). The
68+
scripts installed can be controlled through two additional command line
69+
options:
70+
71+
* ``--altinstall``: if an alternate installation is requested, the ``pipX``
72+
script will *not* be installed.
73+
74+
* ``--default-pip``: if a "default pip" installation is requested, the
75+
``pip`` script will be installed in addition to the two regular scripts.
76+
77+
Providing both of the script selection options will trigger an exception.
78+
79+
80+
Module API
81+
----------
82+
83+
:mod:`ensurepip` exposes two functions for programmatic use:
84+
85+
.. function:: version()
86+
87+
Returns a string specifying the bundled version of pip that will be
88+
installed when bootstrapping an environment.
89+
90+
.. function:: bootstrap(root=None, upgrade=False, user=False, \
91+
altinstall=False, default_pip=False, \
92+
verbosity=0)
93+
94+
Bootstraps ``pip`` into the current or designated environment.
95+
96+
*root* specifies an alternative root directory to install relative to.
97+
If *root* is None, then installation uses the default install location
98+
for the current environment.
99+
100+
*upgrade* indicates whether or not to upgrade an existing installation
101+
of an earlier version of ``pip`` to the bundled version.
102+
103+
*user* indicates whether to use the user scheme rather than installing
104+
globally.
105+
106+
By default, the scripts ``pipX`` and ``pipX.Y`` will be installed (where
107+
X.Y stands for the current version of Python).
108+
109+
If *altinstall* is set, then ``pipX`` will *not* be installed.
110+
111+
If *default_pip* is set, then ``pip`` will be installed in addition to
112+
the two regular scripts.
113+
114+
Setting both *altinstall* and *default_pip* will trigger
115+
:exc:`ValueError`.
116+
117+
*verbosity* controls the level of output to :data:`sys.stdout` from the
118+
bootstrapping operation.
119+
120+
.. note::
121+
122+
The bootstrapping process may install additional modules required by
123+
``pip``, but other software should not assume those dependencies will
124+
always be present by default (as the dependencies may be removed in a
125+
future version of ``pip``).

Doc/library/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ the `Python Package Index <http://pypi.python.org/pypi>`_.
6565
tk.rst
6666
development.rst
6767
debug.rst
68+
distribution.rst
6869
python.rst
6970
custominterp.rst
7071
modules.rst

Doc/library/python.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,3 @@ overview:
2525
inspect.rst
2626
site.rst
2727
fpectl.rst
28-
distutils.rst

Doc/whatsnew/3.4.rst

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ New library modules:
9292

9393
* :mod:`asyncio`: New provisonal API for asynchronous IO (:pep:`3156`).
9494
* :mod:`enum`: Support for enumeration types (:pep:`435`).
95+
* :mod:`ensurepip`: Bootstrapping the pip installer (:pep:`453`).
9596
* :mod:`selectors`: High-level and efficient I/O multiplexing, built upon the
9697
:mod:`select` module primitives.
9798
* :mod:`statistics`: A basic numerically stable statistics library (:pep:`450`).
@@ -123,6 +124,34 @@ CPython implementation improvements:
123124

124125
Please read on for a comprehensive list of user-facing changes.
125126

127+
128+
PEP 453: Explicit bootstrapping of pip in Python installations
129+
==============================================================
130+
131+
The new :mod:`ensurepip` module (defined in :pep:`453`) provides a standard
132+
cross-platform mechanism to boostrap the pip installer into Python
133+
installations and virtual environments.
134+
135+
.. note::
136+
137+
Only the first phase of PEP 453 has been implemented at this point.
138+
This section will be fleshed out with additional details once those
139+
other changes are implemented.
140+
141+
Refer to :issue:`19347` for the progress on additional steps:
142+
143+
* ``make install`` and ``make altinstall`` integration
144+
* Windows installer integration
145+
* Mac OS X installer integration
146+
* :mod:`venv` module and :command:`pyvenv` integration
147+
148+
.. seealso::
149+
150+
:pep:`453` - Explicit bootstrapping of pip in Python installations
151+
PEP written by Donald Stufft and Nick Coghlan, implemented by
152+
Donald Stufft, Nick Coghlan (and ...).
153+
154+
126155
.. _pep-446:
127156

128157
PEP 446: Make newly created file descriptors non-inheritable

Lib/ensurepip/__init__.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import os
2+
import os.path
3+
import pkgutil
4+
import sys
5+
import tempfile
6+
7+
# TODO: Remove the --pre flag when a pip 1.5 final copy is available
8+
9+
10+
__all__ = ["version", "bootstrap"]
11+
12+
13+
_SETUPTOOLS_VERSION = "1.3.2"
14+
15+
_PIP_VERSION = "1.5.dev1"
16+
17+
_PROJECTS = [
18+
("setuptools", _SETUPTOOLS_VERSION),
19+
("pip", _PIP_VERSION),
20+
]
21+
22+
23+
def _run_pip(args, additional_paths):
24+
# Add our bundled software to the sys.path so we can import it
25+
sys.path = additional_paths + sys.path
26+
27+
# Install the bundled software
28+
import pip
29+
pip.main(args)
30+
31+
32+
def version():
33+
"""
34+
Returns a string specifying the bundled version of pip.
35+
"""
36+
return _PIP_VERSION
37+
38+
39+
def bootstrap(*, root=None, upgrade=False, user=False,
40+
altinstall=False, default_pip=False,
41+
verbosity=0):
42+
"""
43+
Bootstrap pip into the current Python installation (or the given root
44+
directory).
45+
"""
46+
if altinstall and default_pip:
47+
raise ValueError("Cannot use altinstall and default_pip together")
48+
49+
# By default, installing pip and setuptools installs all of the
50+
# following scripts (X.Y == running Python version):
51+
#
52+
# pip, pipX, pipX.Y, easy_install, easy_install-X.Y
53+
#
54+
# pip 1.5+ allows ensurepip to request that some of those be left out
55+
if altinstall:
56+
# omit pip, pipX and easy_install
57+
os.environ["ENSUREPIP_OPTIONS"] = "altinstall"
58+
elif not default_pip:
59+
# omit pip and easy_install
60+
os.environ["ENSUREPIP_OPTIONS"] = "install"
61+
62+
with tempfile.TemporaryDirectory() as tmpdir:
63+
# Put our bundled wheels into a temporary directory and construct the
64+
# additional paths that need added to sys.path
65+
additional_paths = []
66+
for project, version in _PROJECTS:
67+
wheel_name = "{}-{}-py2.py3-none-any.whl".format(project, version)
68+
whl = pkgutil.get_data(
69+
"ensurepip",
70+
"_bundled/{}".format(wheel_name),
71+
)
72+
with open(os.path.join(tmpdir, wheel_name), "wb") as fp:
73+
fp.write(whl)
74+
75+
additional_paths.append(os.path.join(tmpdir, wheel_name))
76+
77+
# Construct the arguments to be passed to the pip command
78+
args = [
79+
"install", "--no-index", "--find-links", tmpdir,
80+
# Temporary until pip 1.5 is final
81+
"--pre",
82+
]
83+
if root:
84+
args += ["--root", root]
85+
if upgrade:
86+
args += ["--upgrade"]
87+
if user:
88+
args += ["--user"]
89+
if verbosity:
90+
args += ["-" + "v" * verbosity]
91+
92+
_run_pip(args + [p[0] for p in _PROJECTS], additional_paths)

Lib/ensurepip/__main__.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import argparse
2+
import ensurepip
3+
4+
5+
def main():
6+
parser = argparse.ArgumentParser(prog="python -m ensurepip")
7+
parser.add_argument(
8+
"--version",
9+
action="version",
10+
version="pip {}".format(ensurepip.version()),
11+
help="Show the version of pip that is bundled with this Python.",
12+
)
13+
parser.add_argument(
14+
"-v", "--verbose",
15+
action="count",
16+
default=0,
17+
dest="verbosity",
18+
help=("Give more output. Option is additive, and can be used up to 3 "
19+
"times."),
20+
)
21+
parser.add_argument(
22+
"-U", "--upgrade",
23+
action="store_true",
24+
default=False,
25+
help="Upgrade pip and dependencies, even if already installed.",
26+
)
27+
parser.add_argument(
28+
"--user",
29+
action="store_true",
30+
default=False,
31+
help="Install using the user scheme.",
32+
)
33+
parser.add_argument(
34+
"--root",
35+
default=None,
36+
help="Install everything relative to this alternate root directory.",
37+
)
38+
parser.add_argument(
39+
"--altinstall",
40+
action="store_true",
41+
default=False,
42+
help=("Make an alternate install, installing only the X.Y versioned"
43+
"scripts (Default: pipX, pipX.Y, easy_install-X.Y)"),
44+
)
45+
parser.add_argument(
46+
"--default-pip",
47+
action="store_true",
48+
default=False,
49+
help=("Make a default pip install, installing the unqualified pip "
50+
"and easy_install in addition to the versioned scripts"),
51+
)
52+
53+
args = parser.parse_args()
54+
55+
ensurepip.bootstrap(
56+
root=args.root,
57+
upgrade=args.upgrade,
58+
user=args.user,
59+
verbosity=args.verbosity,
60+
altinstall=args.altinstall,
61+
default_pip=args.default_pip,
62+
)
63+
64+
65+
if __name__ == "__main__":
66+
main()
909 KB
Binary file not shown.

0 commit comments

Comments
 (0)