Skip to content

Release 21.3.1 #10609

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Oct 22, 2021
Merged
1 change: 1 addition & 0 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Dongweiming <[email protected]> <[email protected]
Dustin Ingram <[email protected]> <[email protected]>
Endoh Takanao <[email protected]>
Erik M. Bray <[email protected]>
Ee Durbin <[email protected]>
Gabriel de Perthuis <[email protected]>
Hsiaoming Yang <[email protected]>
Hugo van Kemenade <[email protected]> Hugo <[email protected]>
Expand Down
3 changes: 1 addition & 2 deletions AUTHORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ DrFeathers
Dustin Ingram
Dwayne Bailey
Ed Morley
Ee Durbin
Eitan Adler
ekristina
elainechan
Expand All @@ -222,8 +223,6 @@ Eric Hanchrow
Eric Hopper
Erik M. Bray
Erik Rose
Ernest W Durbin III
Ernest W. Durbin III
Erwin Janssen
Eugene Vereshchagin
everdimension
Expand Down
25 changes: 25 additions & 0 deletions NEWS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,31 @@

.. towncrier release notes start

21.3.1 (2021-10-22)
===================


Bug Fixes
---------


- Always refuse installing or building projects that have no ``pyproject.toml`` nor
``setup.py``. (`#10531 <https://github.com/pypa/pip/issues/10531>`_)
- Tweak running-as-root detection, to check ``os.getuid`` if it exists, on Unix-y and non-Linux/non-MacOS machines. (`#10565 <https://github.com/pypa/pip/issues/10565>`_)
- When installing projects with a ``pyproject.toml`` in editable mode, and the build
backend does not support :pep:`660`, prepare metadata using
``prepare_metadata_for_build_wheel`` instead of ``setup.py egg_info``. Also, refuse
installing projects that only have a ``setup.cfg`` and no ``setup.py`` nor
``pyproject.toml``. These restore the pre-21.3 behaviour. (`#10573 <https://github.com/pypa/pip/issues/10573>`_)
- Restore compatibility of where configuration files are loaded from on MacOS (back to ``Library/Application Support/pip``, instead of ``Preferences/pip``). (`#10585 <https://github.com/pypa/pip/issues/10585>`_)

Vendored Libraries
------------------


- Upgrade pep517 to 0.12.0


21.3 (2021-10-11)
=================

Expand Down
2 changes: 1 addition & 1 deletion docs/html/news.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ Changelog
Major and minor releases of pip also include changes listed within
prior beta releases.

.. towncrier-draft-entries:: |release|, unreleased as on
.. towncrier-draft-entries:: Not yet released

.. pip-news-include:: ../../NEWS.rst
9 changes: 3 additions & 6 deletions docs/html/reference/build-system/setup-py.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ depending on the package), the generated wheel is added to pip's wheel cache
and will be used for this installation. The built wheel is cached locally
by pip to avoid repeated identical builds.

If this wheel generation fails, pip will attempt a direct installation instead.
If this wheel generation fails, pip runs `setup.py clean` to clean up any build
artifacts that may have been generated. After that, pip will attempt a direct
installation.

### Direct Installation

Expand All @@ -70,11 +72,6 @@ For installing packages in "editable" mode
`setup.py develop`, which will use setuptools' mechanisms to perform an
editable/development installation.

### Cleanup

After attempting installation, pip may run `setup.py clean` to clean up build
artifacts from that setuptools has generated.

## Setuptools Injection

To support projects that directly use `distutils`, pip injects `setuptools` into
Expand Down
7 changes: 3 additions & 4 deletions docs/html/topics/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,10 @@ complexity for backwards compatibility reasons.
```{tab} Unix

Global
: {file}`/etc/pip.conf`
: In a "pip" subdirectory of any of the paths set in the environment variable
`XDG_CONFIG_DIRS` (if it exists), for example {file}`/etc/xdg/pip/pip.conf`.

Alternatively, it may be in a "pip" subdirectory of any of the paths set
in the environment variable `XDG_CONFIG_DIRS` (if it exists), for
example {file}`/etc/xdg/pip/pip.conf`.
This will be followed by loading {file}`/etc/pip.conf`.

User
: {file}`$HOME/.config/pip/pip.conf`, which respects the `XDG_CONFIG_HOME` environment variable.
Expand Down
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
sphinx ~= 4.1.0
sphinx ~= 4.2
towncrier
furo
myst_parser
Expand Down
2 changes: 1 addition & 1 deletion noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def lint(session: nox.Session) -> None:

@nox.session
def vendoring(session: nox.Session) -> None:
session.install("vendoring~=1.0.0")
session.install("vendoring~=1.2.0")

if "--upgrade" not in session.posargs:
session.run("vendoring", "sync", "-v")
Expand Down
10 changes: 9 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@ requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

[tool.towncrier]
# For finding the __version__
package = "pip"
package_dir = "src"
# For writing into the correct file
filename = "NEWS.rst"
# For finding the news fragments
directory = "news/"
title_format = "{version} ({project_date})"

# For rendering properly for this project
issue_format = "`#{issue} <https://github.com/pypa/pip/issues/{issue}>`_"
template = "tools/news/template.rst"

# Grouping of entries, within our changelog
type = [
{ name = "Process", directory = "process", showcontent = true },
{ name = "Deprecations and Removals", directory = "removal", showcontent = true },
Expand Down Expand Up @@ -54,4 +60,6 @@ distro = []
setuptools = "pkg_resources"

[tool.vendoring.license.fallback-urls]
CacheControl = "https://raw.githubusercontent.com/ionrock/cachecontrol/v0.12.6/LICENSE.txt"
distlib = "https://bitbucket.org/pypa/distlib/raw/master/LICENSE.txt"
webencodings = "https://github.com/SimonSapin/python-webencodings/raw/master/LICENSE"
2 changes: 1 addition & 1 deletion src/pip/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import List, Optional

__version__ = "21.3"
__version__ = "22.0.dev0"


def main(args: Optional[List[str]] = None) -> int:
Expand Down
7 changes: 4 additions & 3 deletions src/pip/_internal/cli/req_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,10 @@ def warn_if_run_as_root() -> None:
# checks: https://mypy.readthedocs.io/en/stable/common_issues.html
if sys.platform == "win32" or sys.platform == "cygwin":
return
if sys.platform == "darwin" or sys.platform == "linux":
if os.getuid() != 0:
return

if os.getuid() != 0:
return

logger.warning(
"Running pip as the 'root' user can result in broken permissions and "
"conflicting behaviour with the system package manager. "
Expand Down
40 changes: 26 additions & 14 deletions src/pip/_internal/distributions/sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,22 @@ def prepare_distribution_metadata(
# Set up the build isolation, if this requirement should be isolated
should_isolate = self.req.use_pep517 and build_isolation
if should_isolate:
self._setup_isolation(finder)
# Setup an isolated environment and install the build backend static
# requirements in it.
self._prepare_build_backend(finder)
# Check that if the requirement is editable, it either supports PEP 660 or
# has a setup.py or a setup.cfg. This cannot be done earlier because we need
# to setup the build backend to verify it supports build_editable, nor can
# it be done later, because we want to avoid installing build requirements
# needlessly. Doing it here also works around setuptools generating
# UNKNOWN.egg-info when running get_requires_for_build_wheel on a directory
# without setup.py nor setup.cfg.
self.req.isolated_editable_sanity_check()
# Install the dynamic build requirements.
self._install_build_reqs(finder)

self.req.prepare_metadata()

def _setup_isolation(self, finder: PackageFinder) -> None:
self._prepare_build_backend(finder)
# Install any extra build dependencies that the backend requests.
# This must be done in a second pass, as the pyproject.toml
# dependencies must be installed before we can call the backend.
if self.req.editable and self.req.permit_editable_wheels:
build_reqs = self._get_build_requires_editable()
else:
build_reqs = self._get_build_requires_wheel()
self._install_build_reqs(finder, build_reqs)

def _prepare_build_backend(self, finder: PackageFinder) -> None:
# Isolate in a BuildEnvironment and install the build-time
# requirements.
Expand Down Expand Up @@ -91,8 +92,19 @@ def _get_build_requires_editable(self) -> Iterable[str]:
with backend.subprocess_runner(runner):
return backend.get_requires_for_build_editable()

def _install_build_reqs(self, finder: PackageFinder, reqs: Iterable[str]) -> None:
conflicting, missing = self.req.build_env.check_requirements(reqs)
def _install_build_reqs(self, finder: PackageFinder) -> None:
# Install any extra build dependencies that the backend requests.
# This must be done in a second pass, as the pyproject.toml
# dependencies must be installed before we can call the backend.
if (
self.req.editable
and self.req.permit_editable_wheels
and self.req.supports_pyproject_editable()
):
build_reqs = self._get_build_requires_editable()
else:
build_reqs = self._get_build_requires_wheel()
conflicting, missing = self.req.build_env.check_requirements(build_reqs)
if conflicting:
self._raise_conflicts("the backend dependencies", conflicting)
self.req.build_env.install_requirements(
Expand Down
4 changes: 1 addition & 3 deletions src/pip/_internal/operations/build/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ def generate_metadata(build_env: BuildEnvironment, backend: Pep517HookCaller) ->
# Note that Pep517HookCaller implements a fallback for
# prepare_metadata_for_build_wheel, so we don't have to
# consider the possibility that this hook doesn't exist.
runner = runner_with_spinner_message(
"Preparing wheel metadata (pyproject.toml)"
)
runner = runner_with_spinner_message("Preparing metadata (pyproject.toml)")
with backend.subprocess_runner(runner):
distinfo_dir = backend.prepare_metadata_for_build_wheel(metadata_dir)

Expand Down
1 change: 1 addition & 0 deletions src/pip/_internal/operations/prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ def _ensure_link_req_src_dir(
# installation.
# FIXME: this won't upgrade when there's an existing
# package unpacked in `req.source_dir`
# TODO: this check is now probably dead code
if is_installable_dir(req.source_dir):
raise PreviousBuildDirError(
"pip can't proceed with requirements '{}' due to a"
Expand Down
6 changes: 6 additions & 0 deletions src/pip/_internal/pyproject.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ def load_pyproject_toml(
has_pyproject = os.path.isfile(pyproject_toml)
has_setup = os.path.isfile(setup_py)

if not has_pyproject and not has_setup:
raise InstallationError(
f"{req_name} does not appear to be a Python project: "
f"neither 'setup.py' nor 'pyproject.toml' found."
)

if has_pyproject:
with open(pyproject_toml, encoding="utf-8") as f:
pp_toml = tomli.load(f)
Expand Down
2 changes: 2 additions & 0 deletions src/pip/_internal/req/constructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ def _get_url_from_path(path: str, name: str) -> Optional[str]:
if _looks_like_path(name) and os.path.isdir(path):
if is_installable_dir(path):
return path_to_url(path)
# TODO: The is_installable_dir test here might not be necessary
# now that it is done in load_pyproject_toml too.
raise InstallationError(
f"Directory {name!r} is not installable. Neither 'setup.py' "
"nor 'pyproject.toml' found."
Expand Down
Loading