summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/ensurepip.rst6
-rw-r--r--Lib/ensurepip/__init__.py8
-rw-r--r--Lib/test/test_ensurepip.py8
-rw-r--r--Lib/test/test_venv.py14
4 files changed, 27 insertions, 9 deletions
diff --git a/Doc/library/ensurepip.rst b/Doc/library/ensurepip.rst
index 528370c..0d82135 100644
--- a/Doc/library/ensurepip.rst
+++ b/Doc/library/ensurepip.rst
@@ -119,6 +119,12 @@ Module API
.. note::
+ The bootstrapping process has side effects on both ``sys.path`` and
+ ``os.environ``. Invoking the command line interface in a subprocess
+ instead allows these side effects to be avoided.
+
+ .. note::
+
The bootstrapping process may install additional modules required by
``pip``, but other software should not assume those dependencies will
always be present by default (as the dependencies may be removed in a
diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py
index b6bc4b6..5ceda51 100644
--- a/Lib/ensurepip/__init__.py
+++ b/Lib/ensurepip/__init__.py
@@ -43,10 +43,18 @@ def bootstrap(*, root=None, upgrade=False, user=False,
"""
Bootstrap pip into the current Python installation (or the given root
directory).
+
+ Note that calling this function will alter both sys.path and os.environ.
"""
if altinstall and default_pip:
raise ValueError("Cannot use altinstall and default_pip together")
+ # We deliberately ignore all pip environment variables
+ # See http://bugs.python.org/issue19734 for details
+ keys_to_remove = [k for k in os.environ if k.startswith("PIP_")]
+ for k in keys_to_remove:
+ del os.environ[k]
+
# By default, installing pip and setuptools installs all of the
# following scripts (X.Y == running Python version):
#
diff --git a/Lib/test/test_ensurepip.py b/Lib/test/test_ensurepip.py
index c119327..8c125bf 100644
--- a/Lib/test/test_ensurepip.py
+++ b/Lib/test/test_ensurepip.py
@@ -126,6 +126,14 @@ class TestBootstrap(unittest.TestCase):
ensurepip.bootstrap(altinstall=True, default_pip=True)
self.run_pip.assert_not_called()
+ def test_pip_environment_variables_removed(self):
+ # ensurepip deliberately ignores all pip environment variables
+ # See http://bugs.python.org/issue19734 for details
+ self.os_environ["PIP_THIS_SHOULD_GO_AWAY"] = "test fodder"
+ ensurepip.bootstrap()
+ self.assertNotIn("PIP_THIS_SHOULD_GO_AWAY", self.os_environ)
+
+
@contextlib.contextmanager
def fake_pip(version=ensurepip._PIP_VERSION):
if version is None:
diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py
index eb225fa..e8437cf 100644
--- a/Lib/test/test_venv.py
+++ b/Lib/test/test_venv.py
@@ -294,11 +294,12 @@ class EnsurePipTest(BaseTest):
# warnings in current versions of Python. Ensure related
# environment settings don't cause venv to fail.
envvars["PYTHONWARNINGS"] = "e"
- # pip doesn't ignore environment variables when running in
- # isolated mode, and we don't have an active virtualenv here,
- # we're relying on the native venv support in 3.3+
+ # ensurepip is different enough from a normal pip invocation
+ # that we want to ensure it ignores the normal pip environment
+ # variable settings. We set PIP_NO_INSTALL here specifically
+ # to check that ensurepip (and hence venv) ignores it.
# See http://bugs.python.org/issue19734 for details
- del envvars["PIP_REQUIRE_VIRTUALENV"]
+ envvars["PIP_NO_INSTALL"] = "1"
try:
self.run_with_capture(venv.create, self.env_dir, with_pip=True)
except subprocess.CalledProcessError as exc:
@@ -328,11 +329,6 @@ class EnsurePipTest(BaseTest):
# installers works (at least in a virtual environment)
cmd = [envpy, '-Im', 'ensurepip._uninstall']
with EnvironmentVarGuard() as envvars:
- # pip doesn't ignore environment variables when running in
- # isolated mode, and we don't have an active virtualenv here,
- # we're relying on the native venv support in 3.3+
- # See http://bugs.python.org/issue19734 for details
- del envvars["PIP_REQUIRE_VIRTUALENV"]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
out, err = p.communicate()