[Python-checkins] (no subject)

Łukasz Langa webhook-mailer at python.org
Mon Jun 17 14:18:29 EDT 2019




To: python-checkins at python.org
Subject: bpo-34556: Add --upgrade-deps to venv module (#13100)
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0

https://github.com/python/cpython/commit/4acdbf11b1fae1af24c47413a6caa593010d=
1b6f
commit: 4acdbf11b1fae1af24c47413a6caa593010d1b6f
branch: master
author: Cooper Lees <cooper at fb.com>
committer: =C5=81ukasz Langa <lukasz at langa.pl>
date: 2019-06-17T19:18:13+01:00
summary:

bpo-34556: Add --upgrade-deps to venv module (#13100)

Add --upgrade-deps to venv module
- This allows for pip + setuptools to be automatically upgraded to the latest=
 version on PyPI
- Update documentation to represent this change

bpo-34556: Add --upgrade to venv module

files:
A Misc/NEWS.d/next/Core and Builtins/2019-05-05-18-09-40.bpo-34556.o9kfpu.rst
M Doc/library/venv.rst
M Doc/using/venv-create.inc
M Lib/test/test_venv.py
M Lib/venv/__init__.py

diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst
index 4f083a3181e7..d3d5ae2b007d 100644
--- a/Doc/library/venv.rst
+++ b/Doc/library/venv.rst
@@ -97,7 +97,7 @@ creation according to their needs, the :class:`EnvBuilder` =
class.
=20
 .. class:: EnvBuilder(system_site_packages=3DFalse, clear=3DFalse, \
                       symlinks=3DFalse, upgrade=3DFalse, with_pip=3DFalse, \
-                      prompt=3DNone)
+                      prompt=3DNone, upgrade_deps=3DFalse)
=20
     The :class:`EnvBuilder` class accepts the following keyword arguments on
     instantiation:
@@ -123,12 +123,17 @@ creation according to their needs, the :class:`EnvBuild=
er` class.
       (defaults to ``None`` which means directory name of the environment wo=
uld
       be used).
=20
+    * ``upgrade_deps`` -- Update the base venv modules to the latest on PyPI
+
     .. versionchanged:: 3.4
        Added the ``with_pip`` parameter
=20
     .. versionadded:: 3.6
        Added the ``prompt`` parameter
=20
+    .. versionadded:: 3.8
+       Added the ``upgrade_deps`` parameter
+
     Creators of third-party virtual environment tools will be free to use the
     provided ``EnvBuilder`` class as a base class.
=20
diff --git a/Doc/using/venv-create.inc b/Doc/using/venv-create.inc
index 1ada83c07a67..8fd107b33202 100644
--- a/Doc/using/venv-create.inc
+++ b/Doc/using/venv-create.inc
@@ -35,7 +35,7 @@ your :ref:`Python installation <using-on-windows>`::
 The command, if run with ``-h``, will show the available options::
=20
     usage: venv [-h] [--system-site-packages] [--symlinks | --copies] [--cle=
ar]
-                [--upgrade] [--without-pip] [--prompt PROMPT]
+                [--upgrade] [--without-pip] [--prompt PROMPT] [--upgrade-dep=
s]
                 ENV_DIR [ENV_DIR ...]
=20
     Creates virtual Python environments in one or more target directories.
@@ -60,10 +60,15 @@ The command, if run with ``-h``, will show the available =
options::
                             environment (pip is bootstrapped by default)
       --prompt PROMPT       Provides an alternative prompt prefix for this
                             environment.
+      --upgrade-deps        Upgrade core dependencies: pip setuptools to the
+                            latest version in PyPI
=20
     Once an environment has been created, you may wish to activate it, e.g. =
by
     sourcing an activate script in its bin directory.
=20
+.. versionchanged:: 3.8
+   Add ``--upgrade-deps`` option to upgrade pip + setuptools to the latest o=
n PyPI
+
 .. versionchanged:: 3.4
    Installs pip by default, added the ``--without-pip``  and ``--copies``
    options
diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py
index 24d3a69b1878..4f6c11b2663e 100644
--- a/Lib/test/test_venv.py
+++ b/Lib/test/test_venv.py
@@ -16,9 +16,9 @@
 from test.support import (captured_stdout, captured_stderr, requires_zlib,
                           can_symlink, EnvironmentVarGuard, rmtree,
                           import_module)
-import threading
 import unittest
 import venv
+from unittest.mock import patch
=20
 try:
     import ctypes
@@ -131,6 +131,28 @@ def test_prompt(self):
         self.assertEqual(context.prompt, '(My prompt) ')
         self.assertIn("prompt =3D 'My prompt'\n", data)
=20
+    def test_upgrade_dependencies(self):
+        builder =3D venv.EnvBuilder()
+        bin_path =3D 'Scripts' if sys.platform =3D=3D 'win32' else 'bin'
+        pip_exe =3D 'pip.exe' if sys.platform =3D=3D 'win32' else 'pip'
+        with tempfile.TemporaryDirectory() as fake_env_dir:
+
+            def pip_cmd_checker(cmd):
+                self.assertEqual(
+                    cmd,
+                    [
+                        os.path.join(fake_env_dir, bin_path, pip_exe),
+                        'install',
+                        '-U',
+                        'pip',
+                        'setuptools'
+                    ]
+                )
+
+            fake_context =3D builder.ensure_directories(fake_env_dir)
+            with patch('venv.subprocess.check_call', pip_cmd_checker):
+                builder.upgrade_dependencies(fake_context)
+
     @requireVenvCreate
     def test_prefixes(self):
         """
diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py
index 4a49b240b8e2..b64125fa4fe1 100644
--- a/Lib/venv/__init__.py
+++ b/Lib/venv/__init__.py
@@ -12,6 +12,8 @@
 import sysconfig
 import types
=20
+
+CORE_VENV_DEPS =3D ('pip', 'setuptools')
 logger =3D logging.getLogger(__name__)
=20
=20
@@ -38,16 +40,19 @@ class EnvBuilder:
     :param with_pip: If True, ensure pip is installed in the virtual
                      environment
     :param prompt: Alternative terminal prefix for the environment.
+    :param upgrade_deps: Update the base venv modules to the latest on PyPI
     """
=20
     def __init__(self, system_site_packages=3DFalse, clear=3DFalse,
-                 symlinks=3DFalse, upgrade=3DFalse, with_pip=3DFalse, prompt=
=3DNone):
+                 symlinks=3DFalse, upgrade=3DFalse, with_pip=3DFalse, prompt=
=3DNone,
+                 upgrade_deps=3DFalse):
         self.system_site_packages =3D system_site_packages
         self.clear =3D clear
         self.symlinks =3D symlinks
         self.upgrade =3D upgrade
         self.with_pip =3D with_pip
         self.prompt =3D prompt
+        self.upgrade_deps =3D upgrade_deps
=20
     def create(self, env_dir):
         """
@@ -74,6 +79,8 @@ def create(self, env_dir):
             # restore it and rewrite the configuration
             self.system_site_packages =3D True
             self.create_configuration(context)
+        if self.upgrade_deps:
+            self.upgrade_dependencies(context)
=20
     def clear_directory(self, path):
         for fn in os.listdir(path):
@@ -105,7 +112,6 @@ def create_if_needed(d):
         prompt =3D self.prompt if self.prompt is not None else context.env_n=
ame
         context.prompt =3D '(%s) ' % prompt
         create_if_needed(env_dir)
-        env =3D os.environ
         executable =3D getattr(sys, '_base_executable', sys.executable)
         dirname, exename =3D os.path.split(os.path.abspath(executable))
         context.executable =3D executable
@@ -363,13 +369,25 @@ def install_scripts(self, context, path):
                         f.write(data)
                     shutil.copymode(srcfile, dstfile)
=20
+    def upgrade_dependencies(self, context):
+        logger.debug(
+            f'Upgrading {CORE_VENV_DEPS} packages in {context.bin_path}'
+        )
+        if sys.platform =3D=3D 'win32':
+            pip_exe =3D os.path.join(context.bin_path, 'pip.exe')
+        else:
+            pip_exe =3D os.path.join(context.bin_path, 'pip')
+        cmd =3D [pip_exe, 'install', '-U']
+        cmd.extend(CORE_VENV_DEPS)
+        subprocess.check_call(cmd)
+
=20
 def create(env_dir, system_site_packages=3DFalse, clear=3DFalse,
-                    symlinks=3DFalse, with_pip=3DFalse, prompt=3DNone):
+           symlinks=3DFalse, with_pip=3DFalse, prompt=3DNone, upgrade_deps=
=3DFalse):
     """Create a virtual environment in a directory."""
     builder =3D EnvBuilder(system_site_packages=3Dsystem_site_packages,
                          clear=3Dclear, symlinks=3Dsymlinks, with_pip=3Dwith=
_pip,
-                         prompt=3Dprompt)
+                         prompt=3Dprompt, upgrade_deps=3Dupgrade_deps)
     builder.create(env_dir)
=20
 def main(args=3DNone):
@@ -432,6 +450,11 @@ def main(args=3DNone):
         parser.add_argument('--prompt',
                             help=3D'Provides an alternative prompt prefix fo=
r '
                                  'this environment.')
+        parser.add_argument('--upgrade-deps', default=3DFalse, action=3D'sto=
re_true',
+                            dest=3D'upgrade_deps',
+                            help=3D'Upgrade core dependencies: {} to the lat=
est '
+                                 'version in PyPI'.format(
+                                 ' '.join(CORE_VENV_DEPS)))
         options =3D parser.parse_args(args)
         if options.upgrade and options.clear:
             raise ValueError('you cannot supply --upgrade and --clear togeth=
er.')
@@ -440,7 +463,8 @@ def main(args=3DNone):
                              symlinks=3Doptions.symlinks,
                              upgrade=3Doptions.upgrade,
                              with_pip=3Doptions.with_pip,
-                             prompt=3Doptions.prompt)
+                             prompt=3Doptions.prompt,
+                             upgrade_deps=3Doptions.upgrade_deps)
         for d in options.dirs:
             builder.create(d)
=20
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-05-18-09-40.bpo-34556=
.o9kfpu.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-05-18-09-40.bpo-3455=
6.o9kfpu.rst
new file mode 100644
index 000000000000..7861eac5cb25
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-05-18-09-40.bpo-34556.o9kfpu=
.rst=09
@@ -0,0 +1 @@
+Add ``--upgrade-deps`` to venv module. Patch by Cooper Ry Lees



More information about the Python-checkins mailing list