Skip to content

Commit

Permalink
Stop installing setuptools and wheel on Python 3.12+
Browse files Browse the repository at this point in the history
Currently `get-pip.py` installs not only pip, but also setuptools and
wheel by default, unless the `--no-setuptools` / `--no-wheel` (or
`PIP_NO_SETUPTOOLS` / `PIP_NO_WHEEL` env vars) are used.

This has historically been necessary, however, modern versions of pip
will now fallback to `pyproject.toml` (PEP 517: [1]) based builds (which
will default to a setuptools backend, and thus automatically install
setuptools and wheel in the isolated build environment) if either
setuptools is not installed (as of pip 22.1: [2]), or if wheel is not
installed (as of pip 23.1: [3]).

In addition, as of Python 3.12, the stdlib's `ensurepip` and `venv`
modules no longer install setuptools, and only install pip ([4]).

As such, it is now time for `get-pip.py` to stop installing setuptools
and wheel by default on Python 3.12+, in order to:
- Act as another small step towards `pyproject.toml` / PEP 517
  based builds eventually becoming the pip default.
- Improve parity with the behaviour of `ensurepip` / `venv` on
  Python 3.12+.
- Allow `get-pip.py` to focus on its primary responsibility:
  bootstrapping Pip.

Closes pypa#200.

[1]: https://peps.python.org/pep-0517/
[2]: pypa/pip#10717
[3]: pypa/pip#11871
[4]: python/cpython#101039
  • Loading branch information
edmorley committed Jul 29, 2024
1 parent ac92537 commit def4aec
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 30 deletions.
28 changes: 18 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# get-pip.py

`get-pip.py` is a bootstrapping script that enables users to install pip,
setuptools, and wheel in Python environments that don't already have them. You
`get-pip.py` is a bootstrapping script that enables users to install pip
in Python environments that don't already have it installed. You
should not directly reference the files located in this repository and instead
use the versions located at <https://bootstrap.pypa.io/>.

Expand All @@ -12,26 +12,34 @@ $ curl -sSL https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python get-pip.py
```

Upon execution, `get-pip.py` will install `pip`, `setuptools` and `wheel` in
the current Python environment.
Upon execution, `get-pip.py` will install the latest version of `pip` into the
current Python environment. When using Python 3.11 or older, by default the
packages `setuptools` and `wheel` will also be installed if an existing version
of them was not found.

It is possible to provide additional arguments to the underlying script. These
are passed through to the underlying `pip install` command, and can thus be
used to constraint the versions of the packages, or to pass other pip options
such as `--no-index`.
used to constrain the versions of the packages, install additional packages,
or to pass other pip options such as `--no-index`.

```console
$ python get-pip.py "pip < 21.0" "setuptools < 50.0" "wheel < 1.0"
# Constrain the pip version
$ python get-pip.py "pip < 21.0"

# Force the installation of `setuptools` and `wheel` on newer Python versions.
$ python get-pip.py setuptools wheel

# Install packages from a local directory instead of PyPI.
$ python get-pip.py --no-index --find-links=/local/copies
```

### get-pip.py options

This script also has it's own options, which control which packages it will
This script also has its own options, which control which packages it will
install.

- `--no-setuptools`: do not attempt to install `setuptools`.
- `--no-wheel`: do not attempt to install `wheel`.
- `--no-setuptools`: Do not attempt to install `setuptools`. This is a no-op on Python 3.12+.
- `--no-wheel`: Do not attempt to install `wheel`. This is a no-op on Python 3.12+.

## Development

Expand Down
12 changes: 7 additions & 5 deletions public/3.6/get-pip.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,24 @@

def include_setuptools(args):
"""
Install setuptools only if absent and not excluded.
Install setuptools only if absent, not excluded and when using Python <3.12.
"""
cli = not args.no_setuptools
env = not os.environ.get("PIP_NO_SETUPTOOLS")
absent = not importlib.util.find_spec("setuptools")
return cli and env and absent
python_lt_3_12 = this_python < (3, 12)
return cli and env and absent and python_lt_3_12


def include_wheel(args):
"""
Install wheel only if absent and not excluded.
Install wheel only if absent, not excluded and when using Python <3.12.
"""
cli = not args.no_wheel
env = not os.environ.get("PIP_NO_WHEEL")
absent = not importlib.util.find_spec("wheel")
return cli and env and absent
python_lt_3_12 = this_python < (3, 12)
return cli and env and absent and python_lt_3_12


def determine_pip_install_arguments():
Expand Down Expand Up @@ -111,7 +113,7 @@ def bootstrap(tmpdir):
monkeypatch_for_cert(tmpdir)

# Execute the included pip and use it to install the latest pip and
# setuptools from PyPI
# any user-requested packages from PyPI.
from pip._internal.cli.main import main as pip_entry_point
args = determine_pip_install_arguments()
sys.exit(pip_entry_point(args))
Expand Down
12 changes: 7 additions & 5 deletions public/3.7/get-pip.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,24 @@

def include_setuptools(args):
"""
Install setuptools only if absent and not excluded.
Install setuptools only if absent, not excluded and when using Python <3.12.
"""
cli = not args.no_setuptools
env = not os.environ.get("PIP_NO_SETUPTOOLS")
absent = not importlib.util.find_spec("setuptools")
return cli and env and absent
python_lt_3_12 = this_python < (3, 12)
return cli and env and absent and python_lt_3_12


def include_wheel(args):
"""
Install wheel only if absent and not excluded.
Install wheel only if absent, not excluded and when using Python <3.12.
"""
cli = not args.no_wheel
env = not os.environ.get("PIP_NO_WHEEL")
absent = not importlib.util.find_spec("wheel")
return cli and env and absent
python_lt_3_12 = this_python < (3, 12)
return cli and env and absent and python_lt_3_12


def determine_pip_install_arguments():
Expand Down Expand Up @@ -111,7 +113,7 @@ def bootstrap(tmpdir):
monkeypatch_for_cert(tmpdir)

# Execute the included pip and use it to install the latest pip and
# setuptools from PyPI
# any user-requested packages from PyPI.
from pip._internal.cli.main import main as pip_entry_point
args = determine_pip_install_arguments()
sys.exit(pip_entry_point(args))
Expand Down
12 changes: 7 additions & 5 deletions public/get-pip.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,24 @@

def include_setuptools(args):
"""
Install setuptools only if absent and not excluded.
Install setuptools only if absent, not excluded and when using Python <3.12.
"""
cli = not args.no_setuptools
env = not os.environ.get("PIP_NO_SETUPTOOLS")
absent = not importlib.util.find_spec("setuptools")
return cli and env and absent
python_lt_3_12 = this_python < (3, 12)
return cli and env and absent and python_lt_3_12


def include_wheel(args):
"""
Install wheel only if absent and not excluded.
Install wheel only if absent, not excluded and when using Python <3.12.
"""
cli = not args.no_wheel
env = not os.environ.get("PIP_NO_WHEEL")
absent = not importlib.util.find_spec("wheel")
return cli and env and absent
python_lt_3_12 = this_python < (3, 12)
return cli and env and absent and python_lt_3_12


def determine_pip_install_arguments():
Expand Down Expand Up @@ -111,7 +113,7 @@ def bootstrap(tmpdir):
monkeypatch_for_cert(tmpdir)

# Execute the included pip and use it to install the latest pip and
# setuptools from PyPI
# any user-requested packages from PyPI.
from pip._internal.cli.main import main as pip_entry_point
args = determine_pip_install_arguments()
sys.exit(pip_entry_point(args))
Expand Down
12 changes: 7 additions & 5 deletions templates/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,24 @@

def include_setuptools(args):
"""
Install setuptools only if absent and not excluded.
Install setuptools only if absent, not excluded and when using Python <3.12.
"""
cli = not args.no_setuptools
env = not os.environ.get("PIP_NO_SETUPTOOLS")
absent = not importlib.util.find_spec("setuptools")
return cli and env and absent
python_lt_3_12 = this_python < (3, 12)
return cli and env and absent and python_lt_3_12


def include_wheel(args):
"""
Install wheel only if absent and not excluded.
Install wheel only if absent, not excluded and when using Python <3.12.
"""
cli = not args.no_wheel
env = not os.environ.get("PIP_NO_WHEEL")
absent = not importlib.util.find_spec("wheel")
return cli and env and absent
python_lt_3_12 = this_python < (3, 12)
return cli and env and absent and python_lt_3_12


def determine_pip_install_arguments():
Expand Down Expand Up @@ -111,7 +113,7 @@ def bootstrap(tmpdir):
monkeypatch_for_cert(tmpdir)

# Execute the included pip and use it to install the latest pip and
# setuptools from PyPI
# any user-requested packages from PyPI.
from pip._internal.cli.main import main as pip_entry_point
args = determine_pip_install_arguments()
sys.exit(pip_entry_point(args))
Expand Down

0 comments on commit def4aec

Please sign in to comment.