mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	gh-95299: Stop installing setuptools as a part of ensurepip and venv (#101039)
Remove the bundled setuptools wheel from ensurepip, and stop installing setuptools in environments created by venv. Co-Authored-by: Hugo van Kemenade <hugovk@users.noreply.github.com> Co-authored-by: C.A.M. Gerlach <CAM.Gerlach@Gerlach.CAM> Co-authored-by: Oleg Iarygin <oleg@arhadthedev.net>
This commit is contained in:
		
							parent
							
								
									f39e00f952
								
							
						
					
					
						commit
						ece20dba12
					
				
					 13 changed files with 57 additions and 48 deletions
				
			
		|  | @ -1,4 +1,4 @@ | |||
| name: Verify bundled pip and setuptools | ||||
| name: Verify bundled wheels | ||||
| 
 | ||||
| on: | ||||
|   workflow_dispatch: | ||||
|  | @ -29,5 +29,5 @@ jobs: | |||
|       - uses: actions/setup-python@v4 | ||||
|         with: | ||||
|           python-version: '3' | ||||
|       - name: Compare checksums of bundled pip and setuptools to ones published on PyPI | ||||
|       - name: Compare checksum of bundled wheels to the ones published on PyPI | ||||
|         run: ./Tools/build/verify_ensurepip_wheels.py | ||||
|  |  | |||
|  | @ -284,11 +284,14 @@ creation according to their needs, the :class:`EnvBuilder` class. | |||
| 
 | ||||
|     .. method:: upgrade_dependencies(context) | ||||
| 
 | ||||
|        Upgrades the core venv dependency packages (currently ``pip`` and | ||||
|        ``setuptools``) in the environment. This is done by shelling out to the | ||||
|        Upgrades the core venv dependency packages (currently ``pip``) | ||||
|        in the environment. This is done by shelling out to the | ||||
|        ``pip`` executable in the environment. | ||||
| 
 | ||||
|        .. versionadded:: 3.9 | ||||
|        .. versionchanged:: 3.12 | ||||
| 
 | ||||
|           ``setuptools`` is no longer a core venv dependency. | ||||
| 
 | ||||
|     .. method:: post_setup(context) | ||||
| 
 | ||||
|  |  | |||
|  | @ -61,12 +61,16 @@ 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 | ||||
|       --upgrade-deps        Upgrade core dependencies (pip) to the | ||||
|                             latest version in PyPI | ||||
| 
 | ||||
|     Once an environment has been created, you may wish to activate it, e.g. by | ||||
|     sourcing an activate script in its bin directory. | ||||
| 
 | ||||
| .. versionchanged:: 3.12 | ||||
| 
 | ||||
|    ``setuptools`` is no longer a core venv dependency. | ||||
| 
 | ||||
| .. versionchanged:: 3.9 | ||||
|    Add ``--upgrade-deps`` option to upgrade pip + setuptools to the latest on PyPI | ||||
| 
 | ||||
|  | @ -104,4 +108,3 @@ invoked to bootstrap ``pip`` into the virtual environment. | |||
| Multiple paths can be given to ``venv``, in which case an identical virtual | ||||
| environment will be created, according to the given options, at each provided | ||||
| path. | ||||
| 
 | ||||
|  |  | |||
|  | @ -731,6 +731,24 @@ Removed | |||
|   project can be installed: it still provides ``distutils``. | ||||
|   (Contributed by Victor Stinner in :gh:`92584`.) | ||||
| 
 | ||||
| * Remove the bundled setuptools wheel from :mod:`ensurepip`, | ||||
|   and stop installing setuptools in environments created by :mod:`venv`. | ||||
| 
 | ||||
|   ``pip (>= 22.1)`` does not require setuptools to be installed in the | ||||
|   environment. ``setuptools``-based (and ``distutils``-based) packages | ||||
|   can still be used with ``pip install``, since pip will provide | ||||
|   ``setuptools`` in the build environment it uses for building a | ||||
|   package. | ||||
| 
 | ||||
|   ``easy_install``, ``pkg_resources``, ``setuptools`` and ``distutils`` | ||||
|   are no longer provided by default in environments created with | ||||
|   ``venv`` or bootstrapped with ``ensurepip``, since they are part of | ||||
|   the ``setuptools`` package. For projects relying on these at runtime, | ||||
|   the ``setuptools`` project should be declared as a dependency and | ||||
|   installed separately (typically, using pip). | ||||
| 
 | ||||
|   (Contributed by Pradyun Gedam in :gh:`95299`.) | ||||
| 
 | ||||
| * Removed many old deprecated :mod:`unittest` features: | ||||
| 
 | ||||
|   - A number of :class:`~unittest.TestCase` method aliases: | ||||
|  |  | |||
|  | @ -9,11 +9,9 @@ | |||
| 
 | ||||
| 
 | ||||
| __all__ = ["version", "bootstrap"] | ||||
| _PACKAGE_NAMES = ('setuptools', 'pip') | ||||
| _SETUPTOOLS_VERSION = "65.5.0" | ||||
| _PACKAGE_NAMES = ('pip',) | ||||
| _PIP_VERSION = "23.0.1" | ||||
| _PROJECTS = [ | ||||
|     ("setuptools", _SETUPTOOLS_VERSION, "py3"), | ||||
|     ("pip", _PIP_VERSION, "py3"), | ||||
| ] | ||||
| 
 | ||||
|  | @ -153,17 +151,17 @@ def _bootstrap(*, root=None, upgrade=False, user=False, | |||
| 
 | ||||
|     _disable_pip_configuration_settings() | ||||
| 
 | ||||
|     # By default, installing pip and setuptools installs all of the | ||||
|     # By default, installing pip installs all of the | ||||
|     # following scripts (X.Y == running Python version): | ||||
|     # | ||||
|     #   pip, pipX, pipX.Y, easy_install, easy_install-X.Y | ||||
|     #   pip, pipX, pipX.Y | ||||
|     # | ||||
|     # pip 1.5+ allows ensurepip to request that some of those be left out | ||||
|     if altinstall: | ||||
|         # omit pip, pipX and easy_install | ||||
|         # omit pip, pipX | ||||
|         os.environ["ENSUREPIP_OPTIONS"] = "altinstall" | ||||
|     elif not default_pip: | ||||
|         # omit pip and easy_install | ||||
|         # omit pip | ||||
|         os.environ["ENSUREPIP_OPTIONS"] = "install" | ||||
| 
 | ||||
|     with tempfile.TemporaryDirectory() as tmpdir: | ||||
|  | @ -271,14 +269,14 @@ def _main(argv=None): | |||
|         action="store_true", | ||||
|         default=False, | ||||
|         help=("Make an alternate install, installing only the X.Y versioned " | ||||
|               "scripts (Default: pipX, pipX.Y, easy_install-X.Y)."), | ||||
|               "scripts (Default: pipX, pipX.Y)."), | ||||
|     ) | ||||
|     parser.add_argument( | ||||
|         "--default-pip", | ||||
|         action="store_true", | ||||
|         default=False, | ||||
|         help=("Make a default pip install, installing the unqualified pip " | ||||
|               "and easy_install in addition to the versioned scripts."), | ||||
|               "in addition to the versioned scripts."), | ||||
|     ) | ||||
| 
 | ||||
|     args = parser.parse_args(argv) | ||||
|  |  | |||
										
											Binary file not shown.
										
									
								
							|  | @ -20,7 +20,6 @@ def test_version(self): | |||
|         # Test version() | ||||
|         with tempfile.TemporaryDirectory() as tmpdir: | ||||
|             self.touch(tmpdir, "pip-1.2.3b1-py2.py3-none-any.whl") | ||||
|             self.touch(tmpdir, "setuptools-49.1.3-py3-none-any.whl") | ||||
|             with (unittest.mock.patch.object(ensurepip, '_PACKAGES', None), | ||||
|                   unittest.mock.patch.object(ensurepip, '_WHEEL_PKG_DIR', tmpdir)): | ||||
|                 self.assertEqual(ensurepip.version(), '1.2.3b1') | ||||
|  | @ -36,15 +35,12 @@ def test_get_packages_no_dir(self): | |||
| 
 | ||||
|         # use bundled wheel packages | ||||
|         self.assertIsNotNone(packages['pip'].wheel_name) | ||||
|         self.assertIsNotNone(packages['setuptools'].wheel_name) | ||||
| 
 | ||||
|     def test_get_packages_with_dir(self): | ||||
|         # Test _get_packages() with a wheel package directory | ||||
|         setuptools_filename = "setuptools-49.1.3-py3-none-any.whl" | ||||
|         pip_filename = "pip-20.2.2-py2.py3-none-any.whl" | ||||
| 
 | ||||
|         with tempfile.TemporaryDirectory() as tmpdir: | ||||
|             self.touch(tmpdir, setuptools_filename) | ||||
|             self.touch(tmpdir, pip_filename) | ||||
|             # not used, make sure that it's ignored | ||||
|             self.touch(tmpdir, "wheel-0.34.2-py2.py3-none-any.whl") | ||||
|  | @ -53,15 +49,12 @@ def test_get_packages_with_dir(self): | |||
|                   unittest.mock.patch.object(ensurepip, '_WHEEL_PKG_DIR', tmpdir)): | ||||
|                 packages = ensurepip._get_packages() | ||||
| 
 | ||||
|             self.assertEqual(packages['setuptools'].version, '49.1.3') | ||||
|             self.assertEqual(packages['setuptools'].wheel_path, | ||||
|                              os.path.join(tmpdir, setuptools_filename)) | ||||
|             self.assertEqual(packages['pip'].version, '20.2.2') | ||||
|             self.assertEqual(packages['pip'].wheel_path, | ||||
|                              os.path.join(tmpdir, pip_filename)) | ||||
| 
 | ||||
|             # wheel package is ignored | ||||
|             self.assertEqual(sorted(packages), ['pip', 'setuptools']) | ||||
|             self.assertEqual(sorted(packages), ['pip']) | ||||
| 
 | ||||
| 
 | ||||
| class EnsurepipMixin: | ||||
|  | @ -92,13 +85,13 @@ def test_basic_bootstrapping(self): | |||
|         self.run_pip.assert_called_once_with( | ||||
|             [ | ||||
|                 "install", "--no-cache-dir", "--no-index", "--find-links", | ||||
|                 unittest.mock.ANY, "setuptools", "pip", | ||||
|                 unittest.mock.ANY, "pip", | ||||
|             ], | ||||
|             unittest.mock.ANY, | ||||
|         ) | ||||
| 
 | ||||
|         additional_paths = self.run_pip.call_args[0][1] | ||||
|         self.assertEqual(len(additional_paths), 2) | ||||
|         self.assertEqual(len(additional_paths), 1) | ||||
| 
 | ||||
|     def test_bootstrapping_with_root(self): | ||||
|         ensurepip.bootstrap(root="/foo/bar/") | ||||
|  | @ -107,7 +100,7 @@ def test_bootstrapping_with_root(self): | |||
|             [ | ||||
|                 "install", "--no-cache-dir", "--no-index", "--find-links", | ||||
|                 unittest.mock.ANY, "--root", "/foo/bar/", | ||||
|                 "setuptools", "pip", | ||||
|                 "pip", | ||||
|             ], | ||||
|             unittest.mock.ANY, | ||||
|         ) | ||||
|  | @ -118,7 +111,7 @@ def test_bootstrapping_with_user(self): | |||
|         self.run_pip.assert_called_once_with( | ||||
|             [ | ||||
|                 "install", "--no-cache-dir", "--no-index", "--find-links", | ||||
|                 unittest.mock.ANY, "--user", "setuptools", "pip", | ||||
|                 unittest.mock.ANY, "--user", "pip", | ||||
|             ], | ||||
|             unittest.mock.ANY, | ||||
|         ) | ||||
|  | @ -129,7 +122,7 @@ def test_bootstrapping_with_upgrade(self): | |||
|         self.run_pip.assert_called_once_with( | ||||
|             [ | ||||
|                 "install", "--no-cache-dir", "--no-index", "--find-links", | ||||
|                 unittest.mock.ANY, "--upgrade", "setuptools", "pip", | ||||
|                 unittest.mock.ANY, "--upgrade", "pip", | ||||
|             ], | ||||
|             unittest.mock.ANY, | ||||
|         ) | ||||
|  | @ -140,7 +133,7 @@ def test_bootstrapping_with_verbosity_1(self): | |||
|         self.run_pip.assert_called_once_with( | ||||
|             [ | ||||
|                 "install", "--no-cache-dir", "--no-index", "--find-links", | ||||
|                 unittest.mock.ANY, "-v", "setuptools", "pip", | ||||
|                 unittest.mock.ANY, "-v", "pip", | ||||
|             ], | ||||
|             unittest.mock.ANY, | ||||
|         ) | ||||
|  | @ -151,7 +144,7 @@ def test_bootstrapping_with_verbosity_2(self): | |||
|         self.run_pip.assert_called_once_with( | ||||
|             [ | ||||
|                 "install", "--no-cache-dir", "--no-index", "--find-links", | ||||
|                 unittest.mock.ANY, "-vv", "setuptools", "pip", | ||||
|                 unittest.mock.ANY, "-vv", "pip", | ||||
|             ], | ||||
|             unittest.mock.ANY, | ||||
|         ) | ||||
|  | @ -162,7 +155,7 @@ def test_bootstrapping_with_verbosity_3(self): | |||
|         self.run_pip.assert_called_once_with( | ||||
|             [ | ||||
|                 "install", "--no-cache-dir", "--no-index", "--find-links", | ||||
|                 unittest.mock.ANY, "-vvv", "setuptools", "pip", | ||||
|                 unittest.mock.ANY, "-vvv", "pip", | ||||
|             ], | ||||
|             unittest.mock.ANY, | ||||
|         ) | ||||
|  | @ -239,7 +232,6 @@ def test_uninstall(self): | |||
|         self.run_pip.assert_called_once_with( | ||||
|             [ | ||||
|                 "uninstall", "-y", "--disable-pip-version-check", "pip", | ||||
|                 "setuptools", | ||||
|             ] | ||||
|         ) | ||||
| 
 | ||||
|  | @ -250,7 +242,6 @@ def test_uninstall_with_verbosity_1(self): | |||
|         self.run_pip.assert_called_once_with( | ||||
|             [ | ||||
|                 "uninstall", "-y", "--disable-pip-version-check", "-v", "pip", | ||||
|                 "setuptools", | ||||
|             ] | ||||
|         ) | ||||
| 
 | ||||
|  | @ -261,7 +252,6 @@ def test_uninstall_with_verbosity_2(self): | |||
|         self.run_pip.assert_called_once_with( | ||||
|             [ | ||||
|                 "uninstall", "-y", "--disable-pip-version-check", "-vv", "pip", | ||||
|                 "setuptools", | ||||
|             ] | ||||
|         ) | ||||
| 
 | ||||
|  | @ -272,7 +262,7 @@ def test_uninstall_with_verbosity_3(self): | |||
|         self.run_pip.assert_called_once_with( | ||||
|             [ | ||||
|                 "uninstall", "-y", "--disable-pip-version-check", "-vvv", | ||||
|                 "pip", "setuptools", | ||||
|                 "pip" | ||||
|             ] | ||||
|         ) | ||||
| 
 | ||||
|  | @ -312,13 +302,13 @@ def test_basic_bootstrapping(self): | |||
|         self.run_pip.assert_called_once_with( | ||||
|             [ | ||||
|                 "install", "--no-cache-dir", "--no-index", "--find-links", | ||||
|                 unittest.mock.ANY, "setuptools", "pip", | ||||
|                 unittest.mock.ANY, "pip", | ||||
|             ], | ||||
|             unittest.mock.ANY, | ||||
|         ) | ||||
| 
 | ||||
|         additional_paths = self.run_pip.call_args[0][1] | ||||
|         self.assertEqual(len(additional_paths), 2) | ||||
|         self.assertEqual(len(additional_paths), 1) | ||||
|         self.assertEqual(exit_code, 0) | ||||
| 
 | ||||
|     def test_bootstrapping_error_code(self): | ||||
|  | @ -344,7 +334,6 @@ def test_basic_uninstall(self): | |||
|         self.run_pip.assert_called_once_with( | ||||
|             [ | ||||
|                 "uninstall", "-y", "--disable-pip-version-check", "pip", | ||||
|                 "setuptools", | ||||
|             ] | ||||
|         ) | ||||
| 
 | ||||
|  |  | |||
|  | @ -227,7 +227,6 @@ def pip_cmd_checker(cmd, **kwargs): | |||
|                         'install', | ||||
|                         '--upgrade', | ||||
|                         'pip', | ||||
|                         'setuptools' | ||||
|                     ] | ||||
|                 ) | ||||
| 
 | ||||
|  | @ -745,7 +744,6 @@ def do_test_with_pip(self, system_site_packages): | |||
|         # future pip versions, this test can likely be relaxed further. | ||||
|         out = out.decode("latin-1") # Force to text, prevent decoding errors | ||||
|         self.assertIn("Successfully uninstalled pip", out) | ||||
|         self.assertIn("Successfully uninstalled setuptools", out) | ||||
|         # Check pip is now gone from the virtual environment. This only | ||||
|         # applies in the system_site_packages=False case, because in the | ||||
|         # other case, pip may still be available in the system site-packages | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ | |||
| import types | ||||
| 
 | ||||
| 
 | ||||
| CORE_VENV_DEPS = ('pip', 'setuptools') | ||||
| CORE_VENV_DEPS = ('pip',) | ||||
| logger = logging.getLogger(__name__) | ||||
| 
 | ||||
| 
 | ||||
|  | @ -523,7 +523,7 @@ def main(args=None): | |||
|                              'this environment.') | ||||
|     parser.add_argument('--upgrade-deps', default=False, action='store_true', | ||||
|                         dest='upgrade_deps', | ||||
|                         help=f'Upgrade core dependencies: {", ".join(CORE_VENV_DEPS)} ' | ||||
|                         help=f'Upgrade core dependencies ({", ".join(CORE_VENV_DEPS)}) ' | ||||
|                              'to the latest version in PyPI') | ||||
|     options = parser.parse_args(args) | ||||
|     if options.upgrade and options.clear: | ||||
|  |  | |||
|  | @ -56,19 +56,19 @@ if [ -d /usr/local/bin ] ; then | |||
| 
 | ||||
|         cd /usr/local/bin | ||||
| 
 | ||||
|         # Create pipx.y and easy_install-x.y links if /usr/local/bin/pythonx.y | ||||
|         # Create pipx.y links if /usr/local/bin/pythonx.y | ||||
|         #   is linked to this framework version | ||||
|         install_links_if_our_fw "python${PYVER}" \ | ||||
|                                     "pip${PYVER}" "easy_install-${PYVER}" | ||||
|                                     "pip${PYVER}" | ||||
| 
 | ||||
|         # Create pipx link if /usr/local/bin/pythonx is linked to this version | ||||
|         install_links_if_our_fw "python${PYMAJOR}" \ | ||||
|                                     "pip${PYMAJOR}" | ||||
| 
 | ||||
|         # Create pip and easy_install link if /usr/local/bin/python | ||||
|         # Create pip link if /usr/local/bin/python | ||||
|         #   is linked to this version | ||||
|         install_links_if_our_fw "python" \ | ||||
|                                     "pip" "easy_install" | ||||
|                                     "pip" | ||||
|     ) | ||||
| fi | ||||
| exit 0 | ||||
|  |  | |||
|  | @ -166,7 +166,6 @@ altinstallunixtools: | |||
| 	-if test "x$(ENSUREPIP)" != "xno"  ; then \
 | ||||
| 		cd "$(DESTDIR)$(FRAMEWORKUNIXTOOLSPREFIX)/bin" && \
 | ||||
| 		for fn in \
 | ||||
| 				easy_install-$(VERSION) \
 | ||||
| 				pip$(VERSION) \
 | ||||
| 				; \
 | ||||
| 		do \
 | ||||
|  |  | |||
|  | @ -0,0 +1 @@ | |||
| Remove the bundled setuptools wheel from ``ensurepip``, and stop installing setuptools in environments created by ``venv``. | ||||
|  | @ -14,7 +14,7 @@ | |||
| from pathlib import Path | ||||
| from urllib.request import urlopen | ||||
| 
 | ||||
| PACKAGE_NAMES = ("pip", "setuptools") | ||||
| PACKAGE_NAMES = ("pip",) | ||||
| ENSURE_PIP_ROOT = Path(__file__).parent.parent.parent / "Lib/ensurepip" | ||||
| WHEEL_DIR = ENSURE_PIP_ROOT / "_bundled" | ||||
| ENSURE_PIP_INIT_PY_TEXT = (ENSURE_PIP_ROOT / "__init__.py").read_text(encoding="utf-8") | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Pradyun Gedam
						Pradyun Gedam