mirror of https://github.com/python/cpython
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
|
@ -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 @@ from importlib import resources
|
|||
|
||||
|
||||
__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 @@ class TestPackages(unittest.TestCase):
|
|||
# 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 @@ class TestPackages(unittest.TestCase):
|
|||
|
||||
# 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 @@ class TestPackages(unittest.TestCase):
|
|||
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 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase):
|
|||
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 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase):
|
|||
[
|
||||
"install", "--no-cache-dir", "--no-index", "--find-links",
|
||||
unittest.mock.ANY, "--root", "/foo/bar/",
|
||||
"setuptools", "pip",
|
||||
"pip",
|
||||
],
|
||||
unittest.mock.ANY,
|
||||
)
|
||||
|
@ -118,7 +111,7 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase):
|
|||
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 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase):
|
|||
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 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase):
|
|||
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 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase):
|
|||
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 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase):
|
|||
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 @@ class TestUninstall(EnsurepipMixin, unittest.TestCase):
|
|||
self.run_pip.assert_called_once_with(
|
||||
[
|
||||
"uninstall", "-y", "--disable-pip-version-check", "pip",
|
||||
"setuptools",
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -250,7 +242,6 @@ class TestUninstall(EnsurepipMixin, unittest.TestCase):
|
|||
self.run_pip.assert_called_once_with(
|
||||
[
|
||||
"uninstall", "-y", "--disable-pip-version-check", "-v", "pip",
|
||||
"setuptools",
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -261,7 +252,6 @@ class TestUninstall(EnsurepipMixin, unittest.TestCase):
|
|||
self.run_pip.assert_called_once_with(
|
||||
[
|
||||
"uninstall", "-y", "--disable-pip-version-check", "-vv", "pip",
|
||||
"setuptools",
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -272,7 +262,7 @@ class TestUninstall(EnsurepipMixin, unittest.TestCase):
|
|||
self.run_pip.assert_called_once_with(
|
||||
[
|
||||
"uninstall", "-y", "--disable-pip-version-check", "-vvv",
|
||||
"pip", "setuptools",
|
||||
"pip"
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -312,13 +302,13 @@ class TestBootstrappingMainFunction(EnsurepipMixin, unittest.TestCase):
|
|||
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 @@ class TestUninstallationMainFunction(EnsurepipMixin, unittest.TestCase):
|
|||
self.run_pip.assert_called_once_with(
|
||||
[
|
||||
"uninstall", "-y", "--disable-pip-version-check", "pip",
|
||||
"setuptools",
|
||||
]
|
||||
)
|
||||
|
||||
|
|
|
@ -227,7 +227,6 @@ class BasicTest(BaseTest):
|
|||
'install',
|
||||
'--upgrade',
|
||||
'pip',
|
||||
'setuptools'
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -745,7 +744,6 @@ class EnsurePipTest(BaseTest):
|
|||
# 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 sysconfig
|
|||
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 @@ import re
|
|||
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…
Reference in New Issue