diff --git a/docs/html/cli/pip.rst b/docs/html/cli/pip.rst
index 88ef33e1163..f8ac787b7af 100644
--- a/docs/html/cli/pip.rst
+++ b/docs/html/cli/pip.rst
@@ -77,7 +77,7 @@ when decision is needed.
.. _`2-build-system-interface`:
.. rubric:: Build System Interface
-This is now covered in :doc:`../reference/build-system/index`.
+This is now covered in :doc:`../reference/build-system`.
.. _`General Options`:
diff --git a/docs/html/cli/pip_install.rst b/docs/html/cli/pip_install.rst
index 1e0decafddc..e65c001fed0 100644
--- a/docs/html/cli/pip_install.rst
+++ b/docs/html/cli/pip_install.rst
@@ -255,7 +255,7 @@ This is now covered in :doc:`../topics/local-project-installs`.
.. _`0-build-system-interface`:
.. rubric:: Build System Interface
-This is now covered in :doc:`../reference/build-system/index`.
+This is now covered in :doc:`../reference/build-system`.
.. _`pip install Options`:
diff --git a/docs/html/cli/pip_wheel.rst b/docs/html/cli/pip_wheel.rst
index ba749529c0c..50b656c4334 100644
--- a/docs/html/cli/pip_wheel.rst
+++ b/docs/html/cli/pip_wheel.rst
@@ -28,7 +28,7 @@ Description
.. _`1-build-system-interface`:
.. rubric:: Build System Interface
-This is now covered in :doc:`../reference/build-system/index`.
+This is now covered in :doc:`../reference/build-system`.
Differences to ``build``
------------------------
diff --git a/docs/html/reference/build-system/pyproject-toml.md b/docs/html/reference/build-system.md
similarity index 87%
rename from docs/html/reference/build-system/pyproject-toml.md
rename to docs/html/reference/build-system.md
index 778584de397..28f7123dd31 100644
--- a/docs/html/reference/build-system/pyproject-toml.md
+++ b/docs/html/reference/build-system.md
@@ -1,9 +1,28 @@
-# `pyproject.toml`
+(build-interface)=
```{versionadded} 10.0
```
+```{versionchanged} 23.1
+The legacy interface where pip could invoke `setup.py install`
+in some circumstances was removed,
+in favor of the fallback behavior described below.
+```
+
+```{versionchanged} 25.3
+The legacy interface where pip could invoke `setup.py build_wheel` or
+`setup.py develop` in some circumstances was removed,
+in favor of the fallback behavior described below..
+```
+
+# Build System Interface
+
+When dealing with installable source distributions of a package, pip does not
+directly handle the build process for the package. This responsibility is
+delegated to "build backends" -- also known as "build systems". This means
+that pip needs an interface, to interact with these build backends.
+
Modern Python packages can contain a `pyproject.toml` file, first introduced in
{pep}`518` and later expanded in {pep}`517`, {pep}`621` and {pep}`660`.
This file contains build system requirements and information, which are used by
@@ -96,16 +115,6 @@ For performing editable installs, pip will use {pep}`660`
`build_wheel_for_editable` hook that has to be provided by the build backend.
The wheels generated using this mechanism are not cached.
-```{admonition} Compatibility fallback
-If this hook is missing on the build backend _and_ there's a `setup.py` file
-in the project, pip will fallback to the legacy setup.py-based editable
-installation.
-
-This is considered a stopgap solution until setuptools adds support for
-{pep}`660`, at which point this functionality will be removed; following pip's
-regular {ref}`deprecation policy `.
-```
-
### Backend Configuration
Build backends have the ability to accept configuration settings, which can
@@ -125,8 +134,7 @@ files.
## Build output
It is the responsibility of the build backend to ensure that the output is
-in the correct encoding, as described in {pep}`517`. This likely involves
-dealing with [the same challenges as pip has for legacy builds](build-output).
+in the correct encoding, as described in {pep}`517`.
## Fallback Behaviour
@@ -138,7 +146,8 @@ https://setuptools.pypa.io/en/stable/userguide/quickstart.html#basic-use).
```
If a project does not have a `pyproject.toml` file containing a `build-system`
-section, it will be assumed to have the following backend settings:
+section, and contains a `setup.py` it will be assumed to have the following
+backend settings:
```toml
[build-system]
diff --git a/docs/html/reference/build-system/index.md b/docs/html/reference/build-system/index.md
deleted file mode 100644
index ed43fec3778..00000000000
--- a/docs/html/reference/build-system/index.md
+++ /dev/null
@@ -1,127 +0,0 @@
-(build-interface)=
-
-# Build System Interface
-
-When dealing with installable source distributions of a package, pip does not
-directly handle the build process for the package. This responsibility is
-delegated to "build backends" -- also known as "build systems". This means
-that pip needs an interface, to interact with these build backends.
-
-There are two main interfaces that pip uses for these interactions:
-
-```{toctree}
-:hidden:
-
-pyproject-toml
-setup-py
-```
-
-
-[`pyproject.toml` based](pyproject-toml)
-: Standards-backed interface, that has explicit declaration and management of
- build dependencies.
-
-[`setup.py` based](setup-py)
-: Legacy interface, that we're working to migrate users away from. Has no good
- mechanisms to declare build dependencies.
-
-
-Details on the individual interfaces can be found on their dedicated pages,
-linked above. This document covers the nuances around which build system
-interface pip will use for a project, as well as details that apply to all
-the build system interfaces that pip may use.
-
-## Determining which build system interface is used
-
-Currently, pip uses the `pyproject.toml` based build system interface, if a
-`pyproject.toml` file exists. If not, the legacy build system interface is used.
-The intention is to switch to using the `pyproject.toml` build system interface
-unconditionally and to drop support for the legacy build system interface at
-some point in the future.
-
-When performing a build, pip will mention which build system interface it is
-using. Typically, this will take the form of a message like:
-
-```none
-Building wheel for pip (pyproject.toml)... done
-```
-
-```none
-Building wheel for pip (setup.py)... done
-```
-
-The content in the brackets, refers to which build system interface is being
-used.
-
-```{versionchanged} 21.3
-The output uses "pyproject.toml" instead of "PEP 517" to refer to be
-`pyproject.toml` based build system interface.
-```
-
-## Controlling which build system interface is used
-
-The [`--use-pep517`](install_--use-pep517) flag (and corresponding environment
-variable: `PIP_USE_PEP517`) can be used to force all packages to build using
-the `pyproject.toml` based build system interface. There is no way to force
-the use of the legacy build system interface.
-
-(controlling-setup_requires)=
-
-## Controlling `setup_requires`
-
-```{hint}
-This is only relevant for projects that use setuptools as the build backend,
-and use the `setup_requires` keyword argument in their setup.py file.
-```
-
-The `setup_requires` argument in `setup.py` is used to specify build-time
-dependencies for a package. This has been superseded by the
-`build-system.requires` key in `pyproject.toml` files (per {pep}`518`).
-However, there are situations where you might encounter a package that uses
-`setup_requires` (eg: the package has not been updated to use the newer
-approach yet!).
-
-If you control the package, consider adding a `pyproject.toml` file to utilise
-the modern build system interface. That avoids invoking the problematic
-behaviour by deferring to pip for the installations.
-
-For the end users, the best solution for dealing with packages with
-`setup_requires` is to install the packages listed in `setup_requires`
-beforehand, using a prior `pip install` command. This is because there is no
-way to control how these dependencies are located by `easy_install`, or how
-setuptools will invoke `pip` using pip's command line options -- which makes it
-tricky to get things working appropriately.
-
-If you wish to ensure that `easy_install` invocations do not reach out to PyPI,
-you will need to configure its behaviour using a
-[`distutils` configuration file][distutils-config]. Here are some examples:
-
-- To have the dependency located at an alternate index with `easy_install`
-
- ```ini
- [easy_install]
- index_url = https://my.index-mirror.com
- ```
-
-- To have the dependency located from a local directory and not crawl PyPI, add this:
-
- ```ini
- [easy_install]
- allow_hosts = ''
- find_links = file:///path/to/local/archives/
- ```
-
-```{admonition} Historical context
-`setuptools < 52.0` will use `easy_install` to try to fulfill `setup_requires`
-dependencies, which can result in weird failures -- `easy_install` does not
-understand many of the modern Python packaging standards, and will usually
-attempt to install incompatible package versions or to build packages
-incorrectly. It also generates improper script wrappers, which don't do the
-right thing in many situations.
-
-Newer versions of `setuptools` will use `pip` for these installations, but have
-limited ability to pass through any command line arguments. This can also result
-in weird failures and subtly-incorrect behaviour.
-```
-
-[distutils-config]: https://docs.python.org/3/install/index.html#distutils-configuration-files
diff --git a/docs/html/reference/build-system/setup-py.md b/docs/html/reference/build-system/setup-py.md
deleted file mode 100644
index 0103a3a6a92..00000000000
--- a/docs/html/reference/build-system/setup-py.md
+++ /dev/null
@@ -1,124 +0,0 @@
-# `setup.py` (legacy)
-
-Prior to the introduction of pyproject.toml-based builds (in {pep}`517` and
-{pep}`518`), pip had only supported installing packages using `setup.py` files
-that were built using {pypi}`setuptools`.
-
-The interface documented here is retained currently solely for legacy purposes,
-until the migration to `pyproject.toml`-based builds can be completed.
-
-```{caution}
-The arguments and syntax of the various invocations of `setup.py` made by
-pip, are considered an implementation detail that is strongly coupled with
-{pypi}`setuptools`. This build system interface is not meant to be used by any
-other build backend, which should be based on the {doc}`pyproject-toml` build
-system interface instead.
-
-Further, projects should _not_ expect to rely on there being any form of
-backward compatibility guarantees around the `setup.py` interface.
-```
-
-## Build process
-
-The overall process for building a package is:
-
-- Generate the package's metadata.
-- Generate a wheel for the package.
-
-The wheel can then be used to perform an installation, if necessary.
-
-### Metadata Generation
-
-As a first step, `pip` needs to get metadata about a package (name, version,
-dependencies, and more). It collects this by calling `setup.py egg_info`.
-
-The `egg_info` command generates the metadata for the package, which pip can
-then consume and proceed to gather all the dependencies of the package. Once
-the dependency resolution process is complete, pip will proceed to the next
-stage of the build process for these packages.
-
-### Wheel Generation
-
-When provided with a {term}`pypug:source distribution (or "sdist")` for a
-package, pip will attempt to build a {term}`pypug:wheel`. Since wheel
-distributions can be [cached](wheel-caching), this can greatly speed up future
-installations for the package.
-
-This is done by calling `setup.py bdist_wheel` which requires the {pypi}`wheel`
-package to be installed.
-
-If this wheel generation is successful (this can include compiling C/C++ code,
-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 runs `setup.py clean` to clean up any build
-artifacts that may have been generated. After that, pip will attempt a direct
-installation.
-
-### Editable Installation
-
-For installing packages in "editable" mode
-({ref}`pip install --editable `), pip will invoke
-`setup.py develop`, which will use setuptools' mechanisms to perform an
-editable/development installation.
-
-## Setuptools Injection
-
-To support projects that directly use `distutils`, pip injects `setuptools` into
-`sys.modules` before invoking `setup.py`. This injection should be transparent
-to `distutils`-based projects.
-
-## Customising the build
-
-The `--global-option` and `--build-option` arguments to the `pip install`
-and `pip wheel` inject additional arguments into the `setup.py` command
-(`--build-option` is only available in `pip wheel`).
-
-```{attention}
-The use of `--global-option` and `--build-option` is highly setuptools
-specific, and is considered more an accident of the current implementation than
-a supported interface. It is documented here for completeness. These flags will
-not be supported, once this build system interface is dropped.
-```
-
-These arguments are included in the command as follows:
-
-```
-python setup.py BUILD COMMAND
-```
-
-The options are passed unmodified, and presently offer direct access to the
-distutils command line. For example:
-
-```{pip-cli}
-$ pip wheel --global-option bdist_ext --global-option -DFOO wheel
-```
-
-will result in pip invoking:
-
-```
-setup.py bdist_ext -DFOO bdist_wheel -d TARGET
-```
-
-This passes a preprocessor symbol to the extension build.
-
-(build-output)=
-
-## Build Output
-
-Any output produced by the build system will be read by pip (for display to the
-user if requested). In order to correctly read the build system output, pip
-requires that the output is written in a well-defined encoding, specifically
-the encoding the user has configured for text output (which can be obtained in
-Python using `locale.getpreferredencoding`). If the configured encoding is
-ASCII, pip assumes UTF-8 (to account for the behaviour of some Unix systems).
-
-Build systems should ensure that any tools they invoke (compilers, etc) produce
-output in the correct encoding. In practice - and in particular on Windows,
-where tools are inconsistent in their use of the "OEM" and "ANSI" codepages -
-this may not always be possible. pip will therefore attempt to recover cleanly
-if presented with incorrectly encoded build tool output, by translating
-unexpected byte sequences to Python-style hexadecimal escape sequences
-(`"\x80\xff"`, etc). However, it is still possible for output to be displayed
-using an incorrect encoding (mojibake).
diff --git a/docs/html/reference/index.md b/docs/html/reference/index.md
index 63ce1ca4dbf..788e6f2b7cd 100644
--- a/docs/html/reference/index.md
+++ b/docs/html/reference/index.md
@@ -6,7 +6,7 @@ interoperability standards that pip utilises/implements.
```{toctree}
:titlesonly:
-build-system/index
+build-system
requirement-specifiers
requirements-file-format
installation-report
diff --git a/docs/html/reference/requirements-file-format.md b/docs/html/reference/requirements-file-format.md
index 020a6e51b5b..51e43d76b8b 100644
--- a/docs/html/reference/requirements-file-format.md
+++ b/docs/html/reference/requirements-file-format.md
@@ -109,7 +109,6 @@ and two {ref}`--find-links ` locations:
The options which can be applied to individual requirements are:
-- {ref}`--global-option `
- {ref}`--config-settings `
- `--hash` (for {ref}`Hash-checking mode`)
@@ -150,30 +149,3 @@ You can now store sensitive data (tokens, keys, etc.) in environment variables
and only specify the variable name for your requirements, letting pip lookup
the value at runtime. This approach aligns with the commonly used
[12-factor configuration pattern](https://12factor.net/config).
-
-
-## Influencing the build system
-
-```{danger}
-This disables the use of wheels (cached or otherwise). This could mean that builds will be slower, less deterministic, less reliable and may not behave correctly upon installation.
-
-This mechanism is only preserved for backwards compatibility and should be considered deprecated. A future release of pip may drop these options.
-```
-
-The `--global-option` option is used to pass options to `setup.py`.
-
-```{attention}
-These options are highly coupled with how pip invokes setuptools using the {doc}`../reference/build-system/setup-py` build system interface. It is not compatible with newer {doc}`../reference/build-system/pyproject-toml` build system interface.
-
-This is will not work with other build-backends or newer setup.cfg-only projects.
-```
-
-If you have a declaration like:
-
- FooProject >= 1.2 --global-option="--no-user-cfg"
-
-The above translates roughly into running FooProject's `setup.py` script as:
-
- python setup.py --no-user-cfg install
-
-Note that the only way of giving more than one option to `setup.py` is through multiple `--global-option` options.
diff --git a/docs/html/topics/local-project-installs.md b/docs/html/topics/local-project-installs.md
index bd70dbe2f78..9e83c96ef2d 100644
--- a/docs/html/topics/local-project-installs.md
+++ b/docs/html/topics/local-project-installs.md
@@ -37,17 +37,6 @@ With an editable install, you only need to perform a re-installation if you chan
It is possible to see behaviour differences between regular installs vs editable installs. These differences depend on the build-backend, and you should check the build-backend documentation for the details. In case you distribute the project as a "distribution package", users will see the behaviour of regular installs -- thus, it is important to ensure that regular installs work correctly.
```
-```{note}
-This is functionally the same as [setuptools' develop mode], and that's precisely the mechanism used for setuptools-based projects.
-
-There are two advantages over using `setup.py develop` directly:
-
-- This works with non-setuptools build-backends as well.
-- The ".egg-info" directory is created relative to the project path, when using pip. This is generally a better location than setuptools, which dumps it in the current working directory.
-```
-
-[setuptools' develop mode]: https://setuptools.readthedocs.io/en/latest/userguide/development_mode.html
-
## Build artifacts
```{versionchanged} 21.3
diff --git a/docs/html/topics/repeatable-installs.md b/docs/html/topics/repeatable-installs.md
index d3f06679587..66e96434bf6 100644
--- a/docs/html/topics/repeatable-installs.md
+++ b/docs/html/topics/repeatable-installs.md
@@ -90,10 +90,3 @@ across machines.
Hash-checking mode can also be used along with this method (since this uses a
requirements file as well), to ensure that future archives are built with
identical packages.
-
-```{warning}
-Beware of the `setup_requires` keyword arg in {file}`setup.py`. The (rare)
-packages that use it will cause those dependencies to be downloaded by
-setuptools directly, skipping pip's protections. If you need to use such a
-package, see {ref}`Controlling setup_requires `.
-```
diff --git a/docs/html/topics/secure-installs.md b/docs/html/topics/secure-installs.md
index bda3c4485b0..9b2f43e4b9a 100644
--- a/docs/html/topics/secure-installs.md
+++ b/docs/html/topics/secure-installs.md
@@ -77,10 +77,6 @@ Other hash algorithms that have guaranteed support from `hashlib` are also suppo
Hash-checking mode also works with {ref}`pip download` and {ref}`pip wheel`. See {doc}`../topics/repeatable-installs` for a comparison of hash-checking mode with other repeatability strategies.
-```{warning}
-Beware of the `setup_requires` keyword arg in {file}`setup.py`. The (rare) packages that use it will cause those dependencies to be downloaded by setuptools directly, skipping pip's hash-checking. If you need to use such a package, see {ref}`controlling setup_requires `.
-```
-
## Do not use setuptools directly
Be careful not to nullify all your security work by installing your actual project by using setuptools' deprecated interfaces directly: for example, by calling `python setup.py install`, `python setup.py develop`, or `easy_install`.
diff --git a/docs/html/user_guide.rst b/docs/html/user_guide.rst
index 30c514f7e59..3abbbd3ff21 100644
--- a/docs/html/user_guide.rst
+++ b/docs/html/user_guide.rst
@@ -191,8 +191,7 @@ In practice, there are 4 common uses of Requirements files:
It's important to be clear that pip determines package dependencies using
-`install_requires metadata
-`_,
+the project metadata (typically in ``pyproject.toml`` or ``setup.py``),
not by discovering ``requirements.txt`` files embedded in projects.
See also:
@@ -445,10 +444,6 @@ name:
For the cases where wheels are not available, pip offers :ref:`pip wheel` as a
convenience, to build wheels for all your requirements and dependencies.
-:ref:`pip wheel` requires the `wheel package
-`_ to be installed, which provides the
-"bdist_wheel" setuptools extension that it uses.
-
To build wheels for your requirements and all their dependencies to a local
directory:
@@ -1003,7 +998,7 @@ of ability. Some examples that you could consider include:
* ``packaging`` - Utilities to work with standard package metadata (versions,
requirements, etc.)
-* ``setuptools`` (specifically ``pkg_resources``) - Functions for querying what
+* ``importlib.metadata`` in the Python stdlib - Functions for querying what
packages the user has installed on their system.
* ``distlib`` - Packaging and distribution utilities (including functions for
diff --git a/news/11457.removal.rst b/news/11457.removal.rst
new file mode 100644
index 00000000000..eb579147eeb
--- /dev/null
+++ b/news/11457.removal.rst
@@ -0,0 +1,2 @@
+Remove support for the legacy setup.py develop editable method in setuptools
+editable installs; setuptools >= 64 is now required.
diff --git a/news/11859.removal.rst b/news/11859.removal.rst
new file mode 100644
index 00000000000..fa56c8d05f6
--- /dev/null
+++ b/news/11859.removal.rst
@@ -0,0 +1,2 @@
+Remove the deprecated ``--global-option`` and ``--build-option``.
+``--config-setting`` is now the only way to pass options to the build backend.
diff --git a/news/6334.removal.rst b/news/6334.removal.rst
new file mode 100644
index 00000000000..791846540b2
--- /dev/null
+++ b/news/6334.removal.rst
@@ -0,0 +1,2 @@
+Remove support for the deprecated ``setup.py bdist_wheel`` mechanism. Consequently,
+``--use-pep517`` is now always on, and ``--no-use-pep517`` has been removed.
diff --git a/src/pip/_internal/cli/cmdoptions.py b/src/pip/_internal/cli/cmdoptions.py
index b22d85da4ec..a4737757b23 100644
--- a/src/pip/_internal/cli/cmdoptions.py
+++ b/src/pip/_internal/cli/cmdoptions.py
@@ -11,7 +11,6 @@
# mypy: strict-optional=False
from __future__ import annotations
-import importlib.util
import logging
import os
import pathlib
@@ -184,8 +183,7 @@ class PipOption(Option):
action="store_true",
default=False,
help=(
- "Allow pip to only run in a virtual environment; "
- "exit with an error otherwise."
+ "Allow pip to only run in a virtual environment; exit with an error otherwise."
),
)
@@ -851,62 +849,16 @@ def _handle_dependency_group(
dest="check_build_deps",
action="store_true",
default=False,
- help="Check the build dependencies when PEP517 is used.",
+ help="Check the build dependencies.",
)
-def _handle_no_use_pep517(
- option: Option, opt: str, value: str, parser: OptionParser
-) -> None:
- """
- Process a value provided for the --no-use-pep517 option.
-
- This is an optparse.Option callback for the no_use_pep517 option.
- """
- # Since --no-use-pep517 doesn't accept arguments, the value argument
- # will be None if --no-use-pep517 is passed via the command-line.
- # However, the value can be non-None if the option is triggered e.g.
- # by an environment variable, for example "PIP_NO_USE_PEP517=true".
- if value is not None:
- msg = """A value was passed for --no-use-pep517,
- probably using either the PIP_NO_USE_PEP517 environment variable
- or the "no-use-pep517" config file option. Use an appropriate value
- of the PIP_USE_PEP517 environment variable or the "use-pep517"
- config file option instead.
- """
- raise_option_error(parser, option=option, msg=msg)
-
- # If user doesn't wish to use pep517, we check if setuptools is installed
- # and raise error if it is not.
- packages = ("setuptools",)
- if not all(importlib.util.find_spec(package) for package in packages):
- msg = (
- f"It is not possible to use --no-use-pep517 "
- f"without {' and '.join(packages)} installed."
- )
- raise_option_error(parser, option=option, msg=msg)
-
- # Otherwise, --no-use-pep517 was passed via the command-line.
- parser.values.use_pep517 = False
-
-
use_pep517: Any = partial(
Option,
"--use-pep517",
dest="use_pep517",
action="store_true",
- default=None,
- help="Use PEP 517 for building source distributions "
- "(use --no-use-pep517 to force legacy behaviour).",
-)
-
-no_use_pep517: Any = partial(
- Option,
- "--no-use-pep517",
- dest="use_pep517",
- action="callback",
- callback=_handle_no_use_pep517,
- default=None,
+ default=True,
help=SUPPRESS_HELP,
)
@@ -939,30 +891,11 @@ def _handle_config_settings(
action="callback",
callback=_handle_config_settings,
metavar="settings",
- help="Configuration settings to be passed to the PEP 517 build backend. "
+ help="Configuration settings to be passed to the build backend. "
"Settings take the form KEY=VALUE. Use multiple --config-settings options "
"to pass multiple keys to the backend.",
)
-build_options: Callable[..., Option] = partial(
- Option,
- "--build-option",
- dest="build_options",
- metavar="options",
- action="append",
- help="Extra arguments to be supplied to 'setup.py bdist_wheel'.",
-)
-
-global_options: Callable[..., Option] = partial(
- Option,
- "--global-option",
- dest="global_options",
- action="append",
- metavar="options",
- help="Extra global options to be supplied to the setup.py "
- "call before the install or bdist_wheel command.",
-)
-
no_clean: Callable[..., Option] = partial(
Option,
"--no-clean",
diff --git a/src/pip/_internal/cli/req_command.py b/src/pip/_internal/cli/req_command.py
index c281346b35d..f6d7f81e82e 100644
--- a/src/pip/_internal/cli/req_command.py
+++ b/src/pip/_internal/cli/req_command.py
@@ -187,7 +187,6 @@ def make_resolver(
ignore_requires_python: bool = False,
force_reinstall: bool = False,
upgrade_strategy: str = "to-satisfy-only",
- use_pep517: bool | None = None,
py_version_info: tuple[int, ...] | None = None,
) -> BaseResolver:
"""
@@ -196,7 +195,6 @@ def make_resolver(
make_install_req = partial(
install_req_from_req_string,
isolated=options.isolated_mode,
- use_pep517=use_pep517,
)
resolver_variant = cls.determine_resolver_variant(options)
# The long import name and duplicated invocation is needed to convince
@@ -267,7 +265,6 @@ def get_requirements(
req,
comes_from=None,
isolated=options.isolated_mode,
- use_pep517=options.use_pep517,
user_supplied=True,
config_settings=getattr(options, "config_settings", None),
)
@@ -278,7 +275,6 @@ def get_requirements(
req_to_add = install_req_from_req_string(
req,
isolated=options.isolated_mode,
- use_pep517=options.use_pep517,
user_supplied=True,
)
requirements.append(req_to_add)
@@ -288,7 +284,6 @@ def get_requirements(
req,
user_supplied=True,
isolated=options.isolated_mode,
- use_pep517=options.use_pep517,
config_settings=getattr(options, "config_settings", None),
)
requirements.append(req_to_add)
@@ -301,7 +296,6 @@ def get_requirements(
req_to_add = install_req_from_parsed_requirement(
parsed_req,
isolated=options.isolated_mode,
- use_pep517=options.use_pep517,
user_supplied=True,
config_settings=(
parsed_req.options.get("config_settings")
diff --git a/src/pip/_internal/commands/download.py b/src/pip/_internal/commands/download.py
index 595774892af..903917b9ba2 100644
--- a/src/pip/_internal/commands/download.py
+++ b/src/pip/_internal/commands/download.py
@@ -7,7 +7,6 @@
from pip._internal.cli.req_command import RequirementCommand, with_cleanup
from pip._internal.cli.status_codes import SUCCESS
from pip._internal.operations.build.build_tracker import get_build_tracker
-from pip._internal.req.req_install import check_legacy_setup_py_options
from pip._internal.utils.misc import ensure_dir, normalize_path, write_output
from pip._internal.utils.temp_dir import TempDirectory
@@ -39,7 +38,6 @@ def add_options(self) -> None:
self.cmd_opts.add_option(cmdoptions.build_constraints())
self.cmd_opts.add_option(cmdoptions.requirements())
self.cmd_opts.add_option(cmdoptions.no_deps())
- self.cmd_opts.add_option(cmdoptions.global_options())
self.cmd_opts.add_option(cmdoptions.no_binary())
self.cmd_opts.add_option(cmdoptions.only_binary())
self.cmd_opts.add_option(cmdoptions.prefer_binary())
@@ -49,7 +47,6 @@ def add_options(self) -> None:
self.cmd_opts.add_option(cmdoptions.progress_bar())
self.cmd_opts.add_option(cmdoptions.no_build_isolation())
self.cmd_opts.add_option(cmdoptions.use_pep517())
- self.cmd_opts.add_option(cmdoptions.no_use_pep517())
self.cmd_opts.add_option(cmdoptions.check_build_deps())
self.cmd_opts.add_option(cmdoptions.ignore_requires_python())
@@ -106,7 +103,6 @@ def run(self, options: Values, args: list[str]) -> int:
)
reqs = self.get_requirements(args, options, finder, session)
- check_legacy_setup_py_options(options, reqs)
preparer = self.make_requirement_preparer(
temp_build_dir=directory,
@@ -124,7 +120,6 @@ def run(self, options: Values, args: list[str]) -> int:
finder=finder,
options=options,
ignore_requires_python=options.ignore_requires_python,
- use_pep517=options.use_pep517,
py_version_info=options.python_version,
)
diff --git a/src/pip/_internal/commands/install.py b/src/pip/_internal/commands/install.py
index 8a9e914a613..0949ff2111c 100644
--- a/src/pip/_internal/commands/install.py
+++ b/src/pip/_internal/commands/install.py
@@ -41,7 +41,6 @@
from pip._internal.req import install_given_reqs
from pip._internal.req.req_install import (
InstallRequirement,
- check_legacy_setup_py_options,
)
from pip._internal.utils.compat import WINDOWS
from pip._internal.utils.filesystem import test_writable_dir
@@ -59,7 +58,7 @@
running_under_virtualenv,
virtualenv_no_global,
)
-from pip._internal.wheel_builder import build, should_build_for_install_command
+from pip._internal.wheel_builder import build
logger = getLogger(__name__)
@@ -211,12 +210,10 @@ def add_options(self) -> None:
self.cmd_opts.add_option(cmdoptions.ignore_requires_python())
self.cmd_opts.add_option(cmdoptions.no_build_isolation())
self.cmd_opts.add_option(cmdoptions.use_pep517())
- self.cmd_opts.add_option(cmdoptions.no_use_pep517())
self.cmd_opts.add_option(cmdoptions.check_build_deps())
self.cmd_opts.add_option(cmdoptions.override_externally_managed())
self.cmd_opts.add_option(cmdoptions.config_settings())
- self.cmd_opts.add_option(cmdoptions.global_options())
self.cmd_opts.add_option(
"--compile",
@@ -336,8 +333,6 @@ def run(self, options: Values, args: list[str]) -> int:
target_temp_dir_path = target_temp_dir.path
self.enter_context(target_temp_dir)
- global_options = options.global_options or []
-
session = self.get_default_session(options)
target_python = make_target_python(options)
@@ -357,7 +352,6 @@ def run(self, options: Values, args: list[str]) -> int:
try:
reqs = self.get_requirements(args, options, finder, session)
- check_legacy_setup_py_options(options, reqs)
wheel_cache = WheelCache(options.cache_dir)
@@ -386,7 +380,6 @@ def run(self, options: Values, args: list[str]) -> int:
ignore_requires_python=options.ignore_requires_python,
force_reinstall=options.force_reinstall,
upgrade_strategy=upgrade_strategy,
- use_pep517=options.use_pep517,
py_version_info=options.python_version,
)
@@ -434,17 +427,13 @@ def run(self, options: Values, args: list[str]) -> int:
protect_pip_from_modification_on_windows(modifying_pip=modifying_pip)
reqs_to_build = [
- r
- for r in requirement_set.requirements_to_install
- if should_build_for_install_command(r)
+ r for r in requirement_set.requirements_to_install if not r.is_wheel
]
_, build_failures = build(
reqs_to_build,
wheel_cache=wheel_cache,
verify=True,
- build_options=[],
- global_options=global_options,
)
if build_failures:
@@ -468,7 +457,6 @@ def run(self, options: Values, args: list[str]) -> int:
installed = install_given_reqs(
to_install,
- global_options,
root=options.root_path,
home=target_temp_dir_path,
prefix=options.prefix_path,
diff --git a/src/pip/_internal/commands/lock.py b/src/pip/_internal/commands/lock.py
index 71d22007f1f..b02fb95dacf 100644
--- a/src/pip/_internal/commands/lock.py
+++ b/src/pip/_internal/commands/lock.py
@@ -11,9 +11,6 @@
from pip._internal.cli.status_codes import SUCCESS
from pip._internal.models.pylock import Pylock, is_valid_pylock_file_name
from pip._internal.operations.build.build_tracker import get_build_tracker
-from pip._internal.req.req_install import (
- check_legacy_setup_py_options,
-)
from pip._internal.utils.logging import getLogger
from pip._internal.utils.misc import (
get_pip_version,
@@ -70,7 +67,6 @@ def add_options(self) -> None:
self.cmd_opts.add_option(cmdoptions.ignore_requires_python())
self.cmd_opts.add_option(cmdoptions.no_build_isolation())
self.cmd_opts.add_option(cmdoptions.use_pep517())
- self.cmd_opts.add_option(cmdoptions.no_use_pep517())
self.cmd_opts.add_option(cmdoptions.check_build_deps())
self.cmd_opts.add_option(cmdoptions.config_settings())
@@ -117,7 +113,6 @@ def run(self, options: Values, args: list[str]) -> int:
)
reqs = self.get_requirements(args, options, finder, session)
- check_legacy_setup_py_options(options, reqs)
wheel_cache = WheelCache(options.cache_dir)
@@ -145,7 +140,6 @@ def run(self, options: Values, args: list[str]) -> int:
ignore_installed=True,
ignore_requires_python=options.ignore_requires_python,
upgrade_strategy="to-satisfy-only",
- use_pep517=options.use_pep517,
)
self.trace_basic_info(finder)
diff --git a/src/pip/_internal/commands/wheel.py b/src/pip/_internal/commands/wheel.py
index 928019bf3c2..28503940d46 100644
--- a/src/pip/_internal/commands/wheel.py
+++ b/src/pip/_internal/commands/wheel.py
@@ -11,7 +11,6 @@
from pip._internal.operations.build.build_tracker import get_build_tracker
from pip._internal.req.req_install import (
InstallRequirement,
- check_legacy_setup_py_options,
)
from pip._internal.utils.misc import ensure_dir, normalize_path
from pip._internal.utils.temp_dir import TempDirectory
@@ -57,7 +56,6 @@ def add_options(self) -> None:
self.cmd_opts.add_option(cmdoptions.prefer_binary())
self.cmd_opts.add_option(cmdoptions.no_build_isolation())
self.cmd_opts.add_option(cmdoptions.use_pep517())
- self.cmd_opts.add_option(cmdoptions.no_use_pep517())
self.cmd_opts.add_option(cmdoptions.check_build_deps())
self.cmd_opts.add_option(cmdoptions.constraints())
self.cmd_opts.add_option(cmdoptions.build_constraints())
@@ -77,8 +75,6 @@ def add_options(self) -> None:
)
self.cmd_opts.add_option(cmdoptions.config_settings())
- self.cmd_opts.add_option(cmdoptions.build_options())
- self.cmd_opts.add_option(cmdoptions.global_options())
self.cmd_opts.add_option(
"--pre",
@@ -120,7 +116,6 @@ def run(self, options: Values, args: list[str]) -> int:
)
reqs = self.get_requirements(args, options, finder, session)
- check_legacy_setup_py_options(options, reqs)
wheel_cache = WheelCache(options.cache_dir)
@@ -141,7 +136,6 @@ def run(self, options: Values, args: list[str]) -> int:
options=options,
wheel_cache=wheel_cache,
ignore_requires_python=options.ignore_requires_python,
- use_pep517=options.use_pep517,
)
self.trace_basic_info(finder)
@@ -162,8 +156,6 @@ def run(self, options: Values, args: list[str]) -> int:
reqs_to_build,
wheel_cache=wheel_cache,
verify=(not options.no_verify),
- build_options=options.build_options or [],
- global_options=options.global_options or [],
)
for req in build_successes:
assert req.link and req.link.is_wheel
diff --git a/src/pip/_internal/distributions/sdist.py b/src/pip/_internal/distributions/sdist.py
index e2821f89e00..f7bd7836d0e 100644
--- a/src/pip/_internal/distributions/sdist.py
+++ b/src/pip/_internal/distributions/sdist.py
@@ -20,7 +20,7 @@ class SourceDistribution(AbstractDistribution):
"""Represents a source distribution.
The preparation step for these needs metadata for the packages to be
- generated, either using PEP 517 or using the legacy `setup.py egg_info`.
+ generated.
"""
@property
@@ -38,28 +38,27 @@ def prepare_distribution_metadata(
build_isolation: bool,
check_build_deps: bool,
) -> None:
- # Load pyproject.toml, to determine whether PEP 517 is to be used
+ # Load pyproject.toml
self.req.load_pyproject_toml()
# Set up the build isolation, if this requirement should be isolated
- should_isolate = self.req.use_pep517 and build_isolation
- if should_isolate:
+ if build_isolation:
# Setup an isolated environment and install the build backend static
# requirements in it.
self._prepare_build_backend(build_env_installer)
- # 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()
+ # Check that the build backend supports PEP 660. 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.
+ self.req.editable_sanity_check()
# Install the dynamic build requirements.
self._install_build_reqs(build_env_installer)
+ else:
+ # When not using build isolation, we still need to check that
+ # the build backend supports PEP 660.
+ self.req.editable_sanity_check()
# Check if the current environment provides build dependencies
- should_check_deps = self.req.use_pep517 and check_build_deps
- if should_check_deps:
+ if check_build_deps:
pyproject_requires = self.req.pyproject_requires
assert pyproject_requires is not None
conflicting, missing = self.req.build_env.check_requirements(
diff --git a/src/pip/_internal/operations/build/metadata_legacy.py b/src/pip/_internal/operations/build/metadata_legacy.py
deleted file mode 100644
index e385b5ddf76..00000000000
--- a/src/pip/_internal/operations/build/metadata_legacy.py
+++ /dev/null
@@ -1,73 +0,0 @@
-"""Metadata generation logic for legacy source distributions."""
-
-import logging
-import os
-
-from pip._internal.build_env import BuildEnvironment
-from pip._internal.cli.spinners import open_spinner
-from pip._internal.exceptions import (
- InstallationError,
- InstallationSubprocessError,
- MetadataGenerationFailed,
-)
-from pip._internal.utils.setuptools_build import make_setuptools_egg_info_args
-from pip._internal.utils.subprocess import call_subprocess
-from pip._internal.utils.temp_dir import TempDirectory
-
-logger = logging.getLogger(__name__)
-
-
-def _find_egg_info(directory: str) -> str:
- """Find an .egg-info subdirectory in `directory`."""
- filenames = [f for f in os.listdir(directory) if f.endswith(".egg-info")]
-
- if not filenames:
- raise InstallationError(f"No .egg-info directory found in {directory}")
-
- if len(filenames) > 1:
- raise InstallationError(
- f"More than one .egg-info directory found in {directory}"
- )
-
- return os.path.join(directory, filenames[0])
-
-
-def generate_metadata(
- build_env: BuildEnvironment,
- setup_py_path: str,
- source_dir: str,
- isolated: bool,
- details: str,
-) -> str:
- """Generate metadata using setup.py-based defacto mechanisms.
-
- Returns the generated metadata directory.
- """
- logger.debug(
- "Running setup.py (path:%s) egg_info for package %s",
- setup_py_path,
- details,
- )
-
- egg_info_dir = TempDirectory(kind="pip-egg-info", globally_managed=True).path
-
- args = make_setuptools_egg_info_args(
- setup_py_path,
- egg_info_dir=egg_info_dir,
- no_user_config=isolated,
- )
-
- with build_env:
- with open_spinner("Preparing metadata (setup.py)") as spinner:
- try:
- call_subprocess(
- args,
- cwd=source_dir,
- command_desc="python setup.py egg_info",
- spinner=spinner,
- )
- except InstallationSubprocessError as error:
- raise MetadataGenerationFailed(package_details=details) from error
-
- # Return the .egg-info directory.
- return _find_egg_info(egg_info_dir)
diff --git a/src/pip/_internal/operations/build/wheel_legacy.py b/src/pip/_internal/operations/build/wheel_legacy.py
deleted file mode 100644
index cef0bd06687..00000000000
--- a/src/pip/_internal/operations/build/wheel_legacy.py
+++ /dev/null
@@ -1,119 +0,0 @@
-from __future__ import annotations
-
-import logging
-import os.path
-
-from pip._internal.cli.spinners import open_spinner
-from pip._internal.utils.deprecation import deprecated
-from pip._internal.utils.setuptools_build import make_setuptools_bdist_wheel_args
-from pip._internal.utils.subprocess import call_subprocess, format_command_args
-
-logger = logging.getLogger(__name__)
-
-
-def format_command_result(
- command_args: list[str],
- command_output: str,
-) -> str:
- """Format command information for logging."""
- command_desc = format_command_args(command_args)
- text = f"Command arguments: {command_desc}\n"
-
- if not command_output:
- text += "Command output: None"
- elif logger.getEffectiveLevel() > logging.DEBUG:
- text += "Command output: [use --verbose to show]"
- else:
- if not command_output.endswith("\n"):
- command_output += "\n"
- text += f"Command output:\n{command_output}"
-
- return text
-
-
-def get_legacy_build_wheel_path(
- names: list[str],
- wheel_directory: str,
- name: str,
- command_args: list[str],
- command_output: str,
-) -> str | None:
- """Return the path to the wheel in the temporary build directory."""
- # Sort for determinism.
- names = sorted(names)
- if not names:
- msg = f"Legacy build of wheel for {name!r} created no files.\n"
- msg += format_command_result(command_args, command_output)
- logger.warning(msg)
- return None
-
- if len(names) > 1:
- msg = (
- f"Legacy build of wheel for {name!r} created more than one file.\n"
- f"Filenames (choosing first): {names}\n"
- )
- msg += format_command_result(command_args, command_output)
- logger.warning(msg)
-
- return os.path.join(wheel_directory, names[0])
-
-
-def build_wheel_legacy(
- name: str,
- setup_py_path: str,
- source_dir: str,
- global_options: list[str],
- build_options: list[str],
- wheel_directory: str,
-) -> str | None:
- """Build one unpacked package using the "legacy" build process.
-
- Returns path to wheel if successfully built. Otherwise, returns None.
- """
- deprecated(
- reason=(
- f"Building {name!r} using the legacy setup.py bdist_wheel mechanism, "
- "which will be removed in a future version."
- ),
- replacement=(
- "to use the standardized build interface by "
- "setting the `--use-pep517` option, "
- "(possibly combined with `--no-build-isolation`), "
- f"or adding a `pyproject.toml` file to the source tree of {name!r}"
- ),
- gone_in="25.3",
- issue=6334,
- )
-
- wheel_args = make_setuptools_bdist_wheel_args(
- setup_py_path,
- global_options=global_options,
- build_options=build_options,
- destination_dir=wheel_directory,
- )
-
- spin_message = f"Building wheel for {name} (setup.py)"
- with open_spinner(spin_message) as spinner:
- logger.debug("Destination directory: %s", wheel_directory)
-
- try:
- output = call_subprocess(
- wheel_args,
- command_desc="python setup.py bdist_wheel",
- cwd=source_dir,
- spinner=spinner,
- )
- except Exception:
- spinner.finish("error")
- logger.error("Failed building wheel for %s", name)
- return None
-
- names = os.listdir(wheel_directory)
- wheel_path = get_legacy_build_wheel_path(
- names=names,
- wheel_directory=wheel_directory,
- name=name,
- command_args=wheel_args,
- command_output=output,
- )
- return wheel_path
diff --git a/src/pip/_internal/operations/install/editable_legacy.py b/src/pip/_internal/operations/install/editable_legacy.py
deleted file mode 100644
index 0603d3d8819..00000000000
--- a/src/pip/_internal/operations/install/editable_legacy.py
+++ /dev/null
@@ -1,48 +0,0 @@
-"""Legacy editable installation process, i.e. `setup.py develop`."""
-
-from __future__ import annotations
-
-import logging
-from collections.abc import Sequence
-
-from pip._internal.build_env import BuildEnvironment
-from pip._internal.utils.logging import indent_log
-from pip._internal.utils.setuptools_build import make_setuptools_develop_args
-from pip._internal.utils.subprocess import call_subprocess
-
-logger = logging.getLogger(__name__)
-
-
-def install_editable(
- *,
- global_options: Sequence[str],
- prefix: str | None,
- home: str | None,
- use_user_site: bool,
- name: str,
- setup_py_path: str,
- isolated: bool,
- build_env: BuildEnvironment,
- unpacked_source_directory: str,
-) -> None:
- """Install a package in editable mode. Most arguments are pass-through
- to setuptools.
- """
- logger.info("Running setup.py develop for %s", name)
-
- args = make_setuptools_develop_args(
- setup_py_path,
- global_options=global_options,
- no_user_config=isolated,
- prefix=prefix,
- home=home,
- use_user_site=use_user_site,
- )
-
- with indent_log():
- with build_env:
- call_subprocess(
- args,
- command_desc="python setup.py develop",
- cwd=unpacked_source_directory,
- )
diff --git a/src/pip/_internal/pyproject.py b/src/pip/_internal/pyproject.py
index 5c08b60e5b5..8c2f7221c93 100644
--- a/src/pip/_internal/pyproject.py
+++ b/src/pip/_internal/pyproject.py
@@ -1,6 +1,5 @@
from __future__ import annotations
-import importlib.util
import os
from collections import namedtuple
from typing import Any
@@ -30,13 +29,11 @@ def make_pyproject_path(unpacked_source_directory: str) -> str:
def load_pyproject_toml(
- use_pep517: bool | None, pyproject_toml: str, setup_py: str, req_name: str
-) -> BuildSystemDetails | None:
+ pyproject_toml: str, setup_py: str, req_name: str
+) -> BuildSystemDetails:
"""Load the pyproject.toml file.
Parameters:
- use_pep517 - Has the user requested PEP 517 processing? None
- means the user hasn't explicitly specified.
pyproject_toml - Location of the project's pyproject.toml file
setup_py - Location of the project's setup.py file
req_name - The name of the requirement we're processing (for
@@ -69,57 +66,7 @@ def load_pyproject_toml(
else:
build_system = None
- # The following cases must use PEP 517
- # We check for use_pep517 being non-None and falsy because that means
- # the user explicitly requested --no-use-pep517. The value 0 as
- # opposed to False can occur when the value is provided via an
- # environment variable or config file option (due to the quirk of
- # strtobool() returning an integer in pip's configuration code).
- if has_pyproject and not has_setup:
- if use_pep517 is not None and not use_pep517:
- raise InstallationError(
- "Disabling PEP 517 processing is invalid: "
- "project does not have a setup.py"
- )
- use_pep517 = True
- elif build_system and "build-backend" in build_system:
- if use_pep517 is not None and not use_pep517:
- raise InstallationError(
- "Disabling PEP 517 processing is invalid: "
- "project specifies a build backend of {} "
- "in pyproject.toml".format(build_system["build-backend"])
- )
- use_pep517 = True
-
- # If we haven't worked out whether to use PEP 517 yet,
- # and the user hasn't explicitly stated a preference,
- # we do so if the project has a pyproject.toml file
- # or if we cannot import setuptools or wheels.
-
- # We fallback to PEP 517 when without setuptools or without the wheel package,
- # so setuptools can be installed as a default build backend.
- # For more info see:
- # https://discuss.python.org/t/pip-without-setuptools-could-the-experience-be-improved/11810/9
- # https://github.com/pypa/pip/issues/8559
- elif use_pep517 is None:
- use_pep517 = (
- has_pyproject
- or not importlib.util.find_spec("setuptools")
- or not importlib.util.find_spec("wheel")
- )
-
- # At this point, we know whether we're going to use PEP 517.
- assert use_pep517 is not None
-
- # If we're using the legacy code path, there is nothing further
- # for us to do here.
- if not use_pep517:
- return None
-
if build_system is None:
- # Either the user has a pyproject.toml with no build-system
- # section, or the user has no pyproject.toml, but has opted in
- # explicitly via --use-pep517.
# In the absence of any explicit backend specification, we
# assume the setuptools backend that most closely emulates the
# traditional direct setup.py execution, and require wheel and
@@ -130,12 +77,6 @@ def load_pyproject_toml(
"build-backend": "setuptools.build_meta:__legacy__",
}
- # If we're using PEP 517, we have build system information (either
- # from pyproject.toml, or defaulted by the code above).
- # Note that at this point, we do not know if the user has actually
- # specified a backend, though.
- assert build_system is not None
-
# Ensure that the build-system section in pyproject.toml conforms
# to PEP 518.
diff --git a/src/pip/_internal/req/__init__.py b/src/pip/_internal/req/__init__.py
index e5050ee588b..5fc8752d8e4 100644
--- a/src/pip/_internal/req/__init__.py
+++ b/src/pip/_internal/req/__init__.py
@@ -2,7 +2,7 @@
import collections
import logging
-from collections.abc import Generator, Sequence
+from collections.abc import Generator
from dataclasses import dataclass
from pip._internal.cli.progress_bars import BarType, get_install_progress_renderer
@@ -37,7 +37,6 @@ def _validate_requirements(
def install_given_reqs(
requirements: list[InstallRequirement],
- global_options: Sequence[str],
root: str | None,
home: str | None,
prefix: str | None,
@@ -83,7 +82,6 @@ def install_given_reqs(
try:
requirement.install(
- global_options,
root=root,
home=home,
prefix=prefix,
diff --git a/src/pip/_internal/req/constructors.py b/src/pip/_internal/req/constructors.py
index 76c8c38499a..f8531e113a3 100644
--- a/src/pip/_internal/req/constructors.py
+++ b/src/pip/_internal/req/constructors.py
@@ -225,9 +225,7 @@ def install_req_from_editable(
editable_req: str,
comes_from: InstallRequirement | str | None = None,
*,
- use_pep517: bool | None = None,
isolated: bool = False,
- global_options: list[str] | None = None,
hash_options: dict[str, list[str]] | None = None,
constraint: bool = False,
user_supplied: bool = False,
@@ -244,9 +242,7 @@ def install_req_from_editable(
permit_editable_wheels=permit_editable_wheels,
link=parts.link,
constraint=constraint,
- use_pep517=use_pep517,
isolated=isolated,
- global_options=global_options,
hash_options=hash_options,
config_settings=config_settings,
extras=parts.extras,
@@ -389,9 +385,7 @@ def install_req_from_line(
name: str,
comes_from: str | InstallRequirement | None = None,
*,
- use_pep517: bool | None = None,
isolated: bool = False,
- global_options: list[str] | None = None,
hash_options: dict[str, list[str]] | None = None,
constraint: bool = False,
line_source: str | None = None,
@@ -411,9 +405,7 @@ def install_req_from_line(
comes_from,
link=parts.link,
markers=parts.markers,
- use_pep517=use_pep517,
isolated=isolated,
- global_options=global_options,
hash_options=hash_options,
config_settings=config_settings,
constraint=constraint,
@@ -426,7 +418,6 @@ def install_req_from_req_string(
req_string: str,
comes_from: InstallRequirement | None = None,
isolated: bool = False,
- use_pep517: bool | None = None,
user_supplied: bool = False,
) -> InstallRequirement:
try:
@@ -455,7 +446,6 @@ def install_req_from_req_string(
req,
comes_from,
isolated=isolated,
- use_pep517=use_pep517,
user_supplied=user_supplied,
)
@@ -463,7 +453,6 @@ def install_req_from_req_string(
def install_req_from_parsed_requirement(
parsed_req: ParsedRequirement,
isolated: bool = False,
- use_pep517: bool | None = None,
user_supplied: bool = False,
config_settings: dict[str, str | list[str]] | None = None,
) -> InstallRequirement:
@@ -471,7 +460,6 @@ def install_req_from_parsed_requirement(
req = install_req_from_editable(
parsed_req.requirement,
comes_from=parsed_req.comes_from,
- use_pep517=use_pep517,
constraint=parsed_req.constraint,
isolated=isolated,
user_supplied=user_supplied,
@@ -482,13 +470,7 @@ def install_req_from_parsed_requirement(
req = install_req_from_line(
parsed_req.requirement,
comes_from=parsed_req.comes_from,
- use_pep517=use_pep517,
isolated=isolated,
- global_options=(
- parsed_req.options.get("global_options", [])
- if parsed_req.options
- else []
- ),
hash_options=(
parsed_req.options.get("hashes", {}) if parsed_req.options else {}
),
@@ -509,9 +491,7 @@ def install_req_from_link_and_ireq(
editable=ireq.editable,
link=link,
markers=ireq.markers,
- use_pep517=ireq.use_pep517,
isolated=ireq.isolated,
- global_options=ireq.global_options,
hash_options=ireq.hash_options,
config_settings=ireq.config_settings,
user_supplied=ireq.user_supplied,
@@ -532,9 +512,7 @@ def install_req_drop_extras(ireq: InstallRequirement) -> InstallRequirement:
editable=ireq.editable,
link=ireq.link,
markers=ireq.markers,
- use_pep517=ireq.use_pep517,
isolated=ireq.isolated,
- global_options=ireq.global_options,
hash_options=ireq.hash_options,
constraint=ireq.constraint,
extras=[],
diff --git a/src/pip/_internal/req/req_file.py b/src/pip/_internal/req/req_file.py
index 0aad0a36602..a4f54b438f2 100644
--- a/src/pip/_internal/req/req_file.py
+++ b/src/pip/_internal/req/req_file.py
@@ -65,7 +65,6 @@
# options to be passed to requirements
SUPPORTED_OPTIONS_REQ: list[Callable[..., optparse.Option]] = [
- cmdoptions.global_options,
cmdoptions.hash,
cmdoptions.config_settings,
]
diff --git a/src/pip/_internal/req/req_install.py b/src/pip/_internal/req/req_install.py
index cdc71f738f0..bd4fb0717d6 100644
--- a/src/pip/_internal/req/req_install.py
+++ b/src/pip/_internal/req/req_install.py
@@ -7,7 +7,7 @@
import sys
import uuid
import zipfile
-from collections.abc import Collection, Iterable, Sequence
+from collections.abc import Collection, Iterable
from optparse import Values
from pathlib import Path
from typing import Any
@@ -34,12 +34,6 @@
from pip._internal.models.link import Link
from pip._internal.operations.build.metadata import generate_metadata
from pip._internal.operations.build.metadata_editable import generate_editable_metadata
-from pip._internal.operations.build.metadata_legacy import (
- generate_metadata as generate_metadata_legacy,
-)
-from pip._internal.operations.install.editable_legacy import (
- install_editable as install_editable_legacy,
-)
from pip._internal.operations.install.wheel import install_wheel
from pip._internal.pyproject import load_pyproject_toml, make_pyproject_path
from pip._internal.req.req_uninstall import UninstallPathSet
@@ -79,10 +73,8 @@ def __init__(
editable: bool = False,
link: Link | None = None,
markers: Marker | None = None,
- use_pep517: bool | None = None,
isolated: bool = False,
*,
- global_options: list[str] | None = None,
hash_options: dict[str, list[str]] | None = None,
config_settings: dict[str, str | list[str]] | None = None,
constraint: bool = False,
@@ -149,7 +141,6 @@ def __init__(
# Set to True after successful installation
self.install_succeeded: bool | None = None
# Supplied options
- self.global_options = global_options if global_options else []
self.hash_options = hash_options if hash_options else {}
self.config_settings = config_settings
# Set to True after successful preparation of this requirement
@@ -181,23 +172,6 @@ def __init__(
# The PEP 517 backend we should use to build the project
self.pep517_backend: BuildBackendHookCaller | None = None
- # Are we using PEP 517 for this requirement?
- # After pyproject.toml has been loaded, the only valid values are True
- # and False. Before loading, None is valid (meaning "use the default").
- # Setting an explicit value before loading pyproject.toml is supported,
- # but after loading this flag should be treated as read only.
- self.use_pep517 = use_pep517
-
- # If config settings are provided, enforce PEP 517.
- if self.config_settings:
- if self.use_pep517 is False:
- logger.warning(
- "--no-use-pep517 ignored for %s "
- "because --config-settings are specified.",
- self,
- )
- self.use_pep517 = True
-
# This requirement needs more preparation before it can be built
self.needs_more_preparation = False
@@ -254,8 +228,6 @@ def name(self) -> str | None:
@functools.cached_property
def supports_pyproject_editable(self) -> bool:
- if not self.use_pep517:
- return False
assert self.pep517_backend
with self.build_env:
runner = runner_with_spinner_message(
@@ -496,13 +468,6 @@ def setup_py_path(self) -> str:
return setup_py
- @property
- def setup_cfg_path(self) -> str:
- assert self.source_dir, f"No source dir for {self}"
- setup_cfg = os.path.join(self.unpacked_source_directory, "setup.cfg")
-
- return setup_cfg
-
@property
def pyproject_toml_path(self) -> str:
assert self.source_dir, f"No source dir for {self}"
@@ -512,20 +477,12 @@ def load_pyproject_toml(self) -> None:
"""Load the pyproject.toml file.
After calling this routine, all of the attributes related to PEP 517
- processing for this requirement have been set. In particular, the
- use_pep517 attribute can be used to determine whether we should
- follow the PEP 517 or legacy (setup.py) code path.
+ processing for this requirement have been set.
"""
pyproject_toml_data = load_pyproject_toml(
- self.use_pep517, self.pyproject_toml_path, self.setup_py_path, str(self)
+ self.pyproject_toml_path, self.setup_py_path, str(self)
)
-
- if pyproject_toml_data is None:
- assert not self.config_settings
- self.use_pep517 = False
- return
-
- self.use_pep517 = True
+ assert pyproject_toml_data
requires, backend, check, backend_path = pyproject_toml_data
self.requirements_to_check = check
self.pyproject_requires = requires
@@ -536,23 +493,15 @@ def load_pyproject_toml(self) -> None:
backend_path=backend_path,
)
- def isolated_editable_sanity_check(self) -> None:
+ def editable_sanity_check(self) -> None:
"""Check that an editable requirement if valid for use with PEP 517/518.
- This verifies that an editable that has a pyproject.toml either supports PEP 660
- or as a setup.py or a setup.cfg
+ This verifies that an editable has a build backend that supports PEP 660.
"""
- if (
- self.editable
- and self.use_pep517
- and not self.supports_pyproject_editable
- and not os.path.isfile(self.setup_py_path)
- and not os.path.isfile(self.setup_cfg_path)
- ):
+ if self.editable and not self.supports_pyproject_editable:
raise InstallationError(
- f"Project {self} has a 'pyproject.toml' and its build "
- f"backend is missing the 'build_editable' hook. Since it does not "
- f"have a 'setup.py' nor a 'setup.cfg', "
+ f"Project {self} uses a build backend "
+ f"that is missing the 'build_editable' hook, so "
f"it cannot be installed in editable mode. "
f"Consider using a build backend that supports PEP 660."
)
@@ -566,30 +515,21 @@ def prepare_metadata(self) -> None:
assert self.source_dir, f"No source dir for {self}"
details = self.name or f"from {self.link}"
- if self.use_pep517:
- assert self.pep517_backend is not None
- if (
- self.editable
- and self.permit_editable_wheels
- and self.supports_pyproject_editable
- ):
- self.metadata_directory = generate_editable_metadata(
- build_env=self.build_env,
- backend=self.pep517_backend,
- details=details,
- )
- else:
- self.metadata_directory = generate_metadata(
- build_env=self.build_env,
- backend=self.pep517_backend,
- details=details,
- )
+ assert self.pep517_backend is not None
+ if (
+ self.editable
+ and self.permit_editable_wheels
+ and self.supports_pyproject_editable
+ ):
+ self.metadata_directory = generate_editable_metadata(
+ build_env=self.build_env,
+ backend=self.pep517_backend,
+ details=details,
+ )
else:
- self.metadata_directory = generate_metadata_legacy(
+ self.metadata_directory = generate_metadata(
build_env=self.build_env,
- setup_py_path=self.setup_py_path,
- source_dir=self.unpacked_source_directory,
- isolated=self.isolated,
+ backend=self.pep517_backend,
details=details,
)
@@ -818,7 +758,6 @@ def archive(self, build_dir: str | None) -> None:
def install(
self,
- global_options: Sequence[str] | None = None,
root: str | None = None,
home: str | None = None,
prefix: str | None = None,
@@ -836,43 +775,6 @@ def install(
prefix=prefix,
)
- if self.editable and not self.is_wheel:
- deprecated(
- reason=(
- f"Legacy editable install of {self} (setup.py develop) "
- "is deprecated."
- ),
- replacement=(
- "to add a pyproject.toml or enable --use-pep517, "
- "and use setuptools >= 64. "
- "If the resulting installation is not behaving as expected, "
- "try using --config-settings editable_mode=compat. "
- "Please consult the setuptools documentation for more information"
- ),
- gone_in="25.3",
- issue=11457,
- )
- if self.config_settings:
- logger.warning(
- "--config-settings ignored for legacy editable install of %s. "
- "Consider upgrading to a version of setuptools "
- "that supports PEP 660 (>= 64).",
- self,
- )
- install_editable_legacy(
- global_options=global_options if global_options is not None else [],
- prefix=prefix,
- home=home,
- use_user_site=use_user_site,
- name=self.req.name,
- setup_py_path=self.setup_py_path,
- isolated=self.isolated,
- build_env=self.build_env,
- unpacked_source_directory=self.unpacked_source_directory,
- )
- self.install_succeeded = True
- return
-
assert self.is_wheel
assert self.local_file_path
@@ -924,23 +826,3 @@ def _has_option(options: Values, reqs: list[InstallRequirement], option: str) ->
if getattr(req, option, None):
return True
return False
-
-
-def check_legacy_setup_py_options(
- options: Values,
- reqs: list[InstallRequirement],
-) -> None:
- has_build_options = _has_option(options, reqs, "build_options")
- has_global_options = _has_option(options, reqs, "global_options")
- if has_build_options or has_global_options:
- deprecated(
- reason="--build-option and --global-option are deprecated.",
- issue=11859,
- replacement="to use --config-settings",
- gone_in="25.3",
- )
- logger.warning(
- "Implying --no-binary=:all: due to the presence of "
- "--build-option / --global-option. "
- )
- options.format_control.disallow_binaries()
diff --git a/src/pip/_internal/resolution/resolvelib/candidates.py b/src/pip/_internal/resolution/resolvelib/candidates.py
index 5a4ab8154d9..108942768f9 100644
--- a/src/pip/_internal/resolution/resolvelib/candidates.py
+++ b/src/pip/_internal/resolution/resolvelib/candidates.py
@@ -69,10 +69,8 @@ def make_install_req_from_link(
line,
user_supplied=template.user_supplied,
comes_from=template.comes_from,
- use_pep517=template.use_pep517,
isolated=template.isolated,
constraint=template.constraint,
- global_options=template.global_options,
hash_options=template.hash_options,
config_settings=template.config_settings,
)
@@ -90,11 +88,9 @@ def make_install_req_from_editable(
link.url,
user_supplied=template.user_supplied,
comes_from=template.comes_from,
- use_pep517=template.use_pep517,
isolated=template.isolated,
constraint=template.constraint,
permit_editable_wheels=template.permit_editable_wheels,
- global_options=template.global_options,
hash_options=template.hash_options,
config_settings=template.config_settings,
)
@@ -115,10 +111,8 @@ def _make_install_req_from_dist(
line,
user_supplied=template.user_supplied,
comes_from=template.comes_from,
- use_pep517=template.use_pep517,
isolated=template.isolated,
constraint=template.constraint,
- global_options=template.global_options,
hash_options=template.hash_options,
config_settings=template.config_settings,
)
diff --git a/src/pip/_internal/utils/setuptools_build.py b/src/pip/_internal/utils/setuptools_build.py
deleted file mode 100644
index 1b8c7a1c21f..00000000000
--- a/src/pip/_internal/utils/setuptools_build.py
+++ /dev/null
@@ -1,149 +0,0 @@
-from __future__ import annotations
-
-import sys
-import textwrap
-from collections.abc import Sequence
-
-# Shim to wrap setup.py invocation with setuptools
-# Note that __file__ is handled via two {!r} *and* %r, to ensure that paths on
-# Windows are correctly handled (it should be "C:\\Users" not "C:\Users").
-_SETUPTOOLS_SHIM = textwrap.dedent(
- """
- exec(compile('''
- # This is -- a caller that pip uses to run setup.py
- #
- # - It imports setuptools before invoking setup.py, to enable projects that directly
- # import from `distutils.core` to work with newer packaging standards.
- # - It provides a clear error message when setuptools is not installed.
- # - It sets `sys.argv[0]` to the underlying `setup.py`, when invoking `setup.py` so
- # setuptools doesn't think the script is `-c`. This avoids the following warning:
- # manifest_maker: standard file '-c' not found".
- # - It generates a shim setup.py, for handling setup.cfg-only projects.
- import os, sys, tokenize, traceback
-
- try:
- import setuptools
- except ImportError:
- print(
- "ERROR: Can not execute `setup.py` since setuptools failed to import in "
- "the build environment with exception:",
- file=sys.stderr,
- )
- traceback.print_exc()
- sys.exit(1)
-
- __file__ = %r
- sys.argv[0] = __file__
-
- if os.path.exists(__file__):
- filename = __file__
- with tokenize.open(__file__) as f:
- setup_py_code = f.read()
- else:
- filename = ""
- setup_py_code = "from setuptools import setup; setup()"
-
- exec(compile(setup_py_code, filename, "exec"))
- ''' % ({!r},), "", "exec"))
- """
-).rstrip()
-
-
-def make_setuptools_shim_args(
- setup_py_path: str,
- global_options: Sequence[str] | None = None,
- no_user_config: bool = False,
- unbuffered_output: bool = False,
-) -> list[str]:
- """
- Get setuptools command arguments with shim wrapped setup file invocation.
-
- :param setup_py_path: The path to setup.py to be wrapped.
- :param global_options: Additional global options.
- :param no_user_config: If True, disables personal user configuration.
- :param unbuffered_output: If True, adds the unbuffered switch to the
- argument list.
- """
- args = [sys.executable]
- if unbuffered_output:
- args += ["-u"]
- args += ["-c", _SETUPTOOLS_SHIM.format(setup_py_path)]
- if global_options:
- args += global_options
- if no_user_config:
- args += ["--no-user-cfg"]
- return args
-
-
-def make_setuptools_bdist_wheel_args(
- setup_py_path: str,
- global_options: Sequence[str],
- build_options: Sequence[str],
- destination_dir: str,
-) -> list[str]:
- # NOTE: Eventually, we'd want to also -S to the flags here, when we're
- # isolating. Currently, it breaks Python in virtualenvs, because it
- # relies on site.py to find parts of the standard library outside the
- # virtualenv.
- args = make_setuptools_shim_args(
- setup_py_path, global_options=global_options, unbuffered_output=True
- )
- args += ["bdist_wheel", "-d", destination_dir]
- args += build_options
- return args
-
-
-def make_setuptools_clean_args(
- setup_py_path: str,
- global_options: Sequence[str],
-) -> list[str]:
- args = make_setuptools_shim_args(
- setup_py_path, global_options=global_options, unbuffered_output=True
- )
- args += ["clean", "--all"]
- return args
-
-
-def make_setuptools_develop_args(
- setup_py_path: str,
- *,
- global_options: Sequence[str],
- no_user_config: bool,
- prefix: str | None,
- home: str | None,
- use_user_site: bool,
-) -> list[str]:
- assert not (use_user_site and prefix)
-
- args = make_setuptools_shim_args(
- setup_py_path,
- global_options=global_options,
- no_user_config=no_user_config,
- )
-
- args += ["develop", "--no-deps"]
-
- if prefix:
- args += ["--prefix", prefix]
- if home is not None:
- args += ["--install-dir", home]
-
- if use_user_site:
- args += ["--user", "--prefix="]
-
- return args
-
-
-def make_setuptools_egg_info_args(
- setup_py_path: str,
- egg_info_dir: str | None,
- no_user_config: bool,
-) -> list[str]:
- args = make_setuptools_shim_args(setup_py_path, no_user_config=no_user_config)
-
- args += ["egg_info"]
-
- if egg_info_dir:
- args += ["--egg-base", egg_info_dir]
-
- return args
diff --git a/src/pip/_internal/wheel_builder.py b/src/pip/_internal/wheel_builder.py
index 90871ad4f3f..4dbf7677866 100644
--- a/src/pip/_internal/wheel_builder.py
+++ b/src/pip/_internal/wheel_builder.py
@@ -18,12 +18,9 @@
from pip._internal.models.wheel import Wheel
from pip._internal.operations.build.wheel import build_wheel_pep517
from pip._internal.operations.build.wheel_editable import build_wheel_editable
-from pip._internal.operations.build.wheel_legacy import build_wheel_legacy
from pip._internal.req.req_install import InstallRequirement
from pip._internal.utils.logging import indent_log
from pip._internal.utils.misc import ensure_dir, hash_file
-from pip._internal.utils.setuptools_build import make_setuptools_clean_args
-from pip._internal.utils.subprocess import call_subprocess
from pip._internal.utils.urls import path_to_url
from pip._internal.vcs import vcs
@@ -42,37 +39,12 @@ def _contains_egg_info(s: str) -> bool:
return bool(_egg_info_re.search(s))
-def _should_build(
- req: InstallRequirement,
-) -> bool:
- """Return whether an InstallRequirement should be built into a wheel."""
- assert not req.constraint
-
- if req.is_wheel:
- return False
-
- assert req.source_dir
-
- if req.editable:
- # we only build PEP 660 editable requirements
- return req.supports_pyproject_editable
-
- return True
-
-
-def should_build_for_install_command(
- req: InstallRequirement,
-) -> bool:
- return _should_build(req)
-
-
def _should_cache(
req: InstallRequirement,
) -> bool | None:
"""
Return whether a built InstallRequirement can be stored in the persistent
- wheel cache, assuming the wheel cache is available, and _should_build()
- has determined a wheel needs to be built.
+ wheel cache, assuming the wheel cache is available.
"""
if req.editable or not req.source_dir:
# never cache editable requirements
@@ -147,8 +119,6 @@ def _build_one(
req: InstallRequirement,
output_dir: str,
verify: bool,
- build_options: list[str],
- global_options: list[str],
editable: bool,
) -> str | None:
"""Build one wheel.
@@ -169,9 +139,7 @@ def _build_one(
# Install build deps into temporary directory (PEP 518)
with req.build_env:
- wheel_path = _build_one_inside_env(
- req, output_dir, build_options, global_options, editable
- )
+ wheel_path = _build_one_inside_env(req, output_dir, editable)
if wheel_path and verify:
try:
_verify_one(req, wheel_path)
@@ -184,44 +152,24 @@ def _build_one(
def _build_one_inside_env(
req: InstallRequirement,
output_dir: str,
- build_options: list[str],
- global_options: list[str],
editable: bool,
) -> str | None:
with TemporaryDirectory(dir=output_dir) as wheel_directory:
assert req.name
- if req.use_pep517:
- assert req.metadata_directory
- assert req.pep517_backend
- if global_options:
- logger.warning(
- "Ignoring --global-option when building %s using PEP 517", req.name
- )
- if build_options:
- logger.warning(
- "Ignoring --build-option when building %s using PEP 517", req.name
- )
- if editable:
- wheel_path = build_wheel_editable(
- name=req.name,
- backend=req.pep517_backend,
- metadata_directory=req.metadata_directory,
- wheel_directory=wheel_directory,
- )
- else:
- wheel_path = build_wheel_pep517(
- name=req.name,
- backend=req.pep517_backend,
- metadata_directory=req.metadata_directory,
- wheel_directory=wheel_directory,
- )
+ assert req.metadata_directory
+ assert req.pep517_backend
+ if editable:
+ wheel_path = build_wheel_editable(
+ name=req.name,
+ backend=req.pep517_backend,
+ metadata_directory=req.metadata_directory,
+ wheel_directory=wheel_directory,
+ )
else:
- wheel_path = build_wheel_legacy(
+ wheel_path = build_wheel_pep517(
name=req.name,
- setup_py_path=req.setup_py_path,
- source_dir=req.unpacked_source_directory,
- global_options=global_options,
- build_options=build_options,
+ backend=req.pep517_backend,
+ metadata_directory=req.metadata_directory,
wheel_directory=wheel_directory,
)
@@ -250,35 +198,13 @@ def _build_one_inside_env(
req.name,
e,
)
- # Ignore return, we can't do anything else useful.
- if not req.use_pep517:
- _clean_one_legacy(req, global_options)
return None
-def _clean_one_legacy(req: InstallRequirement, global_options: list[str]) -> bool:
- clean_args = make_setuptools_clean_args(
- req.setup_py_path,
- global_options=global_options,
- )
-
- logger.info("Running setup.py clean for %s", req.name)
- try:
- call_subprocess(
- clean_args, command_desc="python setup.py clean", cwd=req.source_dir
- )
- return True
- except Exception:
- logger.error("Failed cleaning build dir for %s", req.name)
- return False
-
-
def build(
requirements: Iterable[InstallRequirement],
wheel_cache: WheelCache,
verify: bool,
- build_options: list[str],
- global_options: list[str],
) -> BuildResult:
"""Build wheels.
@@ -303,8 +229,6 @@ def build(
req,
cache_dir,
verify,
- build_options,
- global_options,
req.editable and req.permit_editable_wheels,
)
if wheel_file:
diff --git a/tests/data/packages/SetupPyUTF8/setup.py b/tests/data/packages/SetupPyUTF8/setup.py
index bd9fd2a294b..026d3a215e6 100644
--- a/tests/data/packages/SetupPyUTF8/setup.py
+++ b/tests/data/packages/SetupPyUTF8/setup.py
@@ -1,4 +1,4 @@
-from distutils.core import setup
+from setuptools import setup
setup(
name="SetupPyUTF8",
diff --git a/tests/data/src/chattymodule/backend.py b/tests/data/src/chattymodule/backend.py
new file mode 100644
index 00000000000..5993b53f607
--- /dev/null
+++ b/tests/data/src/chattymodule/backend.py
@@ -0,0 +1,23 @@
+import os
+import sys
+
+from setuptools import build_meta
+from setuptools.build_meta import *
+
+
+def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None):
+ if config_settings and "fail" in config_settings:
+ print("I DIE, I DIE in prepare_metadata_for_build_wheel")
+ sys.exit(1)
+ print("HELLO FROM CHATTYMODULE prepare_metadata_for_build_wheel")
+ return build_meta.prepare_metadata_for_build_wheel(
+ metadata_directory, config_settings
+ )
+
+
+def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
+ if config_settings and "fail" in config_settings:
+ print("I DIE, I DIE in build_wheel")
+ sys.exit(1)
+ print("HELLO FROM CHATTYMODULE build_wheel")
+ return build_meta.build_wheel(wheel_directory, config_settings, metadata_directory)
diff --git a/tests/data/src/chattymodule/pyproject.toml b/tests/data/src/chattymodule/pyproject.toml
new file mode 100644
index 00000000000..54de20d46fc
--- /dev/null
+++ b/tests/data/src/chattymodule/pyproject.toml
@@ -0,0 +1,11 @@
+[build-system]
+requires = ["setuptools"]
+build-backend = "backend"
+backend-path = ["."]
+
+[project]
+name = "chattymodule"
+version = "0.0.1"
+
+[tool.setuptools]
+py-modules = ["chattymodule"]
diff --git a/tests/data/src/chattymodule/setup.cfg b/tests/data/src/chattymodule/setup.cfg
deleted file mode 100644
index 79bc67848ff..00000000000
--- a/tests/data/src/chattymodule/setup.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-[bdist_wheel]
-# This flag says that the code is written to work on both Python 2 and Python
-# 3. If at all possible, it is good practice to do this. If you cannot, you
-# will need to generate wheels for each Python version that you support.
-universal=1
diff --git a/tests/data/src/chattymodule/setup.py b/tests/data/src/chattymodule/setup.py
deleted file mode 100644
index 9f411b6fdff..00000000000
--- a/tests/data/src/chattymodule/setup.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# A chatty setup.py for testing pip subprocess output handling
-
-import os
-import sys
-
-from setuptools import setup
-
-print(f"HELLO FROM CHATTYMODULE {sys.argv[1]}")
-print(sys.argv)
-print(sys.executable)
-print(sys.version)
-
-if "--fail" in sys.argv:
- print("I DIE, I DIE")
- sys.exit(1)
-
-setup(
- name="chattymodule",
- version="0.0.1",
- description="A sample Python project with a single module",
- py_modules=["chattymodule"],
-)
diff --git a/tests/functional/test_check.py b/tests/functional/test_check.py
index 06ed1b08eac..656d5ac866b 100644
--- a/tests/functional/test_check.py
+++ b/tests/functional/test_check.py
@@ -34,7 +34,9 @@ def test_basic_check_missing_dependency(script: PipTestEnvironment) -> None:
install_requires=["missing==0.1"],
)
# Let's install pkga without its dependency
- res = script.pip("install", "--no-index", pkga_path, "--no-deps")
+ res = script.pip(
+ "install", "--no-build-isolation", "--no-index", pkga_path, "--no-deps"
+ )
assert "Successfully installed pkga-1.0" in res.stdout, str(res)
result = script.pip("check", expect_error=True)
@@ -53,7 +55,9 @@ def test_basic_check_broken_dependency(script: PipTestEnvironment) -> None:
install_requires=["broken>=1.0"],
)
# Let's install pkga without its dependency
- res = script.pip("install", "--no-index", pkga_path, "--no-deps")
+ res = script.pip(
+ "install", "--no-build-isolation", "--no-index", pkga_path, "--no-deps"
+ )
assert "Successfully installed pkga-1.0" in res.stdout, str(res)
# Setup broken==0.1
@@ -65,6 +69,7 @@ def test_basic_check_broken_dependency(script: PipTestEnvironment) -> None:
# Let's install broken==0.1
res = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
broken_path,
"--no-warn-conflicts",
@@ -88,7 +93,9 @@ def test_basic_check_broken_dependency_and_missing_dependency(
install_requires=["broken>=1.0"],
)
# Let's install pkga without its dependency
- res = script.pip("install", "--no-index", pkga_path, "--no-deps")
+ res = script.pip(
+ "install", "--no-build-isolation", "--no-index", pkga_path, "--no-deps"
+ )
assert "Successfully installed pkga-1.0" in res.stdout, str(res)
# Setup broken==0.1
@@ -99,7 +106,9 @@ def test_basic_check_broken_dependency_and_missing_dependency(
install_requires=["missing"],
)
# Let's install broken==0.1
- res = script.pip("install", "--no-index", broken_path, "--no-deps")
+ res = script.pip(
+ "install", "--no-build-isolation", "--no-index", broken_path, "--no-deps"
+ )
assert "Successfully installed broken-0.1" in res.stdout, str(res)
result = script.pip("check", expect_error=True)
@@ -122,7 +131,9 @@ def test_check_complicated_name_missing(script: PipTestEnvironment) -> None:
)
# Without dependency
- result = script.pip("install", "--no-index", package_a_path, "--no-deps")
+ result = script.pip(
+ "install", "--no-build-isolation", "--no-index", package_a_path, "--no-deps"
+ )
assert (
"Successfully installed package_A-1.0" in result.stdout
or "Successfully installed package-A-1.0" in result.stdout
@@ -148,7 +159,9 @@ def test_check_complicated_name_broken(script: PipTestEnvironment) -> None:
)
# With broken dependency
- result = script.pip("install", "--no-index", package_a_path, "--no-deps")
+ result = script.pip(
+ "install", "--no-build-isolation", "--no-index", package_a_path, "--no-deps"
+ )
assert (
"Successfully installed package_A-1.0" in result.stdout
or "Successfully installed package-A-1.0" in result.stdout
@@ -156,6 +169,7 @@ def test_check_complicated_name_broken(script: PipTestEnvironment) -> None:
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
dependency_b_path_incompatible,
"--no-deps",
@@ -184,7 +198,9 @@ def test_check_complicated_name_clean(script: PipTestEnvironment) -> None:
version="1.0",
)
- result = script.pip("install", "--no-index", package_a_path, "--no-deps")
+ result = script.pip(
+ "install", "--no-build-isolation", "--no-index", package_a_path, "--no-deps"
+ )
assert (
"Successfully installed package_A-1.0" in result.stdout
or "Successfully installed package-A-1.0" in result.stdout
@@ -192,6 +208,7 @@ def test_check_complicated_name_clean(script: PipTestEnvironment) -> None:
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
dependency_b_path,
"--no-deps",
@@ -215,7 +232,9 @@ def test_check_considers_conditional_reqs(script: PipTestEnvironment) -> None:
],
)
- result = script.pip("install", "--no-index", package_a_path, "--no-deps")
+ result = script.pip(
+ "install", "--no-build-isolation", "--no-index", package_a_path, "--no-deps"
+ )
assert (
"Successfully installed package_A-1.0" in result.stdout
or "Successfully installed package-A-1.0" in result.stdout
@@ -238,7 +257,9 @@ def test_check_development_versions_are_also_considered(
install_requires=["depend>=1.0"],
)
# Let's install pkga without its dependency
- res = script.pip("install", "--no-index", pkga_path, "--no-deps")
+ res = script.pip(
+ "install", "--no-build-isolation", "--no-index", pkga_path, "--no-deps"
+ )
assert "Successfully installed pkga-1.0" in res.stdout, str(res)
# Setup depend==1.1.0.dev0
@@ -250,6 +271,7 @@ def test_check_development_versions_are_also_considered(
# Let's install depend==1.1.0.dev0
res = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
depend_path,
"--no-warn-conflicts",
diff --git a/tests/functional/test_cli.py b/tests/functional/test_cli.py
index 6d2e2a12935..02429eb9a4d 100644
--- a/tests/functional/test_cli.py
+++ b/tests/functional/test_cli.py
@@ -45,7 +45,9 @@ def test_entrypoints_work(entrypoint: str, script: PipTestEnvironment) -> None:
)
# expect_temp because pip install will generate fake_pkg.egg-info
- script.pip("install", "-vvv", str(fake_pkg), expect_temp=True)
+ script.pip(
+ "install", "--no-build-isolation", "-vvv", str(fake_pkg), expect_temp=True
+ )
result = script.pip("-V")
result2 = script.run("fake_pip", "-V", allow_stderr_warning=True)
assert result.stdout == result2.stdout
diff --git a/tests/functional/test_completion.py b/tests/functional/test_completion.py
index f0396aa0c68..5d83694d50b 100644
--- a/tests/functional/test_completion.py
+++ b/tests/functional/test_completion.py
@@ -94,7 +94,7 @@ def script_with_launchers(
tmpdir = tmpdir_factory.mktemp("script_with_launchers")
script = script_factory(tmpdir.joinpath("workspace"))
# Re-install pip so we get the launchers.
- script.pip_install_local("-f", common_wheels, pip_src)
+ script.pip("install", "--no-index", "-f", common_wheels, pip_src)
return script
diff --git a/tests/functional/test_config_settings.py b/tests/functional/test_config_settings.py
index 87de5fcc4c7..d762737ea55 100644
--- a/tests/functional/test_config_settings.py
+++ b/tests/functional/test_config_settings.py
@@ -111,27 +111,6 @@ def make_project(
return name, version, project_dir
-def test_config_settings_implies_pep517(
- script: PipTestEnvironment, tmp_path: Path
-) -> None:
- """Test that setup.py bdist_wheel is not used when config settings are."""
- pkg_path = tmp_path / "pkga"
- pkg_path.mkdir()
- pkg_path.joinpath("setup.py").write_text(
- "from setuptools import setup; setup(name='pkga')\n"
- )
- result = script.pip(
- "wheel",
- "--no-build-isolation",
- "--config-settings",
- "FOO=Hello",
- pkg_path,
- cwd=tmp_path,
- )
- assert "Successfully built pkga" in result.stdout
- assert "Preparing metadata (pyproject.toml)" in result.stdout
-
-
def test_backend_sees_config(script: PipTestEnvironment) -> None:
name, version, project_dir = make_project(script.scratch_path)
script.pip(
diff --git a/tests/functional/test_download.py b/tests/functional/test_download.py
index c5887aa1bf0..3bc9a241ea4 100644
--- a/tests/functional/test_download.py
+++ b/tests/functional/test_download.py
@@ -17,7 +17,6 @@
ScriptFactory,
TestData,
TestPipResult,
- create_basic_sdist_for_package,
create_really_basic_wheel,
)
from tests.lib.server import MockServer, file_response
@@ -54,8 +53,18 @@ def test_download_wheel(script: PipTestEnvironment, data: TestData) -> None:
"""
Test using "pip download" to download a *.whl archive.
"""
+ # This test needs --no-build-isolation because `meta` depends on `simple`
+ # which is a source distribution for which it needs to prepare metadata
+ # to look for transitive dependencies.
result = script.pip(
- "download", "--no-index", "-f", data.packages, "-d", ".", "meta"
+ "download",
+ "--no-build-isolation",
+ "--no-index",
+ "-f",
+ data.packages,
+ "-d",
+ ".",
+ "meta",
)
result.did_create(Path("scratch") / "meta-1.0-py2.py3-none-any.whl")
result.did_not_create(script.site_packages / "piptestpackage")
@@ -122,7 +131,14 @@ def test_download_should_download_wheel_deps(
dep_filename = "translationstring-1.1.tar.gz"
wheel_path = "/".join((data.find_links, wheel_filename))
result = script.pip(
- "download", wheel_path, "-d", ".", "--find-links", data.find_links, "--no-index"
+ "download",
+ "--no-build-isolation",
+ wheel_path,
+ "-d",
+ ".",
+ "--find-links",
+ data.find_links,
+ "--no-index",
)
result.did_create(Path("scratch") / wheel_filename)
result.did_create(Path("scratch") / dep_filename)
@@ -687,8 +703,7 @@ def make_args(python_version: str) -> list[str]:
args = make_args("33")
result = script.pip(*args, expect_error=True)
expected_err = (
- "ERROR: Package 'mypackage' requires a different Python: "
- "3.3.0 not in '==3.2'"
+ "ERROR: Package 'mypackage' requires a different Python: 3.3.0 not in '==3.2'"
)
assert expected_err in result.stderr, f"stderr: {result.stderr}"
@@ -978,6 +993,7 @@ def test_download_prefer_binary_when_wheel_doesnt_satisfy_req(
result = script.pip(
"download",
+ "--no-build-isolation",
"--prefer-binary",
"--no-index",
"-f",
@@ -1006,6 +1022,7 @@ def test_prefer_binary_when_wheel_doesnt_satisfy_req_req_file(
result = script.pip(
"download",
+ "--no-build-isolation",
"--no-index",
"-f",
data.packages,
@@ -1023,6 +1040,7 @@ def test_download_prefer_binary_when_only_tarball_exists(
) -> None:
result = script.pip(
"download",
+ "--no-build-isolation",
"--prefer-binary",
"--no-index",
"-f",
@@ -1047,6 +1065,7 @@ def test_prefer_binary_when_only_tarball_exists_req_file(
)
result = script.pip(
"download",
+ "--no-build-isolation",
"--no-index",
"-f",
data.packages,
@@ -1078,6 +1097,7 @@ def test_download_file_url(
shared_script.pip(
"download",
+ "--no-build-isolation",
"-d",
str(download_dir),
"--no-index",
@@ -1102,7 +1122,12 @@ def test_download_file_url_existing_ok_download(
url = f"{simple_pkg.as_uri()}#sha256={sha256(downloaded_path_bytes).hexdigest()}"
shared_script.pip(
- "download", "-d", str(download_dir), url, "--disable-pip-version-check"
+ "download",
+ "--no-build-isolation",
+ "-d",
+ str(download_dir),
+ url,
+ "--disable-pip-version-check",
)
assert downloaded_path_bytes == downloaded_path.read_bytes()
@@ -1123,6 +1148,7 @@ def test_download_file_url_existing_bad_download(
result = shared_script.pip(
"download",
+ "--no-build-isolation",
"-d",
str(download_dir),
url,
@@ -1159,6 +1185,7 @@ def test_download_http_url_bad_hash(
result = shared_script.pip(
"download",
+ "--no-build-isolation",
"-d",
str(download_dir),
url,
@@ -1187,56 +1214,19 @@ def test_download_editable(
requirements_path.write_text("-e " + editable_path + "\n")
download_dir = tmpdir / "download_dir"
script.pip(
- "download", "--no-deps", "-r", str(requirements_path), "-d", str(download_dir)
+ "download",
+ "--no-build-isolation",
+ "--no-deps",
+ "-r",
+ str(requirements_path),
+ "-d",
+ str(download_dir),
)
downloads = os.listdir(download_dir)
assert len(downloads) == 1
assert downloads[0].endswith(".zip")
-def test_download_use_pep517_propagation(
- script: PipTestEnvironment, tmpdir: Path, common_wheels: Path
-) -> None:
- """
- Check that --use-pep517 applies not just to the requirements specified
- on the command line, but to their dependencies too.
- """
-
- create_basic_sdist_for_package(script, "fake_proj", "1.0", depends=["fake_dep"])
-
- # If --use-pep517 is in effect, then setup.py should be running in an isolated
- # environment that doesn't have pip in it.
- create_basic_sdist_for_package(
- script,
- "fake_dep",
- "1.0",
- setup_py_prelude=textwrap.dedent(
- """\
- try:
- import pip
- except ImportError:
- pass
- else:
- raise Exception(f"not running in isolation")
- """
- ),
- )
-
- download_dir = tmpdir / "download_dir"
- script.pip(
- "download",
- f"--dest={download_dir}",
- "--no-index",
- f"--find-links={common_wheels}",
- f"--find-links={script.scratch_path}",
- "--use-pep517",
- "fake_proj",
- )
-
- downloads = os.listdir(download_dir)
- assert len(downloads) == 2
-
-
@pytest.fixture
def download_local_html_index(
script: PipTestEnvironment,
@@ -1256,6 +1246,7 @@ def run_for_generated_index(
"""
pip_args = [
"download",
+ "--no-build-isolation",
"-d",
str(download_dir),
"-i",
@@ -1287,6 +1278,7 @@ def run_for_generated_index(
"""
pip_args = [
"download",
+ "--no-build-isolation",
"-d",
str(download_dir),
"-i",
diff --git a/tests/functional/test_freeze.py b/tests/functional/test_freeze.py
index 9883beb87fd..374c960514c 100644
--- a/tests/functional/test_freeze.py
+++ b/tests/functional/test_freeze.py
@@ -24,7 +24,6 @@
need_svn,
wheel,
)
-from tests.lib.direct_url import get_created_direct_url_path
from tests.lib.venv import VirtualEnvironment
distribute_re = re.compile("^distribute==[0-9.]+\n", re.MULTILINE)
@@ -210,7 +209,7 @@ def test_freeze_editable_not_vcs(script: PipTestEnvironment) -> None:
# Rename the .git directory so the directory is no longer recognized
# as a VCS directory.
os.rename(os.path.join(pkg_path, ".git"), os.path.join(pkg_path, ".bak"))
- script.pip("install", "-e", pkg_path)
+ script.pip("install", "--no-build-isolation", "-e", pkg_path)
result = script.pip("freeze")
# We need to apply os.path.normcase() to the path since that is what
@@ -232,7 +231,7 @@ def test_freeze_editable_git_with_no_remote(
Test an editable Git install with no remote url.
"""
pkg_path = _create_test_package(script.scratch_path)
- script.pip("install", "-e", pkg_path)
+ script.pip("install", "--no-build-isolation", "-e", pkg_path)
result = script.pip("freeze")
if not deprecated_python:
@@ -596,7 +595,7 @@ def test_freeze_nested_vcs(
os.fspath(src_path),
expect_stderr=True,
)
- script.pip("install", "-e", src_path, expect_stderr=True)
+ script.pip("install", "--no-build-isolation", "-e", src_path, expect_stderr=True)
# Check the freeze output recognizes the inner VCS.
result = script.pip("freeze", expect_stderr=True)
@@ -994,7 +993,7 @@ def test_freeze_direct_url_archive(
script: PipTestEnvironment, shared_data: TestData
) -> None:
req = "simple @ " + shared_data.packages.joinpath("simple-2.0.tar.gz").as_uri()
- script.pip("install", req)
+ script.pip("install", "--no-build-isolation", req)
result = script.pip("freeze")
assert req in result.stdout
@@ -1038,8 +1037,8 @@ def test_freeze_pep610_editable(script: PipTestEnvironment) -> None:
is correctly frozeon as editable.
"""
pkg_path = _create_test_package(script.scratch_path, name="testpkg")
- result = script.pip("install", pkg_path)
- direct_url_path = get_created_direct_url_path(result, "testpkg")
+ result = script.pip("install", "--no-build-isolation", pkg_path)
+ direct_url_path = result.get_created_direct_url_path("testpkg")
assert direct_url_path
# patch direct_url.json to simulate an editable install
with open(direct_url_path) as f:
diff --git a/tests/functional/test_install.py b/tests/functional/test_install.py
index a1bd81d31d0..3b949baa6a6 100644
--- a/tests/functional/test_install.py
+++ b/tests/functional/test_install.py
@@ -16,6 +16,7 @@
import pytest
from pip._internal.cli.status_codes import ERROR, SUCCESS
+from pip._internal.models.direct_url import DirectUrl
from pip._internal.models.index import PyPI, TestPyPI
from pip._internal.utils.misc import rmtree
from pip._internal.utils.urls import path_to_url
@@ -105,8 +106,13 @@ def test_pep518_refuses_conflicting_requires(
create_basic_wheel_for_package(script, "setuptools", "1.0")
create_basic_wheel_for_package(script, "wheel", "1.0")
project_dir = data.src.joinpath("pep518_conflicting_requires")
- result = script.pip_install_local(
- "-f", script.scratch_path, project_dir, expect_error=True
+ result = script.pip(
+ "install",
+ "--no-index",
+ "-f",
+ script.scratch_path,
+ project_dir,
+ expect_error=True,
)
assert result.returncode != 0
assert (
@@ -290,7 +296,7 @@ def test_pip_second_command_line_interface_works(
Check if ``pip`` commands behaves equally
"""
# Re-install pip so we get the launchers.
- script.pip_install_local("-f", common_wheels, pip_src)
+ script.pip("install", "--no-index", "-f", common_wheels, pip_src)
args = [f"pip{pyversion}"]
args.extend(["install", "INITools==0.2"])
args.extend(["-f", os.fspath(data.packages)])
@@ -400,7 +406,9 @@ def test_basic_install_editable_from_svn(script: PipTestEnvironment) -> None:
"""
checkout_path = _create_test_package(script.scratch_path)
repo_url = _create_svn_repo(script.scratch_path, checkout_path)
- result = script.pip("install", "-e", "svn+" + repo_url + "#egg=version-pkg")
+ result = script.pip(
+ "install", "--no-build-isolation", "-e", "svn+" + repo_url + "#egg=version-pkg"
+ )
result.assert_installed("version_pkg", with_files=[".svn"])
@@ -409,6 +417,7 @@ def _test_install_editable_from_git(script: PipTestEnvironment) -> None:
pkg_path = _create_test_package(script.scratch_path, name="testpackage", vcs="git")
args = [
"install",
+ "--no-build-isolation",
"-e",
f"git+{pkg_path.as_uri()}#egg=testpackage",
]
@@ -437,7 +446,9 @@ def test_install_editable_uninstalls_existing(
to_install = data.packages.joinpath("pip_test_package-0.1.tar.gz")
result = script.pip_install_local(to_install)
assert "Successfully installed pip-test-package" in result.stdout
- result.assert_installed("piptestpackage", editable=False)
+ result.assert_installed(
+ "piptestpackage", dist_name="pip-test-package", editable=False
+ )
result = script.pip(
"install",
@@ -449,7 +460,9 @@ def test_install_editable_uninstalls_existing(
)
),
)
- result.assert_installed("pip-test-package", with_files=[".git"])
+ result.assert_installed(
+ "piptestpackage", dist_name="pip-test-package", with_files=[".git"]
+ )
assert "Found existing installation: pip-test-package 0.1" in result.stdout
assert "Uninstalling pip-test-package-" in result.stdout
assert "Successfully uninstalled pip-test-package" in result.stdout
@@ -469,13 +482,8 @@ def test_install_editable_uninstalls_existing_from_path(
result.assert_installed("simplewheel", editable=False)
result.did_create(simple_folder)
- result = script.pip(
- "install",
- "-e",
- to_install,
- )
- install_path = script.site_packages / "simplewheel.egg-link"
- result.did_create(install_path)
+ result = script.pip_install_local("-e", to_install)
+ script.assert_installed_editable("simplewheel")
assert "Found existing installation: simplewheel 1.0" in result.stdout
assert "Uninstalling simplewheel-" in result.stdout
assert "Successfully uninstalled simplewheel" in result.stdout
@@ -488,7 +496,7 @@ def test_basic_install_editable_from_hg(script: PipTestEnvironment) -> None:
pkg_path = _create_test_package(script.scratch_path, name="testpackage", vcs="hg")
url = f"hg+{pkg_path.as_uri()}#egg=testpackage"
assert url.startswith("hg+file")
- args = ["install", "-e", url]
+ args = ["install", "--no-build-isolation", "-e", url]
result = script.pip(*args)
result.assert_installed("testpackage", with_files=[".hg"])
@@ -501,6 +509,7 @@ def test_vcs_url_final_slash_normalization(script: PipTestEnvironment) -> None:
pkg_path = _create_test_package(script.scratch_path, name="testpackage", vcs="hg")
args = [
"install",
+ "--no-build-isolation",
"-e",
f"hg+{pkg_path.as_uri()}/#egg=testpackage",
]
@@ -516,6 +525,7 @@ def test_install_editable_from_bazaar(script: PipTestEnvironment) -> None:
)
args = [
"install",
+ "--no-build-isolation",
"-e",
f"bzr+{pkg_path.as_uri()}/#egg=testpackage",
]
@@ -531,7 +541,7 @@ def test_vcs_url_urlquote_normalization(script: PipTestEnvironment) -> None:
script.scratch_path, name="django_wikiapp", vcs="git"
)
url = f"git+{pkg_path.as_uri().replace('django_', 'django%5F')}/#egg=django_wikiapp"
- script.pip("install", "-e", url)
+ script.pip("install", "--no-build-isolation", "-e", url)
@pytest.mark.parametrize("resolver", ["", "--use-deprecated=legacy-resolver"])
@@ -541,7 +551,7 @@ def test_basic_install_from_local_directory(
"""
Test installing from a local directory.
"""
- args = ["install"]
+ args = ["install", "--no-build-isolation"]
if resolver:
args.append(resolver)
to_install = data.packages.joinpath("FSPkg")
@@ -571,7 +581,6 @@ def test_basic_install_relative_directory(
Test installing a requirement using a relative path.
"""
dist_info_folder = script.site_packages / "fspkg-0.1.dev0.dist-info"
- egg_link_file = script.site_packages / "FSPkg.egg-link"
package_folder = script.site_packages / "fspkg"
# Compute relative install path to FSPkg from scratch path.
@@ -589,13 +598,19 @@ def test_basic_install_relative_directory(
# Install as either editable or not.
if not editable:
- result = script.pip("install", req_path, cwd=script.scratch_path)
+ result = script.pip(
+ "install", "--no-build-isolation", req_path, cwd=script.scratch_path
+ )
result.did_create(dist_info_folder)
result.did_create(package_folder)
else:
# Editable install.
- result = script.pip("install", "-e", req_path, cwd=script.scratch_path)
- result.did_create(egg_link_file)
+ result = script.pip(
+ "install", "--no-build-isolation", "-e", req_path, cwd=script.scratch_path
+ )
+ direct_url = result.get_created_direct_url("fspkg")
+ assert direct_url
+ assert direct_url.is_local_editable()
def test_install_quiet(script: PipTestEnvironment, data: TestData) -> None:
@@ -607,7 +622,7 @@ def test_install_quiet(script: PipTestEnvironment, data: TestData) -> None:
# https://github.com/pypa/pip/issues/3418
# https://github.com/docker-library/python/issues/83
to_install = data.packages.joinpath("FSPkg")
- result = script.pip("install", "-qqq", to_install)
+ result = script.pip("install", "--no-build-isolation", "-qqq", to_install)
assert result.stdout == ""
assert result.stderr == ""
@@ -789,12 +804,12 @@ def test_hashed_install_from_cache(
tmpdir,
) as reqs_file:
result = script.pip_install_local(
- "--use-pep517", "--no-build-isolation", "-r", reqs_file.resolve()
+ "--no-build-isolation", "-r", reqs_file.resolve()
)
assert "Created wheel for simple2" in result.stdout
script.pip("uninstall", "simple2", "-y")
result = script.pip_install_local(
- "--use-pep517", "--no-build-isolation", "-r", reqs_file.resolve()
+ "--no-build-isolation", "-r", reqs_file.resolve()
)
assert "Using cached simple2" in result.stdout
# now try with an invalid hash
@@ -804,7 +819,6 @@ def test_hashed_install_from_cache(
) as reqs_file:
script.pip("uninstall", "simple2", "-y")
result = script.pip_install_local(
- "--use-pep517",
"--no-build-isolation",
"-r",
reqs_file.resolve(),
@@ -862,7 +876,7 @@ def test_install_from_local_directory_with_in_tree_build(
in_tree_build_dir = to_install / "build"
assert not in_tree_build_dir.exists()
- result = script.pip("install", to_install)
+ result = script.pip("install", "--no-build-isolation", to_install)
fspkg_folder = script.site_packages / "fspkg"
dist_info_folder = script.site_packages / "fspkg-0.1.dev0.dist-info"
result.did_create(fspkg_folder)
@@ -895,41 +909,6 @@ def test_editable_install__local_dir_no_setup_py(
)
-@pytest.mark.skipif(
- sys.version_info >= (3, 12),
- reason="Setuptools<64 does not support Python 3.12+",
-)
-@pytest.mark.network
-def test_editable_install_legacy__local_dir_no_setup_py_with_pyproject(
- script: PipTestEnvironment,
-) -> None:
- """
- Test installing in legacy editable mode from a local directory with no
- setup.py but that does have pyproject.toml with a build backend that does
- not support the build_editable hook.
- """
- local_dir = script.scratch_path.joinpath("temp")
- local_dir.mkdir()
- pyproject_path = local_dir.joinpath("pyproject.toml")
- pyproject_path.write_text(
- textwrap.dedent(
- """
- [build-system]
- requires = ["setuptools<64"]
- build-backend = "setuptools.build_meta"
- """
- )
- )
-
- result = script.pip("install", "-e", local_dir, expect_error=True)
- assert not result.files_created
-
- msg = result.stderr
- assert "has a 'pyproject.toml'" in msg
- assert "does not have a 'setup.py' nor a 'setup.cfg'" in msg
- assert "cannot be installed in editable mode" in msg
-
-
def test_editable_install__local_dir_setup_requires_with_pyproject(
script: PipTestEnvironment, shared_data: TestData
) -> None:
@@ -1016,7 +995,7 @@ def test_install_curdir(script: PipTestEnvironment, data: TestData) -> None:
egg_info = join(run_from, "FSPkg.egg-info")
if os.path.isdir(egg_info):
rmtree(egg_info)
- result = script.pip("install", curdir, cwd=run_from)
+ result = script.pip("install", "--no-build-isolation", curdir, cwd=run_from)
fspkg_folder = script.site_packages / "fspkg"
dist_info_folder = script.site_packages / "fspkg-0.1.dev0.dist-info"
result.did_create(fspkg_folder)
@@ -1028,31 +1007,13 @@ def test_install_pardir(script: PipTestEnvironment, data: TestData) -> None:
Test installing parent directory ('..').
"""
run_from = data.packages.joinpath("FSPkg", "fspkg")
- result = script.pip("install", pardir, cwd=run_from)
+ result = script.pip("install", "--no-build-isolation", pardir, cwd=run_from)
fspkg_folder = script.site_packages / "fspkg"
dist_info_folder = script.site_packages / "fspkg-0.1.dev0.dist-info"
result.did_create(fspkg_folder)
result.did_create(dist_info_folder)
-@pytest.mark.network
-def test_install_global_option(script: PipTestEnvironment) -> None:
- """
- Test using global distutils options.
- (In particular those that disable the actual install action)
- """
- result = script.pip(
- "install",
- "--global-option=--version",
- "INITools==0.1",
- expect_error=True, # build is going to fail because of --version
- )
- assert "INITools==0.1\n" in result.stdout
- assert not result.files_created
- assert "Implying --no-binary=:all:" in result.stderr
- assert "A possible replacement is to use --config-settings" in result.stderr
-
-
def test_install_with_hacked_egg_info(
script: PipTestEnvironment, data: TestData
) -> None:
@@ -1060,30 +1021,10 @@ def test_install_with_hacked_egg_info(
test installing a package which defines its own egg_info class
"""
run_from = data.packages.joinpath("HackedEggInfo")
- result = script.pip("install", ".", cwd=run_from)
+ result = script.pip("install", "--no-build-isolation", ".", cwd=run_from)
assert "Successfully installed hackedegginfo-0.0.0\n" in result.stdout
-@pytest.mark.xfail
-@pytest.mark.network
-@need_mercurial
-def test_install_global_option_using_editable(
- script: PipTestEnvironment, tmpdir: Path
-) -> None:
- """
- Test using global distutils options, but in an editable installation
- """
- url = "hg+http://bitbucket.org/runeh/anyjson"
- result = script.pip(
- "install",
- "--global-option=--version",
- "-e",
- f"{local_checkout(url, tmpdir)}@0.2.5#egg=anyjson",
- expect_stderr=True,
- )
- assert "Successfully installed anyjson" in result.stdout
-
-
@pytest.mark.network
def test_install_package_with_same_name_in_curdir(script: PipTestEnvironment) -> None:
"""
@@ -1110,7 +1051,7 @@ def test_install_folder_using_dot_slash(script: PipTestEnvironment) -> None:
script.scratch_path.joinpath("mock").mkdir()
pkg_path = script.scratch_path / "mock"
pkg_path.joinpath("setup.py").write_text(mock100_setup_py)
- result = script.pip("install", "./mock")
+ result = script.pip("install", "--no-build-isolation", "./mock")
dist_info_folder = script.site_packages / "mock-100.1.dist-info"
result.did_create(dist_info_folder)
@@ -1122,7 +1063,7 @@ def test_install_folder_using_slash_in_the_end(script: PipTestEnvironment) -> No
script.scratch_path.joinpath("mock").mkdir()
pkg_path = script.scratch_path / "mock"
pkg_path.joinpath("setup.py").write_text(mock100_setup_py)
- result = script.pip("install", "mock" + os.path.sep)
+ result = script.pip("install", "--no-build-isolation", "mock" + os.path.sep)
dist_info_folder = script.site_packages / "mock-100.1.dist-info"
result.did_create(dist_info_folder)
@@ -1135,7 +1076,7 @@ def test_install_folder_using_relative_path(script: PipTestEnvironment) -> None:
script.scratch_path.joinpath("initools", "mock").mkdir()
pkg_path = script.scratch_path / "initools" / "mock"
pkg_path.joinpath("setup.py").write_text(mock100_setup_py)
- result = script.pip("install", Path("initools") / "mock")
+ result = script.pip("install", "--no-build-isolation", Path("initools") / "mock")
dist_info_folder = script.site_packages / "mock-100.1.dist-info"
result.did_create(dist_info_folder)
@@ -1315,7 +1256,7 @@ def main(): pass
"""
)
)
- result = script.pip("install", opt, target_dir, pkga_path)
+ result = script.pip("install", "--no-build-isolation", opt, target_dir, pkga_path)
# This assertion isn't actually needed, if we get the script warning
# the script.pip() call will fail with "stderr not expected". But we
# leave the assertion to make the intention of the code clearer.
@@ -1329,6 +1270,7 @@ def test_install_package_with_root(script: PipTestEnvironment, data: TestData) -
root_dir = script.scratch_path / "root"
result = script.pip(
"install",
+ "--no-build-isolation",
"--root",
root_dir,
"-f",
@@ -1360,6 +1302,7 @@ def test_install_package_with_prefix(
prefix_path = script.scratch_path / "prefix"
result = script.pip(
"install",
+ "--no-build-isolation",
"--prefix",
prefix_path,
"-f",
@@ -1402,10 +1345,19 @@ def _test_install_editable_with_prefix(
# install pkga package into the absolute prefix directory
prefix_path = script.scratch_path / "prefix"
- result = script.pip("install", "--editable", pkga_path, "--prefix", prefix_path)
+ result = script.pip(
+ "install",
+ "--no-build-isolation",
+ "--editable",
+ pkga_path,
+ "--prefix",
+ prefix_path,
+ )
# assert pkga is installed at correct location
- install_path = script.scratch / site_packages / "pkga.egg-link"
+ install_path = (
+ script.scratch / site_packages / "pkga-0.1.dist-info" / "direct_url.json"
+ )
result.did_create(install_path)
return result
@@ -1431,7 +1383,11 @@ def test_install_editable_with_target(script: PipTestEnvironment) -> None:
target.mkdir()
result = script.pip("install", "--editable", pkg_path, "--target", target)
- result.did_create(script.scratch / "target" / "pkg.egg-link")
+ direct_url_path = result.get_created_direct_url_path("pkg")
+ assert direct_url_path
+ assert direct_url_path.parent.parent == target
+ direct_url = DirectUrl.from_json(direct_url_path.read_text())
+ assert direct_url.is_local_editable()
result.did_create(script.scratch / "target" / "watching_testrunner.py")
@@ -1443,28 +1399,6 @@ def test_install_editable_with_prefix_setup_py(script: PipTestEnvironment) -> No
_test_install_editable_with_prefix(script, {"setup.py": setup_py})
-@pytest.mark.skipif(
- sys.version_info >= (3, 12),
- reason="Setuptools<64 does not support Python 3.12+",
-)
-@pytest.mark.network
-def test_install_editable_legacy_with_prefix_setup_cfg(
- script: PipTestEnvironment,
-) -> None:
- setup_cfg = """[metadata]
-name = pkga
-version = 0.1
-"""
- pyproject_toml = """[build-system]
-requires = ["setuptools<64", "wheel"]
-build-backend = "setuptools.build_meta"
-"""
- result = _test_install_editable_with_prefix(
- script, {"setup.cfg": setup_cfg, "pyproject.toml": pyproject_toml}
- )
- assert "(setup.py develop) is deprecated" in result.stderr
-
-
def test_install_package_conflict_prefix_and_user(
script: PipTestEnvironment, data: TestData
) -> None:
@@ -1498,6 +1432,7 @@ def test_install_package_that_emits_unicode(
to_install = data.packages.joinpath("BrokenEmitsUTF8")
result = script.pip(
"install",
+ "--no-build-isolation",
to_install,
expect_error=True,
expect_temp=True,
@@ -1515,7 +1450,7 @@ def test_install_package_with_utf8_setup(
) -> None:
"""Install a package with a setup.py that declares a utf-8 encoding."""
to_install = data.packages.joinpath("SetupPyUTF8")
- script.pip("install", to_install)
+ script.pip("install", "--no-build-isolation", to_install)
def test_install_package_with_latin1_setup(
@@ -1523,7 +1458,7 @@ def test_install_package_with_latin1_setup(
) -> None:
"""Install a package with a setup.py that declares a latin-1 encoding."""
to_install = data.packages.joinpath("SetupPyLatin1")
- script.pip("install", to_install)
+ script.pip("install", "--no-build-isolation", to_install)
def test_url_req_case_mismatch_no_index(
@@ -1539,7 +1474,13 @@ def test_url_req_case_mismatch_no_index(
"""
Upper = "/".join((data.find_links, "Upper-1.0.tar.gz"))
result = script.pip(
- "install", "--no-index", "-f", data.find_links, Upper, "requiresupper"
+ "install",
+ "--no-build-isolation",
+ "--no-index",
+ "-f",
+ data.find_links,
+ Upper,
+ "requiresupper",
)
# only Upper-1.0.tar.gz should get installed.
@@ -1568,7 +1509,12 @@ def test_url_req_case_mismatch_file_index(
"""
Dinner = "/".join((data.find_links3, "dinner", "Dinner-1.0.tar.gz"))
result = script.pip(
- "install", "--index-url", data.find_links3, Dinner, "requiredinner"
+ "install",
+ "--no-build-isolation",
+ "--index-url",
+ data.find_links3,
+ Dinner,
+ "requiredinner",
)
# only Dinner-1.0.tar.gz should get installed.
@@ -1588,6 +1534,7 @@ def test_url_incorrect_case_no_index(
"""
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -1611,6 +1558,7 @@ def test_url_incorrect_case_file_index(
"""
result = script.pip(
"install",
+ "--no-build-isolation",
"--index-url",
data.find_links3,
"dinner",
@@ -1678,7 +1626,7 @@ def test_install_upgrade_editable_depending_on_other_editable(
"""
)
)
- script.pip("install", "--editable", pkga_path)
+ script.pip("install", "--no-build-isolation", "--editable", pkga_path)
result = script.pip("list", "--format=freeze")
assert "pkga==0.1" in result.stdout
@@ -1694,7 +1642,14 @@ def test_install_upgrade_editable_depending_on_other_editable(
"""
)
)
- script.pip("install", "--upgrade", "--editable", pkgb_path, "--no-index")
+ script.pip(
+ "install",
+ "--no-build-isolation",
+ "--upgrade",
+ "--editable",
+ pkgb_path,
+ "--no-index",
+ )
result = script.pip("list", "--format=freeze")
assert "pkgb==0.1" in result.stdout
@@ -1702,7 +1657,12 @@ def test_install_upgrade_editable_depending_on_other_editable(
def test_install_subprocess_output_handling(
script: PipTestEnvironment, data: TestData
) -> None:
- args = ["install", os.fspath(data.src.joinpath("chattymodule"))]
+ args = [
+ "install",
+ "--no-build-isolation",
+ "--no-cache",
+ os.fspath(data.src.joinpath("chattymodule")),
+ ]
# Regular install should not show output from the chatty setup.py
result = script.pip(*args)
@@ -1713,48 +1673,56 @@ def test_install_subprocess_output_handling(
# Only count examples with sys.argv[1] == egg_info, because we call
# setup.py multiple times, which should not count as duplicate output.
result = script.pip(*(args + ["--verbose"]), expect_stderr=True)
- assert 1 == result.stderr.count("HELLO FROM CHATTYMODULE egg_info")
+ assert 1 == result.stderr.count(
+ "HELLO FROM CHATTYMODULE prepare_metadata_for_build_wheel"
+ )
+ assert 1 == result.stderr.count("HELLO FROM CHATTYMODULE build_wheel")
script.pip("uninstall", "-y", "chattymodule")
# If the install fails, then we *should* show the output... but only once,
# even if --verbose is given.
- result = script.pip(*(args + ["--global-option=--fail"]), expect_error=True)
- # This error is emitted 3 times:
- # - by setup.py bdist_wheel
- # - by setup.py clean
- assert 2 == result.stderr.count("I DIE, I DIE")
+ result = script.pip(*(args + ["--config-setting=fail=1"]), expect_error=True)
+ assert 1 == result.stderr.count("I DIE, I DIE")
+ assert 1 == result.stderr.count("I DIE, I DIE in prepare_metadata_for_build_wheel")
result = script.pip(
- *(args + ["--global-option=--fail", "--verbose"]), expect_error=True
+ *(args + ["--config-setting=fail=1", "--verbose"]), expect_error=True
)
- assert 2 == result.stderr.count("I DIE, I DIE")
+ assert 1 == result.stderr.count("I DIE, I DIE")
+ assert 1 == result.stderr.count("I DIE, I DIE in prepare_metadata_for_build_wheel")
def test_install_log(script: PipTestEnvironment, data: TestData, tmpdir: Path) -> None:
# test that verbose logs go to "--log" file
f = tmpdir.joinpath("log.txt")
- result = script.pip(f"--log={f}", "install", data.src.joinpath("chattymodule"))
+ result = script.pip(
+ f"--log={f}",
+ "install",
+ "--no-build-isolation",
+ data.src.joinpath("chattymodule"),
+ )
assert 0 == result.stdout.count("HELLO FROM CHATTYMODULE")
with open(f) as fp:
- # one from egg_info, one from install
+ # one from prepare_metadata_for_build_wheel, one from build_wheel
assert 2 == fp.read().count("HELLO FROM CHATTYMODULE")
def test_install_topological_sort(script: PipTestEnvironment, data: TestData) -> None:
- res = str(script.pip("install", "TopoRequires4", "--no-index", "-f", data.packages))
+ res = str(
+ script.pip(
+ "install",
+ "--no-build-isolation",
+ "TopoRequires4",
+ "--no-index",
+ "-f",
+ data.packages,
+ )
+ )
order1 = "TopoRequires, TopoRequires2, TopoRequires3, TopoRequires4"
order2 = "TopoRequires, TopoRequires3, TopoRequires2, TopoRequires4"
assert order1 in res or order2 in res, res
-def test_cleanup_after_failed_wheel(script: PipTestEnvironment) -> None:
- res = script.pip_install_local("wheelbrokenafter", expect_error=True)
- assert "ERROR: Failed building wheel for wheelbrokenafter" in res.stderr
- # OK, assert that we *said* we were cleaning up:
- # /!\ if in need to change this, also change test_pep517_no_legacy_cleanup
- assert "Running setup.py clean for wheelbrokenafter" in str(res), str(res)
-
-
def test_install_builds_wheels(script: PipTestEnvironment, data: TestData) -> None:
# We need to use a subprocess to get the right value on Windows.
res = script.run(
@@ -1772,6 +1740,7 @@ def test_install_builds_wheels(script: PipTestEnvironment, data: TestData) -> No
to_install = data.packages.joinpath("requires_wheelbroken_upper")
res = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -1801,6 +1770,7 @@ def test_install_no_binary_builds_wheels(
to_install = data.packages.joinpath("requires_wheelbroken_upper")
res = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"--no-binary=upper",
"-f",
@@ -1847,10 +1817,13 @@ def test_install_no_binary_uses_cached_wheels(
script: PipTestEnvironment, data: TestData
) -> None:
# Seed the cache
- script.pip("install", "--no-index", "-f", data.find_links, "upper")
+ script.pip(
+ "install", "--no-build-isolation", "--no-index", "-f", data.find_links, "upper"
+ )
script.pip("uninstall", "upper", "-y")
res = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"--no-binary=:all:",
"-f",
@@ -1879,6 +1852,7 @@ def test_install_editable_with_wrong_egg_name(
)
result = script.pip(
"install",
+ "--no-build-isolation",
"--editable",
path_to_url(str(pkga_path)) + "#egg=pkgb",
expect_error=(resolver_variant == "resolvelib"),
@@ -1899,7 +1873,9 @@ def test_install_tar_xz(script: PipTestEnvironment, data: TestData) -> None:
import lzma # noqa
except ImportError:
pytest.skip("No lzma support")
- res = script.pip("install", data.packages / "singlemodule-0.0.1.tar.xz")
+ res = script.pip(
+ "install", "--no-build-isolation", data.packages / "singlemodule-0.0.1.tar.xz"
+ )
assert "Successfully installed singlemodule-0.0.1" in res.stdout, res
@@ -1908,7 +1884,9 @@ def test_install_tar_lzma(script: PipTestEnvironment, data: TestData) -> None:
import lzma # noqa
except ImportError:
pytest.skip("No lzma support")
- res = script.pip("install", data.packages / "singlemodule-0.0.1.tar.lzma")
+ res = script.pip(
+ "install", "--no-build-isolation", data.packages / "singlemodule-0.0.1.tar.lzma"
+ )
assert "Successfully installed singlemodule-0.0.1" in res.stdout, res
@@ -1959,7 +1937,7 @@ def test_install_incompatible_python_requires(script: PipTestEnvironment) -> Non
"""
)
)
- result = script.pip("install", pkga_path, expect_error=True)
+ result = script.pip("install", "--no-build-isolation", pkga_path, expect_error=True)
assert _get_expected_error_text() in result.stderr, str(result)
@@ -1978,7 +1956,9 @@ def test_install_incompatible_python_requires_editable(
"""
)
)
- result = script.pip("install", f"--editable={pkga_path}", expect_error=True)
+ result = script.pip(
+ "install", "--no-build-isolation", f"--editable={pkga_path}", expect_error=True
+ )
assert _get_expected_error_text() in result.stderr, str(result)
@@ -2021,7 +2001,7 @@ def test_install_compatible_python_requires(script: PipTestEnvironment) -> None:
"""
)
)
- res = script.pip("install", pkga_path)
+ res = script.pip("install", "--no-build-isolation", pkga_path)
assert "Successfully installed pkga-0.1" in res.stdout, res
@@ -2064,6 +2044,7 @@ def test_install_from_test_pypi_with_ext_url_dep_is_blocked(
) -> None:
res = script.pip(
"install",
+ "--no-build-isolation",
"--index-url",
index,
"pep-508-url-deps",
@@ -2127,12 +2108,15 @@ def test_install_conflict_results_in_warning(
)
# Install pkgA without its dependency
- result1 = script.pip("install", "--no-index", pkgA_path, "--no-deps")
+ result1 = script.pip(
+ "install", "--no-build-isolation", "--no-index", pkgA_path, "--no-deps"
+ )
assert "Successfully installed pkgA-1.0" in result1.stdout, str(result1)
# Then install an incorrect version of the dependency
result2 = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
pkgB_path,
allow_stderr_error=True,
@@ -2157,11 +2141,19 @@ def test_install_conflict_warning_can_be_suppressed(
)
# Install pkgA without its dependency
- result1 = script.pip("install", "--no-index", pkgA_path, "--no-deps")
+ result1 = script.pip(
+ "install", "--no-build-isolation", "--no-index", pkgA_path, "--no-deps"
+ )
assert "Successfully installed pkgA-1.0" in result1.stdout, str(result1)
# Then install an incorrect version of the dependency; suppressing warning
- result2 = script.pip("install", "--no-index", pkgB_path, "--no-warn-conflicts")
+ result2 = script.pip(
+ "install",
+ "--no-build-isolation",
+ "--no-index",
+ pkgB_path,
+ "--no-warn-conflicts",
+ )
assert "Successfully installed pkgB-2.0" in result2.stdout, str(result2)
@@ -2237,6 +2229,7 @@ def test_ignore_yanked_file(script: PipTestEnvironment, data: TestData) -> None:
result = script.pip(
"install",
"simple",
+ "--no-build-isolation",
"--index-url",
data.index_url("yanked"),
)
@@ -2272,7 +2265,13 @@ def test_valid_index_url_argument(
Test the behaviour of an valid --index-url argument
"""
- result = script.pip("install", "--index-url", shared_data.find_links3, "Dinner")
+ result = script.pip(
+ "install",
+ "--no-build-isolation",
+ "--index-url",
+ shared_data.find_links3,
+ "Dinner",
+ )
assert "Successfully installed Dinner" in result.stdout, str(result)
@@ -2289,6 +2288,7 @@ def test_install_yanked_file_and_print_warning(
result = script.pip(
"install",
"simple==3.0",
+ "--no-build-isolation",
"--index-url",
data.index_url("yanked"),
expect_stderr=True,
@@ -2377,7 +2377,15 @@ def test_install_sends_client_cert(
url = f"https://{server.host}:{server.port}/simple"
- args = ["install", "-vvv", "--cert", cert_path, "--client-cert", cert_path]
+ args = [
+ "install",
+ "--no-build-isolation",
+ "-vvv",
+ "--cert",
+ cert_path,
+ "--client-cert",
+ cert_path,
+ ]
args.extend(["--index-url", url])
args.extend(install_args)
args.append("simple")
@@ -2469,7 +2477,9 @@ def test_install_verify_package_name_normalization(
pkg_path = create_test_package_with_setup(
script, name="simple-package", version="1.0"
)
- result = script.pip("install", "-e", ".", expect_stderr=True, cwd=pkg_path)
+ result = script.pip(
+ "install", "--no-build-isolation", "-e", ".", expect_stderr=True, cwd=pkg_path
+ )
assert "Successfully installed simple-package" in result.stdout
result = script.pip("install", package_name)
@@ -2480,7 +2490,7 @@ def test_install_logs_pip_version_in_debug(
script: PipTestEnvironment, shared_data: TestData
) -> None:
fake_package = shared_data.packages / "simple-2.0.tar.gz"
- result = script.pip("install", "-v", fake_package)
+ result = script.pip("install", "--no-build-isolation", "-v", fake_package)
pattern = "Using pip .* from .*"
assert_re_match(pattern, result.stdout)
@@ -2504,6 +2514,7 @@ def install_find_links(
else ()
),
*(("--dry-run",) if dry_run else ()),
+ "--no-build-isolation",
"--no-index",
"--find-links",
data.find_links,
diff --git a/tests/functional/test_install_check.py b/tests/functional/test_install_check.py
index a0598fe2703..cb8312b535d 100644
--- a/tests/functional/test_install_check.py
+++ b/tests/functional/test_install_check.py
@@ -27,13 +27,16 @@ def test_check_install_canonicalization(script: PipTestEnvironment) -> None:
)
# Let's install pkgA without its dependency
- result = script.pip("install", "--no-index", pkga_path, "--no-deps")
+ result = script.pip(
+ "install", "--no-build-isolation", "--no-index", pkga_path, "--no-deps"
+ )
assert "Successfully installed pkgA-1.0" in result.stdout, str(result)
# Install the first missing dependency. Only an error for the
# second dependency should remain.
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
normal_path,
"--quiet",
@@ -51,6 +54,7 @@ def test_check_install_canonicalization(script: PipTestEnvironment) -> None:
# name normalization (as in https://github.com/pypa/pip/issues/5134)
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
special_path,
"--quiet",
@@ -88,12 +92,15 @@ def test_check_install_does_not_warn_for_out_of_graph_issues(
)
# Install a package without it's dependencies
- result = script.pip("install", "--no-index", pkg_broken_path, "--no-deps")
+ result = script.pip(
+ "install", "--no-build-isolation", "--no-index", pkg_broken_path, "--no-deps"
+ )
assert "requires" not in result.stderr
# Install conflict package
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
pkg_conflict_path,
allow_stderr_error=True,
@@ -110,6 +117,7 @@ def test_check_install_does_not_warn_for_out_of_graph_issues(
# Install unrelated package
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
pkg_unrelated_path,
"--quiet",
diff --git a/tests/functional/test_install_cleanup.py b/tests/functional/test_install_cleanup.py
index bc34defc978..457657073c4 100644
--- a/tests/functional/test_install_cleanup.py
+++ b/tests/functional/test_install_cleanup.py
@@ -28,16 +28,3 @@ def test_no_clean_option_blocks_cleaning_after_install(
allow_stderr_warning=True,
)
assert exists(build)
-
-
-@pytest.mark.network
-def test_pep517_no_legacy_cleanup(script: PipTestEnvironment, data: TestData) -> None:
- """Test a PEP 517 failed build does not attempt a legacy cleanup"""
- to_install = data.packages.joinpath("pep517_wrapper_buildsys")
- script.environ["PIP_TEST_FAIL_BUILD_WHEEL"] = "1"
- res = script.pip("install", "-f", data.find_links, to_install, expect_error=True)
- # Must not have built the package
- expected = "Failed building wheel for pep517-wrapper-buildsys"
- assert expected in str(res)
- # Must not have attempted legacy cleanup
- assert "setup.py clean" not in str(res)
diff --git a/tests/functional/test_install_compat.py b/tests/functional/test_install_compat.py
index 47ba41bdf9e..c0ba64c25d7 100644
--- a/tests/functional/test_install_compat.py
+++ b/tests/functional/test_install_compat.py
@@ -73,4 +73,4 @@ def test_setup_py_with_dos_line_endings(
Refs https://github.com/pypa/pip/issues/237
"""
to_install = data.packages.joinpath("LineEndings")
- script.pip("install", to_install)
+ script.pip("install", "--no-build-isolation", to_install)
diff --git a/tests/functional/test_install_config.py b/tests/functional/test_install_config.py
index baee7e80d55..678e51822c1 100644
--- a/tests/functional/test_install_config.py
+++ b/tests/functional/test_install_config.py
@@ -199,6 +199,7 @@ def test_config_file_override_stack(
script.pip("install", "-vvv", "INITools", expect_error=True)
script.pip(
"install",
+ "--no-build-isolation",
"-vvv",
"--index-url",
f"{base_address}/simple3",
@@ -250,7 +251,13 @@ def test_install_no_binary_via_config_disables_cached_wheels(
)
config_file.close()
res = script.pip(
- "install", "--no-index", "-f", data.find_links, "upper", expect_stderr=True
+ "install",
+ "--no-build-isolation",
+ "--no-index",
+ "-f",
+ data.find_links,
+ "upper",
+ expect_stderr=True,
)
finally:
os.unlink(config_file.name)
@@ -520,6 +527,7 @@ def set_password(self, url, username):
with server_running(server):
result = script.pip(
"install",
+ "--no-build-isolation",
"--index-url",
url,
"--cert",
diff --git a/tests/functional/test_install_direct_url.py b/tests/functional/test_install_direct_url.py
index 5aefab09cb3..f67a8615b21 100644
--- a/tests/functional/test_install_direct_url.py
+++ b/tests/functional/test_install_direct_url.py
@@ -3,29 +3,19 @@
from pip._internal.models.direct_url import VcsInfo
from tests.lib import PipTestEnvironment, TestData, _create_test_package
-from tests.lib.direct_url import get_created_direct_url
def test_install_find_links_no_direct_url(script: PipTestEnvironment) -> None:
result = script.pip_install_local("simple")
- assert not get_created_direct_url(result, "simple")
-
-
-def test_install_vcs_editable_no_direct_url(script: PipTestEnvironment) -> None:
- pkg_path = _create_test_package(script.scratch_path, name="testpkg")
- args = ["install", "-e", f"git+{pkg_path.as_uri()}#egg=testpkg"]
- result = script.pip(*args)
- # legacy editable installs do not generate .dist-info,
- # hence no direct_url.json
- assert not get_created_direct_url(result, "testpkg")
+ assert not result.get_created_direct_url("simple")
def test_install_vcs_non_editable_direct_url(script: PipTestEnvironment) -> None:
pkg_path = _create_test_package(script.scratch_path, name="testpkg")
url = pkg_path.as_uri()
- args = ["install", f"git+{url}#egg=testpkg"]
+ args = ["install", "--no-build-isolation", f"git+{url}#egg=testpkg"]
result = script.pip(*args)
- direct_url = get_created_direct_url(result, "testpkg")
+ direct_url = result.get_created_direct_url("testpkg")
assert direct_url
assert direct_url.url == url
assert isinstance(direct_url.info, VcsInfo)
@@ -35,8 +25,8 @@ def test_install_vcs_non_editable_direct_url(script: PipTestEnvironment) -> None
def test_install_archive_direct_url(script: PipTestEnvironment, data: TestData) -> None:
req = "simple @ " + data.packages.joinpath("simple-2.0.tar.gz").as_uri()
assert req.startswith("simple @ file://")
- result = script.pip("install", req)
- assert get_created_direct_url(result, "simple")
+ result = script.pip("install", "--no-build-isolation", req)
+ assert result.get_created_direct_url("simple")
@pytest.mark.network
@@ -48,7 +38,7 @@ def test_install_vcs_constraint_direct_url(script: PipTestEnvironment) -> None:
"#egg=pip-test-package"
)
result = script.pip("install", "pip-test-package", "-c", constraints_file)
- assert get_created_direct_url(result, "pip_test_package")
+ assert result.get_created_direct_url("pip_test_package")
def test_install_vcs_constraint_direct_file_url(script: PipTestEnvironment) -> None:
@@ -56,5 +46,7 @@ def test_install_vcs_constraint_direct_file_url(script: PipTestEnvironment) -> N
url = pkg_path.as_uri()
constraints_file = script.scratch_path / "constraints.txt"
constraints_file.write_text(f"git+{url}#egg=testpkg")
- result = script.pip("install", "testpkg", "-c", constraints_file)
- assert get_created_direct_url(result, "testpkg")
+ result = script.pip(
+ "install", "--no-build-isolation", "testpkg", "-c", constraints_file
+ )
+ assert result.get_created_direct_url("testpkg")
diff --git a/tests/functional/test_install_extras.py b/tests/functional/test_install_extras.py
index 44dbc2a3694..5a0ebc23ced 100644
--- a/tests/functional/test_install_extras.py
+++ b/tests/functional/test_install_extras.py
@@ -35,6 +35,7 @@ def test_extras_after_wheel(script: PipTestEnvironment, data: TestData) -> None:
no_extra = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -45,6 +46,7 @@ def test_extras_after_wheel(script: PipTestEnvironment, data: TestData) -> None:
extra = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -84,6 +86,7 @@ def test_nonexistent_extra_warns_user_no_wheel(
result = script.pip(
"install",
"--no-binary=:all:",
+ "--no-build-isolation",
"--no-index",
"--find-links=" + data.find_links,
"simple[nonexistent]",
@@ -273,4 +276,4 @@ def test_install_setuptools_extras_inconsistency(
"""
)
)
- script.pip("install", "--dry-run", test_project_path)
+ script.pip("install", "--no-build-isolation", "--dry-run", test_project_path)
diff --git a/tests/functional/test_install_index.py b/tests/functional/test_install_index.py
index 73b122a6141..4ebc005ba09 100644
--- a/tests/functional/test_install_index.py
+++ b/tests/functional/test_install_index.py
@@ -9,6 +9,7 @@ def test_find_links_relative_path(script: PipTestEnvironment, data: TestData) ->
result = script.pip(
"install",
"parent==0.1",
+ "--no-build-isolation",
"--no-index",
"--find-links",
"packages/",
@@ -27,7 +28,6 @@ def test_find_links_no_doctype(script: PipTestEnvironment, data: TestData) -> No
result = script.pip(
"install",
"simple==1.0",
- "--use-pep517",
"--no-build-isolation",
"--no-index",
"--find-links",
@@ -52,6 +52,7 @@ def test_find_links_requirements_file_relative_path(
)
result = script.pip(
"install",
+ "--no-build-isolation",
"-r",
script.scratch_path / "test-req.txt",
cwd=data.root,
@@ -69,7 +70,9 @@ def test_install_from_file_index_hash_link(
Test that a pkg can be installed from a file:// index using a link with a
hash
"""
- result = script.pip("install", "-i", data.index_url(), "simple==1.0")
+ result = script.pip(
+ "install", "--no-build-isolation", "-i", data.index_url(), "simple==1.0"
+ )
dist_info_folder = script.site_packages / "simple-1.0.dist-info"
result.did_create(dist_info_folder)
@@ -79,6 +82,8 @@ def test_file_index_url_quoting(script: PipTestEnvironment, data: TestData) -> N
Test url quoting of file index url with a space
"""
index_url = data.index_url("in dex")
- result = script.pip("install", "-vvv", "--index-url", index_url, "simple")
+ result = script.pip(
+ "install", "--no-build-isolation", "-vvv", "--index-url", index_url, "simple"
+ )
result.did_create(script.site_packages / "simple")
result.did_create(script.site_packages / "simple-1.0.dist-info")
diff --git a/tests/functional/test_install_report.py b/tests/functional/test_install_report.py
index 968e30f2dec..ab35c30932b 100644
--- a/tests/functional/test_install_report.py
+++ b/tests/functional/test_install_report.py
@@ -50,6 +50,7 @@ def test_install_report_dep(
report_path = tmp_path / "report.json"
script.pip(
"install",
+ "--no-build-isolation",
"require_simple",
"--dry-run",
"--no-index",
@@ -75,6 +76,7 @@ def test_yanked_version(
report_path = tmp_path / "report.json"
script.pip(
"install",
+ "--no-build-isolation",
"simple==3.0",
"--index-url",
data.index_url("yanked"),
@@ -102,6 +104,7 @@ def test_skipped_yanked_version(
report_path = tmp_path / "report.json"
script.pip(
"install",
+ "--no-build-isolation",
"simple",
"--index-url",
data.index_url("yanked"),
diff --git a/tests/functional/test_install_reqs.py b/tests/functional/test_install_reqs.py
index 3c5b6db4a68..e1c0906298f 100644
--- a/tests/functional/test_install_reqs.py
+++ b/tests/functional/test_install_reqs.py
@@ -13,7 +13,6 @@
_create_test_package_with_subdirectory,
create_basic_sdist_for_package,
create_basic_wheel_for_package,
- make_wheel,
need_svn,
requirements_file,
)
@@ -188,8 +187,7 @@ def test_schema_check_in_requirements_file(script: PipTestEnvironment) -> None:
"""
script.scratch_path.joinpath("file-egg-req.txt").write_text(
"\n{}\n".format(
- "git://github.com/alex/django-fixture-generator.git"
- "#egg=fixture_generator"
+ "git://github.com/alex/django-fixture-generator.git#egg=fixture_generator"
)
)
@@ -217,7 +215,6 @@ def test_relative_requirements_file(
"""
dist_info_folder = script.site_packages / "fspkg-0.1.dev0.dist-info"
- egg_link_file = script.site_packages / "FSPkg.egg-link"
package_folder = script.site_packages / "fspkg"
# Compute relative install path to FSPkg from scratch path.
@@ -238,7 +235,12 @@ def test_relative_requirements_file(
if not editable:
with requirements_file(req_path + "\n", script.scratch_path) as reqs_file:
result = script.pip(
- "install", "-vvv", "-r", reqs_file.name, cwd=script.scratch_path
+ "install",
+ "--no-build-isolation",
+ "-vvv",
+ "-r",
+ reqs_file.name,
+ cwd=script.scratch_path,
)
result.did_create(dist_info_folder)
result.did_create(package_folder)
@@ -247,9 +249,16 @@ def test_relative_requirements_file(
"-e " + req_path + "\n", script.scratch_path
) as reqs_file:
result = script.pip(
- "install", "-vvv", "-r", reqs_file.name, cwd=script.scratch_path
+ "install",
+ "--no-build-isolation",
+ "-vvv",
+ "-r",
+ reqs_file.name,
+ cwd=script.scratch_path,
)
- result.did_create(egg_link_file)
+ direct_url = result.get_created_direct_url("fspkg")
+ assert direct_url
+ assert direct_url.is_local_editable()
@pytest.mark.xfail
@@ -290,6 +299,7 @@ def test_package_in_constraints_and_dependencies(
)
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -315,6 +325,7 @@ def test_constraints_apply_to_dependency_groups(
)
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -331,6 +342,7 @@ def test_multiple_constraints_files(script: PipTestEnvironment, data: TestData)
script.scratch_path.joinpath("inner.txt").write_text("Upper==1.0")
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -357,6 +369,7 @@ def test_respect_order_in_requirements_file(
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -384,9 +397,8 @@ def test_install_local_editable_with_extras(
res = script.pip_install_local(
"-e", f"{to_install}[bar]", allow_stderr_warning=True
)
- res.did_update(script.site_packages / "easy-install.pth")
- res.did_create(script.site_packages / "LocalExtras.egg-link")
- res.did_create(script.site_packages / "simple")
+ res.assert_installed("LocalExtras", editable=True, editable_vcs=False)
+ res.assert_installed("simple", editable=False)
def test_install_collected_dependencies_first(script: PipTestEnvironment) -> None:
@@ -444,7 +456,13 @@ def test_wheel_user_with_prefix_in_pydistutils_cfg(
)
result = script.pip(
- "install", "--user", "--no-index", "-f", data.find_links, "requiresupper"
+ "install",
+ "--no-build-isolation",
+ "--user",
+ "--no-index",
+ "-f",
+ data.find_links,
+ "requiresupper",
)
# Check that we are really installing a wheel
assert "installed requiresupper" in result.stdout
@@ -456,6 +474,7 @@ def test_constraints_not_installed_by_default(
script.scratch_path.joinpath("c.txt").write_text("requiresupper")
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -491,6 +510,7 @@ def test_constraints_local_editable_install_causes_error(
to_install = data.src.joinpath("singlemodule")
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -523,6 +543,7 @@ def test_constraints_local_install_causes_error(
to_install = data.src.joinpath("singlemodule")
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -570,6 +591,7 @@ def test_constraints_constrain_to_local(
)
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -589,6 +611,7 @@ def test_constrained_to_url_install_same_url(
script.scratch_path.joinpath("constraints.txt").write_text(constraints)
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -817,8 +840,7 @@ def test_install_unsupported_wheel_link_with_marker(script: PipTestEnvironment)
result = script.pip("install", "-r", script.scratch_path / "with-marker.txt")
assert (
- "Ignoring asdf: markers 'sys_platform == \"xyz\"' don't match "
- "your environment"
+ "Ignoring asdf: markers 'sys_platform == \"xyz\"' don't match your environment"
) in result.stdout
assert len(result.files_created) == 0
@@ -918,26 +940,3 @@ def test_config_settings_local_to_package(
assert "--verbose" not in simple3_args
simple2_args = simple2_sdist.args()
assert "--verbose" not in simple2_args
-
-
-def test_nonpep517_setuptools_import_failure(script: PipTestEnvironment) -> None:
- """Any import failures of `setuptools` should inform the user both that it's
- not pip's fault, but also exactly what went wrong in the import."""
- # Install a poisoned version of 'setuptools' that fails to import.
- name = "setuptools_poisoned"
- module = """\
-raise ImportError("this 'setuptools' was intentionally poisoned")
-"""
- path = make_wheel(name, "0.1.0", extra_files={"setuptools.py": module}).save_to_dir(
- script.scratch_path
- )
- script.pip("install", "--no-index", path)
-
- result = script.pip_install_local("--no-use-pep517", "simple", expect_error=True)
- nice_message = (
- "ERROR: Can not execute `setup.py`"
- " since setuptools failed to import in the build environment"
- )
- exc_message = "ImportError: this 'setuptools' was intentionally poisoned"
- assert nice_message in result.stderr
- assert exc_message in result.stderr
diff --git a/tests/functional/test_install_requested.py b/tests/functional/test_install_requested.py
index 2c5cad9fcc8..cc834af2ab2 100644
--- a/tests/functional/test_install_requested.py
+++ b/tests/functional/test_install_requested.py
@@ -23,7 +23,12 @@ def _assert_requested_absent(
def test_install_requested_basic(script: PipTestEnvironment, data: TestData) -> None:
result = script.pip(
- "install", "--no-index", "-f", data.find_links, "require_simple"
+ "install",
+ "--no-build-isolation",
+ "--no-index",
+ "-f",
+ data.find_links,
+ "require_simple",
)
_assert_requested_present(script, result, "require_simple", "1.0")
# dependency is not REQUESTED
@@ -36,6 +41,7 @@ def test_install_requested_requirements(
script.scratch_path.joinpath("requirements.txt").write_text("require_simple\n")
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -54,6 +60,7 @@ def test_install_requested_dep_in_requirements(
)
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -72,6 +79,7 @@ def test_install_requested_reqs_and_constraints(
script.scratch_path.joinpath("constraints.txt").write_text("simple<3\n")
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -94,6 +102,7 @@ def test_install_requested_in_reqs_and_constraints(
script.scratch_path.joinpath("constraints.txt").write_text("simple<3\n")
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -113,6 +122,7 @@ def test_install_requested_from_cli_with_constraint(
script.scratch_path.joinpath("constraints.txt").write_text("simple<3\n")
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -133,6 +143,7 @@ def test_install_requested_from_cli_with_url_constraint(
)
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"-c",
script.scratch_path / "constraints.txt",
diff --git a/tests/functional/test_install_upgrade.py b/tests/functional/test_install_upgrade.py
index 43b43d64f82..de52218e96f 100644
--- a/tests/functional/test_install_upgrade.py
+++ b/tests/functional/test_install_upgrade.py
@@ -167,9 +167,22 @@ def test_upgrade_with_newest_already_installed(
If the newest version of a package is already installed, the package should
not be reinstalled and the user should be informed.
"""
- script.pip("install", "-f", data.find_links, "--no-index", "simple")
+ script.pip(
+ "install",
+ "--no-build-isolation",
+ "-f",
+ data.find_links,
+ "--no-index",
+ "simple",
+ )
result = script.pip(
- "install", "--upgrade", "-f", data.find_links, "--no-index", "simple"
+ "install",
+ "--no-build-isolation",
+ "--upgrade",
+ "-f",
+ data.find_links,
+ "--no-index",
+ "simple",
)
assert not result.files_created, "simple upgraded when it should not have"
if resolver_variant == "resolvelib":
@@ -217,8 +230,7 @@ def test_uninstall_before_upgrade_from_url(script: PipTestEnvironment) -> None:
result.did_create(script.site_packages / "initools")
result2 = script.pip(
"install",
- "https://files.pythonhosted.org/packages/source/I/INITools/INITools-"
- "0.3.tar.gz",
+ "https://files.pythonhosted.org/packages/source/I/INITools/INITools-0.3.tar.gz",
)
assert result2.files_created, "upgrade to INITools 0.3 failed"
result3 = script.pip("uninstall", "initools", "-y")
@@ -236,8 +248,7 @@ def test_upgrade_to_same_version_from_url(script: PipTestEnvironment) -> None:
result.did_create(script.site_packages / "initools")
result2 = script.pip(
"install",
- "https://files.pythonhosted.org/packages/source/I/INITools/INITools-"
- "0.3.tar.gz",
+ "https://files.pythonhosted.org/packages/source/I/INITools/INITools-0.3.tar.gz",
)
assert (
script.site_packages / "initools" not in result2.files_updated
@@ -288,10 +299,18 @@ def test_uninstall_rollback(script: PipTestEnvironment, data: TestData) -> None:
crafted to fail on install).
"""
- result = script.pip("install", "-f", data.find_links, "--no-index", "broken==0.1")
+ result = script.pip(
+ "install",
+ "--no-build-isolation",
+ "-f",
+ data.find_links,
+ "--no-index",
+ "broken==0.1",
+ )
result.did_create(script.site_packages / "broken.py")
result2 = script.pip(
"install",
+ "--no-build-isolation",
"-f",
data.find_links,
"--no-index",
diff --git a/tests/functional/test_install_user.py b/tests/functional/test_install_user.py
index 0b1e025cbbe..7d39bc3ce11 100644
--- a/tests/functional/test_install_user.py
+++ b/tests/functional/test_install_user.py
@@ -75,7 +75,7 @@ def test_install_subversion_usersite_editable_with_distribute(
)
),
)
- result.assert_installed("INITools", use_user_site=True)
+ result.assert_installed("INITools")
def test_install_from_current_directory_into_usersite(
self, script: PipTestEnvironment, data: TestData
@@ -86,6 +86,7 @@ def test_install_from_current_directory_into_usersite(
run_from = data.packages.joinpath("FSPkg")
result = script.pip(
"install",
+ "--no-build-isolation",
"-vvv",
"--user",
curdir,
diff --git a/tests/functional/test_install_vcs_git.py b/tests/functional/test_install_vcs_git.py
index 38d416fb62d..187b6faafa0 100644
--- a/tests/functional/test_install_vcs_git.py
+++ b/tests/functional/test_install_vcs_git.py
@@ -108,7 +108,11 @@ def _install_version_pkg_only(
"""
version_pkg_url = _make_version_pkg_url(path, rev=rev)
script.pip(
- "install", "-e", version_pkg_url, allow_stderr_warning=allow_stderr_warning
+ "install",
+ "--no-build-isolation",
+ "-e",
+ version_pkg_url,
+ allow_stderr_warning=allow_stderr_warning,
)
@@ -183,7 +187,9 @@ def test_install_editable_from_git_with_https(
url_path = "pypa/pip-test-package.git"
local_url = _github_checkout(url_path, tmpdir, egg="pip-test-package")
result = script.pip("install", "-e", local_url)
- result.assert_installed("pip-test-package", with_files=[".git"])
+ result.assert_installed(
+ "piptestpackage", dist_name="pip-test-package", with_files=[".git"]
+ )
@pytest.mark.network
@@ -193,11 +199,12 @@ def test_install_noneditable_git(script: PipTestEnvironment) -> None:
"""
result = script.pip(
"install",
- "git+https://github.com/pypa/pip-test-package.git"
- "@0.1.1#egg=pip-test-package",
+ "git+https://github.com/pypa/pip-test-package.git@0.1.1#egg=pip-test-package",
)
dist_info_folder = script.site_packages / "pip_test_package-0.1.1.dist-info"
- result.assert_installed("piptestpackage", without_egg_link=True, editable=False)
+ result.assert_installed(
+ "piptestpackage", dist_name="pip-test-package", editable=False
+ )
result.did_create(dist_info_folder)
@@ -339,29 +346,6 @@ def test_install_git_logs_commit_sha(
assert f"Resolved {base_local_url[4:]} to commit {expected_sha}" in result.stdout
-@pytest.mark.network
-def test_git_with_tag_name_and_update(script: PipTestEnvironment, tmpdir: Path) -> None:
- """
- Test cloning a git repository and updating to a different version.
- """
- url_path = "pypa/pip-test-package.git"
- base_local_url = _github_checkout(url_path, tmpdir)
-
- local_url = f"{base_local_url}#egg=pip-test-package"
- result = script.pip("install", "-e", local_url)
- result.assert_installed("pip-test-package", with_files=[".git"])
-
- new_local_url = f"{base_local_url}@0.1.2#egg=pip-test-package"
- result = script.pip(
- "install",
- "--global-option=--version",
- "-e",
- new_local_url,
- allow_stderr_warning=True,
- )
- assert "0.1.2" in result.stdout
-
-
@pytest.mark.network
def test_git_branch_should_not_be_changed(
script: PipTestEnvironment, tmpdir: Path
@@ -393,7 +377,6 @@ def test_git_with_non_editable_unpacking(
)
result = script.pip(
"install",
- "--global-option=--quiet",
local_url,
allow_stderr_warning=True,
)
@@ -446,7 +429,7 @@ def test_git_with_ambiguous_revs(script: PipTestEnvironment) -> None:
version_pkg_path = _create_test_package(script.scratch_path)
version_pkg_url = _make_version_pkg_url(version_pkg_path, rev="0.1")
script.run("git", "tag", "0.1", cwd=version_pkg_path)
- result = script.pip("install", "-e", version_pkg_url)
+ result = script.pip("install", "--no-build-isolation", "-e", version_pkg_url)
assert "Could not find a tag or branch" not in result.stdout
# it is 'version-pkg' instead of 'version_pkg' because
# egg-link name is version-pkg.egg-link because it is a single .py module
@@ -587,11 +570,11 @@ def test_install_git_branch_not_cached(script: PipTestEnvironment) -> None:
PKG = "gitbranchnotcached"
repo_dir = _create_test_package(script.scratch_path, name=PKG)
url = _make_version_pkg_url(repo_dir, rev="master", name=PKG)
- result = script.pip("install", url, "--only-binary=:all:")
+ result = script.pip("install", "--no-build-isolation", url, "--only-binary=:all:")
assert f"Successfully built {PKG}" in result.stdout, result.stdout
script.pip("uninstall", "-y", PKG)
# build occurs on the second install too because it is not cached
- result = script.pip("install", url)
+ result = script.pip("install", "--no-build-isolation", url)
assert f"Successfully built {PKG}" in result.stdout, result.stdout
@@ -603,9 +586,9 @@ def test_install_git_sha_cached(script: PipTestEnvironment) -> None:
repo_dir = _create_test_package(script.scratch_path, name=PKG)
commit = script.run("git", "rev-parse", "HEAD", cwd=repo_dir).stdout.strip()
url = _make_version_pkg_url(repo_dir, rev=commit, name=PKG)
- result = script.pip("install", url)
+ result = script.pip("install", "--no-build-isolation", url)
assert f"Successfully built {PKG}" in result.stdout, result.stdout
script.pip("uninstall", "-y", PKG)
# build does not occur on the second install because it is cached
- result = script.pip("install", url)
+ result = script.pip("install", "--no-build-isolation", url)
assert f"Successfully built {PKG}" not in result.stdout, result.stdout
diff --git a/tests/functional/test_install_wheel.py b/tests/functional/test_install_wheel.py
index e01ecfb57f3..9ab76ba17b7 100644
--- a/tests/functional/test_install_wheel.py
+++ b/tests/functional/test_install_wheel.py
@@ -38,7 +38,7 @@ def test_install_from_future_wheel_version(
result = script.pip("install", package, "--no-index", expect_error=True)
with pytest.raises(TestFailure):
- result.assert_installed("futurewheel", without_egg_link=True, editable=False)
+ result.assert_installed("futurewheel", editable=False)
package = make_wheel_with_file(
name="futurewheel",
@@ -46,7 +46,7 @@ def test_install_from_future_wheel_version(
wheel_metadata_updates={"Wheel-Version": "1.9"},
).save_to_dir(tmpdir)
result = script.pip("install", package, "--no-index", expect_stderr=True)
- result.assert_installed("futurewheel", without_egg_link=True, editable=False)
+ result.assert_installed("futurewheel", editable=False)
@pytest.mark.parametrize(
@@ -67,7 +67,7 @@ def test_install_from_broken_wheel(
package = data.packages.joinpath(wheel_name)
result = script.pip("install", package, "--no-index", expect_error=True)
with pytest.raises(TestFailure):
- result.assert_installed("futurewheel", without_egg_link=True, editable=False)
+ result.assert_installed("futurewheel", editable=False)
def test_basic_install_from_wheel(
@@ -299,6 +299,7 @@ def test_install_from_wheel_installs_deps(
shutil.copy(data.packages / "source-1.0.tar.gz", tmpdir)
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"--find-links",
tmpdir,
diff --git a/tests/functional/test_list.py b/tests/functional/test_list.py
index 468e6acd6c2..f058439279f 100644
--- a/tests/functional/test_list.py
+++ b/tests/functional/test_list.py
@@ -15,7 +15,6 @@
make_wheel,
wheel,
)
-from tests.lib.direct_url import get_created_direct_url_path
@pytest.fixture(scope="session")
@@ -28,6 +27,7 @@ def simple_script(
script = script_factory(tmpdir.joinpath("workspace"))
script.pip(
"install",
+ "--no-build-isolation",
"-f",
shared_data.find_links,
"--no-index",
@@ -170,6 +170,7 @@ def test_uptodate_flag(script: PipTestEnvironment, data: TestData) -> None:
"""
script.pip(
"install",
+ "--no-build-isolation",
"-f",
data.find_links,
"--no-index",
@@ -210,6 +211,7 @@ def test_uptodate_columns_flag(script: PipTestEnvironment, data: TestData) -> No
"""
script.pip(
"install",
+ "--no-build-isolation",
"-f",
data.find_links,
"--no-index",
@@ -245,6 +247,7 @@ def test_outdated_flag(script: PipTestEnvironment, data: TestData) -> None:
"""
script.pip(
"install",
+ "--no-build-isolation",
"-f",
data.find_links,
"--no-index",
@@ -299,6 +302,7 @@ def test_outdated_columns_flag(script: PipTestEnvironment, data: TestData) -> No
"""
script.pip(
"install",
+ "--no-build-isolation",
"-f",
data.find_links,
"--no-index",
@@ -338,9 +342,17 @@ def pip_test_package_script(
) -> PipTestEnvironment:
tmpdir = tmpdir_factory.mktemp("pip_test_package")
script = script_factory(tmpdir.joinpath("workspace"))
- script.pip("install", "-f", shared_data.find_links, "--no-index", "simple==1.0")
script.pip(
"install",
+ "--no-build-isolation",
+ "-f",
+ shared_data.find_links,
+ "--no-index",
+ "simple==1.0",
+ )
+ script.pip(
+ "install",
+ "--no-build-isolation",
"-e",
"git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package",
)
@@ -427,9 +439,17 @@ def test_outdated_editables_flag(script: PipTestEnvironment, data: TestData) ->
"""
test the behavior of --editable --outdated flag in the list command
"""
- script.pip("install", "-f", data.find_links, "--no-index", "simple==1.0")
+ script.pip(
+ "install",
+ "--no-build-isolation",
+ "-f",
+ data.find_links,
+ "--no-index",
+ "simple==1.0",
+ )
result = script.pip(
"install",
+ "--no-build-isolation",
"-e",
"git+https://github.com/pypa/pip-test-package.git@0.1#egg=pip-test-package",
)
@@ -452,9 +472,17 @@ def test_outdated_editables_columns_flag(
"""
test the behavior of --editable --outdated flag in the list command
"""
- script.pip("install", "-f", data.find_links, "--no-index", "simple==1.0")
+ script.pip(
+ "install",
+ "--no-build-isolation",
+ "-f",
+ data.find_links,
+ "--no-index",
+ "simple==1.0",
+ )
result = script.pip(
"install",
+ "--no-build-isolation",
"-e",
"git+https://github.com/pypa/pip-test-package.git@0.1#egg=pip-test-package",
)
@@ -479,6 +507,7 @@ def test_outdated_not_required_flag(script: PipTestEnvironment, data: TestData)
"""
script.pip(
"install",
+ "--no-build-isolation",
"-f",
data.find_links,
"--no-index",
@@ -498,7 +527,14 @@ def test_outdated_not_required_flag(script: PipTestEnvironment, data: TestData)
def test_outdated_pre(script: PipTestEnvironment, data: TestData) -> None:
- script.pip("install", "-f", data.find_links, "--no-index", "simple==1.0")
+ script.pip(
+ "install",
+ "--no-build-isolation",
+ "-f",
+ data.find_links,
+ "--no-index",
+ "simple==1.0",
+ )
# Let's build a fake wheelhouse
script.scratch_path.joinpath("wheelhouse").mkdir()
@@ -546,7 +582,14 @@ def test_outdated_pre(script: PipTestEnvironment, data: TestData) -> None:
def test_outdated_formats(script: PipTestEnvironment, data: TestData) -> None:
"""Test of different outdated formats"""
- script.pip("install", "-f", data.find_links, "--no-index", "simple==1.0")
+ script.pip(
+ "install",
+ "--no-build-isolation",
+ "-f",
+ data.find_links,
+ "--no-index",
+ "simple==1.0",
+ )
# Let's build a fake wheelhouse
script.scratch_path.joinpath("wheelhouse").mkdir()
@@ -608,7 +651,14 @@ def test_outdated_formats(script: PipTestEnvironment, data: TestData) -> None:
def test_not_required_flag(script: PipTestEnvironment, data: TestData) -> None:
- script.pip("install", "-f", data.find_links, "--no-index", "TopoRequires4")
+ script.pip(
+ "install",
+ "--no-build-isolation",
+ "-f",
+ data.find_links,
+ "--no-index",
+ "TopoRequires4",
+ )
result = script.pip("list", "--not-required", expect_stderr=True)
assert "TopoRequires4 " in result.stdout, str(result)
assert "TopoRequires " not in result.stdout
@@ -735,8 +785,8 @@ def test_list_pep610_editable(script: PipTestEnvironment) -> None:
is correctly listed as editable.
"""
pkg_path = _create_test_package(script.scratch_path, name="testpkg")
- result = script.pip("install", pkg_path)
- direct_url_path = get_created_direct_url_path(result, "testpkg")
+ result = script.pip("install", "--no-build-isolation", pkg_path)
+ direct_url_path = result.get_created_direct_url_path("testpkg")
assert direct_url_path
# patch direct_url.json to simulate an editable install
with open(direct_url_path) as f:
diff --git a/tests/functional/test_lock.py b/tests/functional/test_lock.py
index 727bd72c8a0..9cc6a03a494 100644
--- a/tests/functional/test_lock.py
+++ b/tests/functional/test_lock.py
@@ -59,6 +59,7 @@ def test_lock_sdist_from_findlinks(
"""Test locking a simple wheel package, to the default pylock.toml."""
result = script.pip(
"lock",
+ "--no-build-isolation",
"simple==2.0",
"--no-binary=simple",
"--quiet",
diff --git a/tests/functional/test_new_resolver.py b/tests/functional/test_new_resolver.py
index c094e675a30..b5b26128037 100644
--- a/tests/functional/test_new_resolver.py
+++ b/tests/functional/test_new_resolver.py
@@ -5,7 +5,6 @@
from typing import TYPE_CHECKING, Callable, Protocol
import pytest
-from packaging.utils import canonicalize_name
from tests.conftest import ScriptFactory
from tests.lib import (
@@ -14,27 +13,12 @@
create_basic_wheel_for_package,
create_test_package_with_setup,
)
-from tests.lib.direct_url import get_created_direct_url
from tests.lib.venv import VirtualEnvironment
from tests.lib.wheel import make_wheel
MakeFakeWheel = Callable[[str, str, str], pathlib.Path]
-def assert_editable(script: PipTestEnvironment, *args: str) -> None:
- # This simply checks whether all of the listed packages have a
- # corresponding .egg-link file installed.
- # TODO: Implement a more rigorous way to test for editable installations.
- egg_links = {f"{canonicalize_name(arg)}.egg-link" for arg in args}
- actual_egg_links = {
- f"{canonicalize_name(p.stem)}.egg-link"
- for p in script.site_packages_path.glob("*.egg-link")
- }
- assert (
- egg_links <= actual_egg_links
- ), f"{args!r} not all found in {script.site_packages_path!r}"
-
-
@pytest.fixture
def make_fake_wheel(script: PipTestEnvironment) -> MakeFakeWheel:
def _make_fake_wheel(name: str, version: str, wheel_tag: str) -> pathlib.Path:
@@ -331,6 +315,7 @@ def test_new_resolver_installs_editable(script: PipTestEnvironment) -> None:
)
script.pip(
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-index",
"--find-links",
@@ -340,7 +325,7 @@ def test_new_resolver_installs_editable(script: PipTestEnvironment) -> None:
source_dir,
)
script.assert_installed(base="0.1.0", dep="0.1.0")
- assert_editable(script, "dep")
+ script.assert_installed_editable("dep")
@pytest.mark.parametrize(
@@ -380,6 +365,7 @@ def test_new_resolver_requires_python(
args = [
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-index",
"--find-links",
@@ -536,6 +522,7 @@ def test_new_resolver_only_builds_sdists_when_needed(
# We only ever need to check dep 0.2.0 as it's the latest version
script.pip(
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-index",
"--find-links",
@@ -807,6 +794,7 @@ def test_new_resolver_constraint_on_path_empty(
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-index",
"-c",
@@ -1045,6 +1033,7 @@ def test_new_resolver_extra_merge_in_package(
script.pip(
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-index",
"--find-links",
@@ -1089,6 +1078,7 @@ def test_new_resolver_build_directory_error_zazo_19(script: PipTestEnvironment)
script.pip(
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-index",
"--find-links",
@@ -1184,6 +1174,7 @@ def test_new_resolver_prefers_installed_in_upgrade_if_latest(
# Install the version that's not on the index.
script.pip(
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-index",
local_pkg,
@@ -1192,6 +1183,7 @@ def test_new_resolver_prefers_installed_in_upgrade_if_latest(
# Now --upgrade should still pick the local version because it's "better".
script.pip(
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-index",
"--find-links",
@@ -1303,6 +1295,7 @@ def test_new_resolver_does_reinstall_local_sdists(script: PipTestEnvironment) ->
)
script.pip(
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-index",
archive_path,
@@ -1311,6 +1304,7 @@ def test_new_resolver_does_reinstall_local_sdists(script: PipTestEnvironment) ->
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-index",
archive_path,
@@ -1324,6 +1318,7 @@ def test_new_resolver_does_reinstall_local_paths(script: PipTestEnvironment) ->
pkg = create_test_package_with_setup(script, name="pkg", version="1.0")
script.pip(
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-index",
pkg,
@@ -1332,6 +1327,7 @@ def test_new_resolver_does_reinstall_local_paths(script: PipTestEnvironment) ->
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-index",
pkg,
@@ -1350,6 +1346,7 @@ def test_new_resolver_does_not_reinstall_when_from_a_local_index(
)
script.pip(
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-index",
"--find-links",
@@ -1863,6 +1860,7 @@ def test_new_resolver_succeeds_on_matching_constraint_and_requirement(
script.pip(
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-index",
"-c",
@@ -1872,7 +1870,7 @@ def test_new_resolver_succeeds_on_matching_constraint_and_requirement(
script.assert_installed(test_pkg="0.1.0")
if editable:
- assert_editable(script, "test_pkg")
+ script.assert_installed_editable("test_pkg")
def test_new_resolver_applies_url_constraint_to_dep(script: PipTestEnvironment) -> None:
@@ -2155,9 +2153,9 @@ def test_new_resolver_direct_url_with_extras(
)
script.assert_installed(pkg1="1", pkg2="1", pkg3="1")
- assert not get_created_direct_url(result, "pkg1")
- assert get_created_direct_url(result, "pkg2")
- assert not get_created_direct_url(result, "pkg3")
+ assert not result.get_created_direct_url("pkg1")
+ assert result.get_created_direct_url("pkg2")
+ assert not result.get_created_direct_url("pkg3")
def test_new_resolver_modifies_installed_incompatible(
@@ -2215,6 +2213,7 @@ def test_new_resolver_transitively_depends_on_unnamed_local(
script.pip(
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-index",
"--find-links",
@@ -2268,6 +2267,7 @@ def test_new_resolver_file_url_normalize(
script.pip(
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-index",
format_input(lib_a),
@@ -2479,7 +2479,7 @@ def test_new_resolver_constraint_on_link_with_extra_indirect(
def test_new_resolver_do_not_backtrack_on_build_failure(
script: PipTestEnvironment,
) -> None:
- create_basic_sdist_for_package(script, "pkg1", "2.0", fails_egg_info=True)
+ create_basic_sdist_for_package(script, "pkg1", "2.0", fails_build=True)
create_basic_wheel_for_package(script, "pkg1", "1.0")
result = script.pip(
@@ -2492,14 +2492,14 @@ def test_new_resolver_do_not_backtrack_on_build_failure(
expect_error=True,
)
- assert "egg_info" in result.stderr
+ assert "Failed to build 'pkg1'" in result.stderr
def test_new_resolver_works_when_failing_package_builds_are_disallowed(
script: PipTestEnvironment,
) -> None:
create_basic_wheel_for_package(script, "pkg2", "1.0", depends=["pkg1"])
- create_basic_sdist_for_package(script, "pkg1", "2.0", fails_egg_info=True)
+ create_basic_sdist_for_package(script, "pkg1", "2.0", fails_build=True)
create_basic_wheel_for_package(script, "pkg1", "1.0")
constraints_file = script.scratch_path / "constraints.txt"
constraints_file.write_text("pkg1 != 2.0")
diff --git a/tests/functional/test_new_resolver_errors.py b/tests/functional/test_new_resolver_errors.py
index ebca917d0a5..06c7dafaf41 100644
--- a/tests/functional/test_new_resolver_errors.py
+++ b/tests/functional/test_new_resolver_errors.py
@@ -88,7 +88,9 @@ def test_new_resolver_requires_python_error(script: PipTestEnvironment) -> None:
)
# This always fails because pkgb can never be satisfied.
- result = script.pip("install", "--no-index", pkga, pkgb, expect_error=True)
+ result = script.pip(
+ "install", "--no-build-isolation", "--no-index", pkga, pkgb, expect_error=True
+ )
# The error message should mention the Requires-Python: value causing the
# conflict, not the compatible one.
diff --git a/tests/functional/test_new_resolver_hashes.py b/tests/functional/test_new_resolver_hashes.py
index 5fb1f2bf799..b9d4d7c4adf 100644
--- a/tests/functional/test_new_resolver_hashes.py
+++ b/tests/functional/test_new_resolver_hashes.py
@@ -72,6 +72,7 @@ def test_new_resolver_hash_intersect(
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-deps",
"--no-index",
@@ -102,6 +103,7 @@ def test_new_resolver_hash_intersect_from_constraint(
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-deps",
"--no-index",
@@ -163,6 +165,7 @@ def test_new_resolver_hash_intersect_empty(
result = script.pip(
"install",
+ "--no-build-isolation",
"--no-cache-dir",
"--no-deps",
"--no-index",
diff --git a/tests/functional/test_pep517.py b/tests/functional/test_pep517.py
index 47dae96817f..e36c5f80277 100644
--- a/tests/functional/test_pep517.py
+++ b/tests/functional/test_pep517.py
@@ -4,7 +4,6 @@
from pathlib import Path
from typing import Any
-import pytest
import tomli_w
from pip._internal.build_env import (
@@ -129,25 +128,6 @@ def test_pep517_install_with_reqs(
result.assert_installed("project", editable=False)
-def test_no_use_pep517_without_setup_py(
- script: PipTestEnvironment, tmpdir: Path, data: TestData
-) -> None:
- """Using --no-use-pep517 requires setup.py"""
- project_dir = make_project(
- tmpdir, requires=["test_backend"], backend="test_backend"
- )
- result = script.pip(
- "install",
- "--no-index",
- "--no-use-pep517",
- "-f",
- data.backends,
- project_dir,
- expect_error=True,
- )
- assert "project does not have a setup.py" in result.stderr
-
-
def test_conflicting_pep517_backend_requirements(
script: PipTestEnvironment, tmpdir: Path, data: TestData
) -> None:
@@ -390,45 +370,3 @@ def test_explicit_setuptools_backend(
project_dir,
)
result.assert_installed(name, editable=False)
-
-
-@pytest.mark.network
-def test_pep517_and_build_options(
- script: PipTestEnvironment, tmpdir: Path, data: TestData, common_wheels: Path
-) -> None:
- """Backend generated requirements are installed in the build env"""
- project_dir, name = make_pyproject_with_setup(tmpdir)
- result = script.pip(
- "wheel",
- "--wheel-dir",
- tmpdir,
- "--build-option",
- "foo",
- "-f",
- common_wheels,
- project_dir,
- allow_stderr_warning=True,
- )
- assert "Ignoring --build-option when building" in result.stderr
- assert "using PEP 517" in result.stderr
-
-
-@pytest.mark.network
-def test_pep517_and_global_options(
- script: PipTestEnvironment, tmpdir: Path, data: TestData, common_wheels: Path
-) -> None:
- """Backend generated requirements are installed in the build env"""
- project_dir, name = make_pyproject_with_setup(tmpdir)
- result = script.pip(
- "wheel",
- "--wheel-dir",
- tmpdir,
- "--global-option",
- "foo",
- "-f",
- common_wheels,
- project_dir,
- allow_stderr_warning=True,
- )
- assert "Ignoring --global-option when building" in result.stderr
- assert "using PEP 517" in result.stderr
diff --git a/tests/functional/test_pep660.py b/tests/functional/test_pep660.py
index 9cf3da31172..881d0cc8402 100644
--- a/tests/functional/test_pep660.py
+++ b/tests/functional/test_pep660.py
@@ -2,6 +2,7 @@
from pathlib import Path
from typing import Any
+import pytest
import tomli_w
from tests.lib import PipTestEnvironment
@@ -164,53 +165,31 @@ def test_install_pep660_from_reqs_file(
), "a .egg-link file should not have been created"
-def test_install_no_pep660_setup_py_fallback(
- tmpdir: Path, script: PipTestEnvironment
+@pytest.mark.parametrize("isolation_arg", [[], ["--no-build-isolation"]])
+def test_install_no_pep660(
+ isolation_arg: list[str],
+ tmpdir: Path,
+ script: PipTestEnvironment,
+ common_wheels: Path,
) -> None:
"""
- Test that we fall back to setuptools develop when using a backend that
- does not support build_editable. Since there is a pyproject.toml,
- the prepare_metadata_for_build_wheel hook is called.
- """
- project_dir = _make_project(tmpdir, BACKEND_WITHOUT_PEP660, with_setup_py=True)
- result = script.pip(
- "install",
- "--no-index",
- "--no-build-isolation",
- "--editable",
- project_dir,
- allow_stderr_warning=False,
- )
- _assert_hook_called(project_dir, "prepare_metadata_for_build_wheel")
- assert (
- result.test_env.site_packages.joinpath("project.egg-link")
- in result.files_created
- ), "a .egg-link file should have been created"
-
+ Test the error message when the build backend does not support PEP 660.
-def test_install_no_pep660_setup_cfg_fallback(
- tmpdir: Path, script: PipTestEnvironment
-) -> None:
- """
- Test that we fall back to setuptools develop when using a backend that
- does not support build_editable. Since there is a pyproject.toml,
- the prepare_metadata_for_build_wheel hook is called.
+ The error is the same with and without build isolation.
"""
- project_dir = _make_project(tmpdir, BACKEND_WITHOUT_PEP660, with_setup_py=False)
+ project_dir = _make_project(tmpdir, BACKEND_WITHOUT_PEP660, with_setup_py=True)
result = script.pip(
"install",
"--no-index",
- "--no-build-isolation",
+ "-f",
+ common_wheels,
+ *isolation_arg,
"--editable",
project_dir,
- allow_stderr_warning=False,
+ allow_error=True,
)
- print(result.stdout, result.stderr)
- _assert_hook_called(project_dir, "prepare_metadata_for_build_wheel")
- assert (
- result.test_env.site_packages.joinpath("project.egg-link")
- in result.files_created
- ), ".egg-link file should have been created"
+ assert result.returncode != 0
+ assert "missing the 'build_editable' hook" in result.stderr
def test_wheel_editable_pep660_basic(tmpdir: Path, script: PipTestEnvironment) -> None:
diff --git a/tests/functional/test_proxy.py b/tests/functional/test_proxy.py
index 32eb94a1edf..0810d82d3af 100644
--- a/tests/functional/test_proxy.py
+++ b/tests/functional/test_proxy.py
@@ -77,6 +77,7 @@ def test_proxy_does_not_override_netrc(
script.environ["NETRC"] = netrc
script.pip(
"install",
+ "--no-build-isolation",
"--proxy",
f"http://127.0.0.1:{proxy1.flags.port}",
"--trusted-host",
diff --git a/tests/functional/test_show.py b/tests/functional/test_show.py
index ea831935372..40a40b0aa24 100644
--- a/tests/functional/test_show.py
+++ b/tests/functional/test_show.py
@@ -36,7 +36,7 @@ def test_show_with_files_not_found(script: PipTestEnvironment, data: TestData) -
installed-files.txt not found.
"""
editable = data.packages.joinpath("SetupPyUTF8")
- script.pip("install", "-e", editable)
+ script.run("python", "setup.py", "develop", cwd=editable)
result = script.pip("show", "-f", "SetupPyUTF8")
lines = result.stdout.splitlines()
assert len(lines) == 13
@@ -264,7 +264,14 @@ def test_pip_show_divider(script: PipTestEnvironment, data: TestData) -> None:
"""
Expect a divider between packages
"""
- script.pip("install", "pip-test-package", "--no-index", "-f", data.packages)
+ script.pip(
+ "install",
+ "--no-build-isolation",
+ "pip-test-package",
+ "--no-index",
+ "-f",
+ data.packages,
+ )
result = script.pip("show", "pip", "pip-test-package")
lines = result.stdout.splitlines()
assert "---" in lines
@@ -273,7 +280,14 @@ def test_pip_show_divider(script: PipTestEnvironment, data: TestData) -> None:
def test_package_name_is_canonicalized(
script: PipTestEnvironment, data: TestData
) -> None:
- script.pip("install", "pip-test-package", "--no-index", "-f", data.packages)
+ script.pip(
+ "install",
+ "--no-build-isolation",
+ "pip-test-package",
+ "--no-index",
+ "-f",
+ data.packages,
+ )
dash_show_result = script.pip("show", "pip-test-package")
underscore_upper_show_result = script.pip("show", "pip-test_Package")
@@ -289,7 +303,14 @@ def test_show_required_by_packages_basic(
Test that installed packages that depend on this package are shown
"""
editable_path = os.path.join(data.src, "requires_simple")
- script.pip("install", "--no-index", "-f", data.find_links, editable_path)
+ script.pip(
+ "install",
+ "--no-build-isolation",
+ "--no-index",
+ "-f",
+ data.find_links,
+ editable_path,
+ )
result = script.pip("show", "simple")
lines = result.stdout.splitlines()
@@ -309,7 +330,14 @@ def test_show_required_by_packages_capitalized(
where the package has a capital letter
"""
editable_path = os.path.join(data.src, "requires_capitalized")
- script.pip("install", "--no-index", "-f", data.find_links, editable_path)
+ script.pip(
+ "install",
+ "--no-build-isolation",
+ "--no-index",
+ "-f",
+ data.find_links,
+ editable_path,
+ )
result = script.pip("show", "simple")
lines = result.stdout.splitlines()
@@ -330,9 +358,23 @@ def test_show_required_by_packages_requiring_capitalized(
lower and upper case letters
"""
required_package_path = os.path.join(data.src, "requires_capitalized")
- script.pip("install", "--no-index", "-f", data.find_links, required_package_path)
+ script.pip(
+ "install",
+ "--no-build-isolation",
+ "--no-index",
+ "-f",
+ data.find_links,
+ required_package_path,
+ )
editable_path = os.path.join(data.src, "requires_requires_capitalized")
- script.pip("install", "--no-index", "-f", data.find_links, editable_path)
+ script.pip(
+ "install",
+ "--no-build-isolation",
+ "--no-index",
+ "-f",
+ data.find_links,
+ editable_path,
+ )
result = script.pip("show", "Requires_Capitalized")
lines = result.stdout.splitlines()
diff --git a/tests/functional/test_uninstall.py b/tests/functional/test_uninstall.py
index 7d041bb69e0..1b2f32b152c 100644
--- a/tests/functional/test_uninstall.py
+++ b/tests/functional/test_uninstall.py
@@ -210,9 +210,9 @@ def test_uninstall_overlapping_package(
parent_pkg = data.packages.joinpath("parent-0.1.tar.gz")
child_pkg = data.packages.joinpath("child-0.1.tar.gz")
- result1 = script.pip("install", parent_pkg)
+ result1 = script.pip("install", "--no-build-isolation", parent_pkg)
result1.did_create(join(script.site_packages, "parent"))
- result2 = script.pip("install", child_pkg)
+ result2 = script.pip("install", "--no-build-isolation", child_pkg)
result2.did_create(join(script.site_packages, "child"))
result2.did_create(
normpath(join(script.site_packages, "parent/plugins/child_plugin.py"))
@@ -269,7 +269,7 @@ def test_uninstall_entry_point_colon_in_name(
script_name = script.bin_path.joinpath(console_scripts.split("=")[0].strip())
if sys.platform == "win32":
script_name = script_name.with_suffix(".exe")
- script.pip("install", pkg_path)
+ script.pip("install", "--no-build-isolation", pkg_path)
assert script_name.exists()
script.assert_installed(ep_install="0.1")
@@ -296,7 +296,7 @@ def test_uninstall_gui_scripts(script: PipTestEnvironment) -> None:
script_name = script.bin_path.joinpath("test_")
if sys.platform == "win32":
script_name = script_name.with_suffix(".exe")
- script.pip("install", pkg_path)
+ script.pip("install", "--no-build-isolation", pkg_path)
assert script_name.exists()
script.pip("uninstall", pkg_name, "-y")
assert not script_name.exists()
@@ -313,7 +313,7 @@ def test_uninstall_console_scripts(script: PipTestEnvironment) -> None:
version="0.1",
entry_points={"console_scripts": ["discover = discover:main"]},
)
- result = script.pip("install", pkg_path)
+ result = script.pip("install", "--no-build-isolation", pkg_path)
result.did_create(script.bin / f"discover{script.exe}")
result2 = script.pip("uninstall", "discover", "-y")
assert_all_changes(
@@ -344,7 +344,7 @@ def test_uninstall_console_scripts_uppercase_name(script: PipTestEnvironment) ->
)
script_name = script.bin_path.joinpath("Test" + script.exe)
- script.pip("install", pkg_path)
+ script.pip("install", "--no-build-isolation", pkg_path)
assert script_name.exists()
script.pip("uninstall", "ep_install", "-y")
@@ -437,7 +437,7 @@ def _test_uninstall_editable_with_source_outside_venv(
temp_pkg_dir,
expect_stderr=True,
)
- result2 = script.pip("install", "-e", temp_pkg_dir)
+ result2 = script.run("python", "setup.py", "develop", cwd=temp_pkg_dir)
result2.did_create(join(script.site_packages, "pip-test-package.egg-link"))
result3 = script.pip("uninstall", "-y", "pip-test-package")
assert_all_changes(
@@ -665,9 +665,16 @@ def test_uninstall_editable_and_pip_install(
script.environ["SETUPTOOLS_SYS_PATH_TECHNIQUE"] = "raw"
pkg_path = data.packages.joinpath("FSPkg")
- script.pip("install", "-e", ".", expect_stderr=True, cwd=pkg_path)
+ script.run("python", "setup.py", "develop", expect_stderr=True, cwd=pkg_path)
# ensure both are installed with --ignore-installed:
- script.pip("install", "--ignore-installed", ".", expect_stderr=True, cwd=pkg_path)
+ script.pip(
+ "install",
+ "--no-build-isolation",
+ "--ignore-installed",
+ ".",
+ expect_stderr=True,
+ cwd=pkg_path,
+ )
script.assert_installed(FSPkg="0.1.dev0")
# Uninstall both develop and install
uninstall = script.pip("uninstall", "FSPkg", "-y")
@@ -702,7 +709,7 @@ def test_uninstall_editable_and_pip_install_easy_install_remove(
# Install FSPkg
pkg_path = data.packages.joinpath("FSPkg")
- script.pip("install", "-e", ".", expect_stderr=True, cwd=pkg_path)
+ script.run("python", "setup.py", "develop", expect_stderr=True, cwd=pkg_path)
# Rename easy-install.pth to pip-test-fspkg.pth
easy_install_pth = join(script.site_packages_path, "easy-install.pth")
diff --git a/tests/functional/test_uninstall_user.py b/tests/functional/test_uninstall_user.py
index 63ba5e581d0..25b7512e12c 100644
--- a/tests/functional/test_uninstall_user.py
+++ b/tests/functional/test_uninstall_user.py
@@ -92,7 +92,9 @@ def test_uninstall_editable_from_usersite(
# install
to_install = data.packages.joinpath("FSPkg")
- result1 = script.pip("install", "--user", "-e", to_install)
+ result1 = script.run(
+ "python", "setup.py", "develop", "--user", "--prefix=", cwd=to_install
+ )
egg_link = script.user_site / "FSPkg.egg-link"
result1.did_create(egg_link)
diff --git a/tests/functional/test_wheel.py b/tests/functional/test_wheel.py
index e1ede880496..66099dbebd1 100644
--- a/tests/functional/test_wheel.py
+++ b/tests/functional/test_wheel.py
@@ -53,6 +53,7 @@ def test_pip_wheel_success(script: PipTestEnvironment, data: TestData) -> None:
"""
result = script.pip(
"wheel",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -87,6 +88,7 @@ def test_pip_wheel_success_with_dependency_group(
)
result = script.pip(
"wheel",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -111,6 +113,7 @@ def test_pip_wheel_build_cache(script: PipTestEnvironment, data: TestData) -> No
"""
result = script.pip(
"wheel",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -162,6 +165,7 @@ def test_pip_wheel_build_relative_cachedir(
"""
result = script.pip(
"wheel",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -179,6 +183,7 @@ def test_pip_wheel_builds_when_no_binary_set(
# Check that the wheel package is ignored
res = script.pip(
"wheel",
+ "--no-build-isolation",
"--no-index",
"--no-binary",
":all:",
@@ -199,6 +204,7 @@ def test_pip_wheel_readonly_cache(
# Check that the wheel package is ignored
res = script.pip(
"wheel",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -219,7 +225,13 @@ def test_pip_wheel_builds_editable_deps(
"""
editable_path = os.path.join(data.src, "requires_simple")
result = script.pip(
- "wheel", "--no-index", "-f", data.find_links, "-e", editable_path
+ "wheel",
+ "--no-build-isolation",
+ "--no-index",
+ "-f",
+ data.find_links,
+ "-e",
+ editable_path,
)
wheel_file_name = f"simple-1.0-py{pyversion[0]}-none-any.whl"
wheel_file_path = script.scratch / wheel_file_name
@@ -232,7 +244,13 @@ def test_pip_wheel_builds_editable(script: PipTestEnvironment, data: TestData) -
"""
editable_path = os.path.join(data.src, "simplewheel-1.0")
result = script.pip(
- "wheel", "--no-index", "-f", data.find_links, "-e", editable_path
+ "wheel",
+ "--no-build-isolation",
+ "--no-index",
+ "-f",
+ data.find_links,
+ "-e",
+ editable_path,
)
wheel_file_name = f"simplewheel-1.0-py{pyversion[0]}-none-any.whl"
wheel_file_path = script.scratch / wheel_file_name
@@ -248,6 +266,7 @@ def test_pip_wheel_git_editable_keeps_clone(
"""
script.pip(
"wheel",
+ "--no-build-isolation",
"--no-deps",
"-e",
"git+https://github.com/pypa/pip-test-package#egg=pip-test-package",
@@ -270,7 +289,15 @@ def test_pip_wheel_builds_editable_does_not_create_zip(
wheel_dir = tmpdir / "wheel_dir"
wheel_dir.mkdir()
editable_path = os.path.join(data.src, "simplewheel-1.0")
- script.pip("wheel", "--no-deps", "-e", editable_path, "-w", wheel_dir)
+ script.pip(
+ "wheel",
+ "--no-build-isolation",
+ "--no-deps",
+ "-e",
+ editable_path,
+ "-w",
+ wheel_dir,
+ )
wheels = os.listdir(wheel_dir)
assert len(wheels) == 1
assert wheels[0].endswith(".whl")
@@ -282,6 +309,7 @@ def test_pip_wheel_fail(script: PipTestEnvironment, data: TestData) -> None:
"""
result = script.pip(
"wheel",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -304,6 +332,7 @@ def test_pip_wheel_source_deps(script: PipTestEnvironment, data: TestData) -> No
# 'requires_source' is a wheel that depends on the 'source' project
result = script.pip(
"wheel",
+ "--no-build-isolation",
"--no-index",
"-f",
data.find_links,
@@ -321,7 +350,7 @@ def test_wheel_package_with_latin1_setup(
"""Create a wheel from a package with latin-1 encoded setup.py."""
pkg_to_wheel = data.packages.joinpath("SetupPyLatin1")
- result = script.pip("wheel", pkg_to_wheel)
+ result = script.pip("wheel", "--no-build-isolation", pkg_to_wheel)
assert "Successfully built SetupPyUTF8" in result.stdout
@@ -419,7 +448,9 @@ def test_legacy_wheels_are_not_confused_with_other_files(
pkg_to_wheel = data.src / "simplewheel-1.0"
add_files_to_dist_directory(pkg_to_wheel)
- result = script.pip("wheel", pkg_to_wheel, "-w", script.scratch_path)
+ result = script.pip(
+ "wheel", "--no-build-isolation", pkg_to_wheel, "-w", script.scratch_path
+ )
assert "Installing build dependencies" not in result.stdout, result.stdout
wheel_file_name = f"simplewheel-1.0-py{pyversion[0]}-none-any.whl"
diff --git a/tests/lib/__init__.py b/tests/lib/__init__.py
index 78fe3604480..1b9d1b96350 100644
--- a/tests/lib/__init__.py
+++ b/tests/lib/__init__.py
@@ -14,6 +14,7 @@
from contextlib import contextmanager
from hashlib import sha256
from io import BytesIO, StringIO
+from pathlib import Path
from textwrap import dedent
from typing import Any, AnyStr, Callable, Literal, Protocol, Union, cast
from urllib.request import pathname2url
@@ -28,11 +29,11 @@
from pip._internal.index.collector import LinkCollector
from pip._internal.index.package_finder import PackageFinder
from pip._internal.locations import get_major_minor_version
+from pip._internal.models.direct_url import DIRECT_URL_METADATA_NAME, DirectUrl
from pip._internal.models.search_scope import SearchScope
from pip._internal.models.selection_prefs import SelectionPreferences
from pip._internal.models.target_python import TargetPython
from pip._internal.network.session import PipSession
-from pip._internal.utils.egg_link import _egg_link_names
from tests.lib.venv import VirtualEnvironment
from tests.lib.wheel import make_wheel
@@ -50,10 +51,6 @@
_FilesState = dict[str, Union[FoundDir, FoundFile]]
-def assert_paths_equal(actual: str, expected: str) -> None:
- assert os.path.normpath(actual) == os.path.normpath(expected)
-
-
def create_file(path: str, contents: str | None = None) -> None:
"""Create a file on the path, with the given contents"""
from pip._internal.utils.misc import ensure_dir
@@ -292,90 +289,71 @@ def files_updated(self) -> FoundFiles:
def files_deleted(self) -> FoundFiles:
return FoundFiles(self._impl.files_deleted)
- def _get_egg_link_path_created(self, egg_link_paths: list[str]) -> str | None:
- for egg_link_path in egg_link_paths:
- if egg_link_path in self.files_created:
- return egg_link_path
+ def get_created_direct_url_path(self, pkg: str) -> Path | None:
+ dist_info_prefix = canonicalize_name(pkg).replace("-", "_") + "-"
+ for filename in self.files_created:
+ if (
+ filename.name == DIRECT_URL_METADATA_NAME
+ and filename.parent.name.endswith(".dist-info")
+ and filename.parent.name.startswith(dist_info_prefix)
+ ):
+ return self.test_env.base_path / filename
+ return None
+
+ def get_created_direct_url(self, pkg: str) -> DirectUrl | None:
+ direct_url_path = self.get_created_direct_url_path(pkg)
+ if direct_url_path:
+ with open(direct_url_path) as f:
+ return DirectUrl.from_json(f.read())
return None
def assert_installed(
self,
pkg_name: str,
+ *,
+ dist_name: str | None = None,
editable: bool = True,
+ editable_vcs: bool = True,
with_files: list[str] | None = None,
without_files: list[str] | None = None,
- without_egg_link: bool = False,
- use_user_site: bool = False,
sub_dir: str | None = None,
) -> None:
+ if dist_name is None:
+ dist_name = pkg_name
with_files = with_files or []
without_files = without_files or []
e = self.test_env
- if editable:
- pkg_dir = e.venv / "src" / canonicalize_name(pkg_name)
+ if editable and editable_vcs:
+ pkg_dir = e.venv / "src" / canonicalize_name(dist_name)
# If package was installed in a sub directory
if sub_dir:
pkg_dir = pkg_dir / sub_dir
+ elif editable and not editable_vcs:
+ pkg_dir = None
+ assert not with_files
+ assert not without_files
else:
- without_egg_link = True
pkg_dir = e.site_packages / pkg_name
- if use_user_site:
- egg_link_paths = [
- e.user_site / egg_link_name
- for egg_link_name in _egg_link_names(pkg_name)
- ]
- else:
- egg_link_paths = [
- e.site_packages / egg_link_name
- for egg_link_name in _egg_link_names(pkg_name)
- ]
-
- egg_link_path_created = self._get_egg_link_path_created(egg_link_paths)
- if without_egg_link:
- if egg_link_path_created:
+ direct_url = self.get_created_direct_url(dist_name)
+ if not editable:
+ if direct_url and direct_url.is_local_editable():
raise TestFailure(
- f"unexpected egg link file created: {egg_link_path_created!r}\n"
+ "unexpected editable direct_url.json created: "
+ f"{self.get_created_direct_url_path(dist_name)!r}\n"
f"{self}"
)
else:
- if not egg_link_path_created:
+ if not direct_url or not direct_url.is_local_editable():
raise TestFailure(
- f"expected egg link file missing: {egg_link_paths!r}\n{self}"
- )
-
- egg_link_file = self.files_created[egg_link_path_created]
- egg_link_contents = egg_link_file.bytes.replace(os.linesep, "\n")
-
- # FIXME: I don't understand why there's a trailing . here
- if not (
- egg_link_contents.endswith("\n.")
- and egg_link_contents[:-2].endswith(os.fspath(pkg_dir))
- ):
- expected_ending = f"{pkg_dir}\n."
- raise TestFailure(
- textwrap.dedent(
- f"""
- Incorrect egg_link file {egg_link_file!r}
- Expected ending: {expected_ending!r}
- ------- Actual contents -------
- {egg_link_contents!r}
- -------------------------------
- """
- ).strip()
+ f"{dist_name!r} not installed as editable: direct_url.json "
+ "not found or not editable\n"
+ f"{self.get_created_direct_url_path(dist_name)!r}\n"
+ f"{self}"
)
- if use_user_site:
- pth_file = e.user_site / "easy-install.pth"
- else:
- pth_file = e.site_packages / "easy-install.pth"
-
- if (pth_file in self.files_updated) == without_egg_link:
- maybe = "" if without_egg_link else "not "
- raise TestFailure(f"{pth_file} unexpectedly {maybe}updated by install")
-
- if (pkg_dir in self.files_created) == (os.curdir in without_files):
+ if pkg_dir and (pkg_dir in self.files_created) == (os.curdir in without_files):
maybe = "not " if os.curdir in without_files else ""
files = sorted(p.as_posix() for p in self.files_created)
raise TestFailure(
@@ -728,6 +706,7 @@ def pip_install_local(
) -> TestPipResult:
return self.pip(
"install",
+ "--no-build-isolation",
"--no-index",
"--find-links",
pathlib.Path(DATA_DIR, "packages").as_uri(),
@@ -756,6 +735,17 @@ def assert_not_installed(self, *args: str) -> None:
expected = {canonicalize_name(k) for k in args}
assert not (expected & installed), f"{expected!r} contained in {installed!r}"
+ def assert_installed_editable(self, dist_name: str) -> None:
+ dist_name = canonicalize_name(dist_name)
+ ret = self.pip("list", "--format=json")
+ installed = json.loads(ret.stdout)
+ assert any(
+ x
+ for x in installed
+ if canonicalize_name(x["name"]) == dist_name
+ and x.get("editable_project_location")
+ )
+
# FIXME ScriptTest does something similar, but only within a single
# ProcResult; this generalizes it so states can be compared across
@@ -1224,8 +1214,7 @@ def create_basic_sdist_for_package(
version: str,
extra_files: dict[str, str] | None = None,
*,
- fails_egg_info: bool = False,
- fails_bdist_wheel: bool = False,
+ fails_build: bool = False,
depends: list[str] | None = None,
setup_py_prelude: str = "",
) -> pathlib.Path:
@@ -1237,14 +1226,10 @@ def create_basic_sdist_for_package(
{setup_py_prelude}
- fails_bdist_wheel = {fails_bdist_wheel!r}
- fails_egg_info = {fails_egg_info!r}
-
- if fails_egg_info and "egg_info" in sys.argv:
- raise Exception("Simulated failure for generating metadata.")
+ fails_build = {fails_build!r}
- if fails_bdist_wheel and "bdist_wheel" in sys.argv:
- raise Exception("Simulated failure for building a wheel.")
+ if fails_build:
+ raise Exception("Simulated build failure.")
setup(name={name!r}, version={version!r},
install_requires={depends!r})
@@ -1254,8 +1239,7 @@ def create_basic_sdist_for_package(
version=version,
depends=depends or [],
setup_py_prelude=setup_py_prelude,
- fails_bdist_wheel=fails_bdist_wheel,
- fails_egg_info=fails_egg_info,
+ fails_build=fails_build,
),
}
diff --git a/tests/lib/direct_url.py b/tests/lib/direct_url.py
deleted file mode 100644
index 3049da9c1d2..00000000000
--- a/tests/lib/direct_url.py
+++ /dev/null
@@ -1,27 +0,0 @@
-from __future__ import annotations
-
-import os
-import re
-from pathlib import Path
-
-from pip._internal.models.direct_url import DIRECT_URL_METADATA_NAME, DirectUrl
-
-from tests.lib import TestPipResult
-
-
-def get_created_direct_url_path(result: TestPipResult, pkg: str) -> Path | None:
- direct_url_metadata_re = re.compile(
- pkg + r"-[\d\.]+\.dist-info." + DIRECT_URL_METADATA_NAME + r"$"
- )
- for filename in result.files_created:
- if direct_url_metadata_re.search(os.fspath(filename)):
- return result.test_env.base_path / filename
- return None
-
-
-def get_created_direct_url(result: TestPipResult, pkg: str) -> DirectUrl | None:
- direct_url_path = get_created_direct_url_path(result, pkg)
- if direct_url_path:
- with open(direct_url_path) as f:
- return DirectUrl.from_json(f.read())
- return None
diff --git a/tests/unit/resolution_resolvelib/conftest.py b/tests/unit/resolution_resolvelib/conftest.py
index ee2633afac9..436abddbd4d 100644
--- a/tests/unit/resolution_resolvelib/conftest.py
+++ b/tests/unit/resolution_resolvelib/conftest.py
@@ -35,7 +35,7 @@ def finder(data: TestData) -> PackageFinder:
def preparer(finder: PackageFinder) -> Iterator[RequirementPreparer]:
session = PipSession()
rc = InstallCommand("x", "y")
- o = rc.parse_args([])
+ o = rc.parse_args(["--no-build-isolation"])
with global_tempdir_manager():
with TempDirectory() as tmp:
diff --git a/tests/unit/test_options.py b/tests/unit/test_options.py
index c996bee8eca..1052558ab2f 100644
--- a/tests/unit/test_options.py
+++ b/tests/unit/test_options.py
@@ -198,91 +198,6 @@ def test_cache_dir__PIP_NO_CACHE_DIR_invalid__with_no_cache_dir(
main(["--no-cache-dir", "fake"])
-class TestUsePEP517Options:
- """
- Test options related to using --use-pep517.
- """
-
- def parse_args(self, args: list[str]) -> Values:
- # We use DownloadCommand since that is one of the few Command
- # classes with the use_pep517 options.
- command = create_command("download")
- options, args = command.parse_args(args)
-
- return options
-
- def test_no_option(self) -> None:
- """
- Test passing no option.
- """
- options = self.parse_args([])
- assert options.use_pep517 is None
-
- def test_use_pep517(self) -> None:
- """
- Test passing --use-pep517.
- """
- options = self.parse_args(["--use-pep517"])
- assert options.use_pep517 is True
-
- def test_no_use_pep517(self) -> None:
- """
- Test passing --no-use-pep517.
- """
- options = self.parse_args(["--no-use-pep517"])
- assert options.use_pep517 is False
-
- def test_PIP_USE_PEP517_true(self, monkeypatch: pytest.MonkeyPatch) -> None:
- """
- Test setting PIP_USE_PEP517 to "true".
- """
- monkeypatch.setenv("PIP_USE_PEP517", "true")
- options = self.parse_args([])
- # This is an int rather than a boolean because strtobool() in pip's
- # configuration code returns an int.
- assert options.use_pep517 == 1
-
- def test_PIP_USE_PEP517_false(self, monkeypatch: pytest.MonkeyPatch) -> None:
- """
- Test setting PIP_USE_PEP517 to "false".
- """
- monkeypatch.setenv("PIP_USE_PEP517", "false")
- options = self.parse_args([])
- # This is an int rather than a boolean because strtobool() in pip's
- # configuration code returns an int.
- assert options.use_pep517 == 0
-
- def test_use_pep517_and_PIP_USE_PEP517_false(
- self, monkeypatch: pytest.MonkeyPatch
- ) -> None:
- """
- Test passing --use-pep517 and setting PIP_USE_PEP517 to "false".
- """
- monkeypatch.setenv("PIP_USE_PEP517", "false")
- options = self.parse_args(["--use-pep517"])
- assert options.use_pep517 is True
-
- def test_no_use_pep517_and_PIP_USE_PEP517_true(
- self, monkeypatch: pytest.MonkeyPatch
- ) -> None:
- """
- Test passing --no-use-pep517 and setting PIP_USE_PEP517 to "true".
- """
- monkeypatch.setenv("PIP_USE_PEP517", "true")
- options = self.parse_args(["--no-use-pep517"])
- assert options.use_pep517 is False
-
- def test_PIP_NO_USE_PEP517(
- self, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
- ) -> None:
- """
- Test setting PIP_NO_USE_PEP517, which isn't allowed.
- """
- monkeypatch.setenv("PIP_NO_USE_PEP517", "true")
- with assert_option_error(capsys, expected="--no-use-pep517 error"):
- self.parse_args([])
-
-
class TestOptionsInterspersed(AddFakeCommandMixin):
def test_general_option_after_subcommand(self) -> None:
# FakeCommand intentionally returns the wrong type.
diff --git a/tests/unit/test_pep517.py b/tests/unit/test_pep517.py
index 27008de79c2..86e6ca70e34 100644
--- a/tests/unit/test_pep517.py
+++ b/tests/unit/test_pep517.py
@@ -4,72 +4,9 @@
import pytest
-from pip._internal.exceptions import InstallationError, InvalidPyProjectBuildRequires
+from pip._internal.exceptions import InvalidPyProjectBuildRequires
from pip._internal.req import InstallRequirement
-from tests.lib import TestData
-
-
-@pytest.mark.parametrize(
- "source, expected",
- [
- ("pep517_setup_and_pyproject", True),
- ("pep517_setup_only", False),
- ("pep517_pyproject_only", True),
- ],
-)
-def test_use_pep517(shared_data: TestData, source: str, expected: bool) -> None:
- """
- Test that we choose correctly between PEP 517 and legacy code paths
- """
- src = shared_data.src.joinpath(source)
- req = InstallRequirement(None, None)
- req.source_dir = os.fspath(src) # make req believe it has been unpacked
- req.load_pyproject_toml()
- assert req.use_pep517 is expected
-
-
-def test_use_pep517_rejects_setup_cfg_only(shared_data: TestData) -> None:
- """
- Test that projects with setup.cfg but no pyproject.toml are rejected.
- """
- src = shared_data.src.joinpath("pep517_setup_cfg_only")
- req = InstallRequirement(None, None)
- req.source_dir = os.fspath(src) # make req believe it has been unpacked
- with pytest.raises(InstallationError) as e:
- req.load_pyproject_toml()
- err_msg = e.value.args[0]
- assert (
- "does not appear to be a Python project: "
- "neither 'setup.py' nor 'pyproject.toml' found" in err_msg
- )
-
-
-@pytest.mark.parametrize(
- "source, msg",
- [
- ("pep517_setup_and_pyproject", "specifies a build backend"),
- ("pep517_pyproject_only", "does not have a setup.py"),
- ],
-)
-def test_disabling_pep517_invalid(shared_data: TestData, source: str, msg: str) -> None:
- """
- Test that we fail if we try to disable PEP 517 when it's not acceptable
- """
- src = shared_data.src.joinpath(source)
- req = InstallRequirement(None, None)
- req.source_dir = os.fspath(src) # make req believe it has been unpacked
-
- # Simulate --no-use-pep517
- req.use_pep517 = False
-
- with pytest.raises(InstallationError) as e:
- req.load_pyproject_toml()
-
- err_msg = e.value.args[0]
- assert "Disabling PEP 517 processing is invalid" in err_msg
- assert msg in err_msg
-
@pytest.mark.parametrize(
"spec", [("./foo",), ("git+https://example.com/pkg@dev#egg=myproj",)]
diff --git a/tests/unit/test_req.py b/tests/unit/test_req.py
index 0a245fab6a3..38f9207de82 100644
--- a/tests/unit/test_req.py
+++ b/tests/unit/test_req.py
@@ -90,11 +90,11 @@ def _basic_resolver(
finder: PackageFinder,
require_hashes: bool = False,
wheel_cache: WheelCache | None = None,
+ build_isolation: bool = True,
) -> Iterator[Resolver]:
make_install_req = partial(
install_req_from_req_string,
isolated=False,
- use_pep517=None,
)
session = PipSession()
@@ -104,7 +104,7 @@ def _basic_resolver(
build_dir=os.path.join(self.tempdir, "build"),
src_dir=os.path.join(self.tempdir, "src"),
download_dir=None,
- build_isolation=True,
+ build_isolation=build_isolation,
build_isolation_installer=installer,
check_build_deps=False,
build_tracker=tracker,
@@ -166,7 +166,7 @@ def test_environment_marker_extras(self, data: TestData) -> None:
req.user_supplied = True
reqset.add_unnamed_requirement(req)
finder = make_test_finder(find_links=[data.find_links])
- with self._basic_resolver(finder) as resolver:
+ with self._basic_resolver(finder, build_isolation=False) as resolver:
reqset = resolver.resolve(reqset.all_requirements, True)
assert not reqset.has_requirement("simple")
@@ -319,7 +319,9 @@ def test_unhashed_deps_on_require_hashes(self, data: TestData) -> None:
)
)
- with self._basic_resolver(finder, require_hashes=True) as resolver:
+ with self._basic_resolver(
+ finder, require_hashes=True, build_isolation=False
+ ) as resolver:
with pytest.raises(
HashErrors,
match=(
@@ -360,7 +362,7 @@ def test_hashed_deps_on_require_hashes(self) -> None:
def test_download_info_find_links(self, data: TestData) -> None:
"""Test that download_info is set for requirements via find_links."""
finder = make_test_finder(find_links=[data.find_links])
- with self._basic_resolver(finder) as resolver:
+ with self._basic_resolver(finder, build_isolation=False) as resolver:
ireq = get_processed_req_from_line("simple")
reqset = resolver.resolve([ireq], True)
assert len(reqset.all_requirements) == 1
@@ -385,7 +387,7 @@ def test_download_info_index_url(self) -> None:
def test_download_info_web_archive(self) -> None:
"""Test that download_info is set for requirements from a web archive."""
finder = make_test_finder()
- with self._basic_resolver(finder) as resolver:
+ with self._basic_resolver(finder, build_isolation=False) as resolver:
ireq = get_processed_req_from_line(
"pip-test-package @ "
"https://github.com/pypa/pip-test-package/tarball/0.1.1"
@@ -495,7 +497,7 @@ def test_download_info_local_wheel(self, data: TestData) -> None:
def test_download_info_local_dir(self, data: TestData) -> None:
"""Test that download_info is set for requirements from a local dir."""
finder = make_test_finder()
- with self._basic_resolver(finder) as resolver:
+ with self._basic_resolver(finder, build_isolation=False) as resolver:
ireq_url = data.packages.joinpath("FSPkg").as_uri()
ireq = get_processed_req_from_line(f"FSPkg @ {ireq_url}")
reqset = resolver.resolve([ireq], True)
@@ -508,7 +510,7 @@ def test_download_info_local_dir(self, data: TestData) -> None:
def test_download_info_local_editable_dir(self, data: TestData) -> None:
"""Test that download_info is set for requirements from a local editable dir."""
finder = make_test_finder()
- with self._basic_resolver(finder) as resolver:
+ with self._basic_resolver(finder, build_isolation=False) as resolver:
ireq_url = data.packages.joinpath("FSPkg").as_uri()
ireq = get_processed_req_from_line(f"-e {ireq_url}#egg=FSPkg")
reqset = resolver.resolve([ireq], True)
@@ -523,7 +525,7 @@ def test_download_info_local_editable_dir(self, data: TestData) -> None:
def test_download_info_vcs(self) -> None:
"""Test that download_info is set for requirements from git."""
finder = make_test_finder()
- with self._basic_resolver(finder) as resolver:
+ with self._basic_resolver(finder, build_isolation=False) as resolver:
ireq = get_processed_req_from_line(
"pip-test-package @ git+https://github.com/pypa/pip-test-package"
)
@@ -792,9 +794,7 @@ def test_install_req_drop_extras(self, inp: str, out: str) -> None:
# all else should be the same
assert without_extras.link == req.link
assert without_extras.markers == req.markers
- assert without_extras.use_pep517 == req.use_pep517
assert without_extras.isolated == req.isolated
- assert without_extras.global_options == req.global_options
assert without_extras.hash_options == req.hash_options
assert without_extras.constraint == req.constraint
assert without_extras.config_settings == req.config_settings
@@ -841,9 +841,7 @@ def test_install_req_extend_extras(
# all else should be the same
assert extended.link == req.link
assert extended.markers == req.markers
- assert extended.use_pep517 == req.use_pep517
assert extended.isolated == req.isolated
- assert extended.global_options == req.global_options
assert extended.hash_options == req.hash_options
assert extended.constraint == req.constraint
assert extended.config_settings == req.config_settings
diff --git a/tests/unit/test_req_file.py b/tests/unit/test_req_file.py
index 248171c7b5c..88fc4c58bb9 100644
--- a/tests/unit/test_req_file.py
+++ b/tests/unit/test_req_file.py
@@ -33,7 +33,7 @@
)
from pip._internal.req.req_install import InstallRequirement
-from tests.lib import TestData, make_test_finder, requirements_file
+from tests.lib import TestData, make_test_finder
@pytest.fixture
@@ -422,13 +422,9 @@ def test_recursive_relative_requirements_file(
list(parse_requirements(filename=str(root_req_file), session=session))
def test_options_on_a_requirement_line(self, line_processor: LineProcessor) -> None:
- line = (
- 'SomeProject --global-option="yo3" --global-option "yo4" '
- '--config-settings="yo3=yo4" --config-settings "yo1=yo2"'
- )
+ line = 'SomeProject --config-settings="yo3=yo4" --config-settings "yo1=yo2"'
filename = "filename"
req = line_processor(line, filename, 1)[0]
- assert req.global_options == ["yo3", "yo4"]
assert req.config_settings == {"yo3": "yo4", "yo1": "yo2"}
def test_hash_options(self, line_processor: LineProcessor) -> None:
@@ -937,29 +933,6 @@ def test_req_file_no_finder(self, tmpdir: Path) -> None:
parse_reqfile(tmpdir.joinpath("req.txt"), session=PipSession())
- def test_install_requirements_with_options(
- self,
- tmpdir: Path,
- finder: PackageFinder,
- session: PipSession,
- options: mock.Mock,
- ) -> None:
- global_option = "--dry-run"
-
- content = f"""
- --only-binary :all:
- INITools==2.0 --global-option="{global_option}"
- """
-
- with requirements_file(content, tmpdir) as reqs_file:
- req = next(
- parse_reqfile(
- reqs_file.resolve(), finder=finder, options=options, session=session
- )
- )
-
- assert req.global_options == [global_option]
-
@pytest.mark.parametrize(
"raw_req_file,expected_name,expected_spec",
[
diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py
index 147728b4e97..a9f7beea296 100644
--- a/tests/unit/test_utils.py
+++ b/tests/unit/test_utils.py
@@ -51,7 +51,6 @@
split_auth_netloc_from_url,
tabulate,
)
-from pip._internal.utils.setuptools_build import make_setuptools_shim_args
class Tests_EgglinkPath:
@@ -932,59 +931,6 @@ def test_deprecated_message_reads_well_future() -> None:
)
-def test_make_setuptools_shim_args() -> None:
- # Test all arguments at once, including the overall ordering.
- args = make_setuptools_shim_args(
- "/dir/path/setup.py",
- global_options=["--some", "--option"],
- no_user_config=True,
- unbuffered_output=True,
- )
-
- assert args[1:3] == ["-u", "-c"]
- assert args[4:] == ["--some", "--option", "--no-user-cfg"]
-
- shim = args[3]
- # Spot-check key aspects of the command string.
- assert "import setuptools" in shim
- assert "'/dir/path/setup.py'" in args[3]
- assert "sys.argv[0] = __file__" in args[3]
-
-
-@pytest.mark.parametrize("global_options", [None, [], ["--some", "--option"]])
-def test_make_setuptools_shim_args__global_options(
- global_options: list[str] | None,
-) -> None:
- args = make_setuptools_shim_args(
- "/dir/path/setup.py",
- global_options=global_options,
- )
-
- if global_options:
- assert len(args) == 5
- for option in global_options:
- assert option in args
- else:
- assert len(args) == 3
-
-
-@pytest.mark.parametrize("no_user_config", [False, True])
-def test_make_setuptools_shim_args__no_user_config(no_user_config: bool) -> None:
- args = make_setuptools_shim_args(
- "/dir/path/setup.py",
- no_user_config=no_user_config,
- )
- assert ("--no-user-cfg" in args) == no_user_config
-
-
-@pytest.mark.parametrize("unbuffered_output", [False, True])
-def test_make_setuptools_shim_args__unbuffered_output(unbuffered_output: bool) -> None:
- args = make_setuptools_shim_args(
- "/dir/path/setup.py", unbuffered_output=unbuffered_output
- )
- assert ("-u" in args) == unbuffered_output
-
-
@pytest.mark.parametrize(
"isatty,no_stdin,expected",
[
diff --git a/tests/unit/test_wheel.py b/tests/unit/test_wheel.py
index cadff3e5856..e0ac6497b78 100644
--- a/tests/unit/test_wheel.py
+++ b/tests/unit/test_wheel.py
@@ -3,7 +3,6 @@
from __future__ import annotations
import csv
-import logging
import os
import pathlib
import sys
@@ -26,7 +25,6 @@
DirectUrl,
)
from pip._internal.models.scheme import Scheme
-from pip._internal.operations.build.wheel_legacy import get_legacy_build_wheel_path
from pip._internal.operations.install import wheel
from pip._internal.operations.install.wheel import (
InstalledCSVRow,
@@ -37,68 +35,10 @@
from pip._internal.utils.misc import hash_file
from pip._internal.utils.unpacking import unpack_file
-from tests.lib import DATA_DIR, TestData, assert_paths_equal
+from tests.lib import DATA_DIR, TestData
from tests.lib.wheel import make_wheel
-def call_get_legacy_build_wheel_path(
- caplog: pytest.LogCaptureFixture, names: list[str]
-) -> str | None:
- wheel_path = get_legacy_build_wheel_path(
- names=names,
- wheel_directory="/tmp/abcd",
- name="pendulum",
- command_args=["arg1", "arg2"],
- command_output="output line 1\noutput line 2\n",
- )
- return wheel_path
-
-
-def test_get_legacy_build_wheel_path(caplog: pytest.LogCaptureFixture) -> None:
- actual = call_get_legacy_build_wheel_path(caplog, names=["name"])
- assert actual is not None
- assert_paths_equal(actual, "/tmp/abcd/name")
- assert not caplog.records
-
-
-def test_get_legacy_build_wheel_path__no_names(
- caplog: pytest.LogCaptureFixture,
-) -> None:
- caplog.set_level(logging.INFO)
- actual = call_get_legacy_build_wheel_path(caplog, names=[])
- assert actual is None
- assert len(caplog.records) == 1
- record = caplog.records[0]
- assert record.levelname == "WARNING"
- assert record.message.splitlines() == [
- "Legacy build of wheel for 'pendulum' created no files.",
- "Command arguments: arg1 arg2",
- "Command output: [use --verbose to show]",
- ]
-
-
-def test_get_legacy_build_wheel_path__multiple_names(
- caplog: pytest.LogCaptureFixture,
-) -> None:
- caplog.set_level(logging.INFO)
- # Deliberately pass the names in non-sorted order.
- actual = call_get_legacy_build_wheel_path(
- caplog,
- names=["name2", "name1"],
- )
- assert actual is not None
- assert_paths_equal(actual, "/tmp/abcd/name1")
- assert len(caplog.records) == 1
- record = caplog.records[0]
- assert record.levelname == "WARNING"
- assert record.message.splitlines() == [
- "Legacy build of wheel for 'pendulum' created more than one file.",
- "Filenames (choosing first): ['name1', 'name2']",
- "Command arguments: arg1 arg2",
- "Command output: [use --verbose to show]",
- ]
-
-
@pytest.mark.parametrize(
"console_scripts",
[
diff --git a/tests/unit/test_wheel_builder.py b/tests/unit/test_wheel_builder.py
index 0547ac818bc..1fc9e789256 100644
--- a/tests/unit/test_wheel_builder.py
+++ b/tests/unit/test_wheel_builder.py
@@ -1,6 +1,5 @@
from __future__ import annotations
-import logging
import os
from dataclasses import dataclass
from pathlib import Path
@@ -10,7 +9,6 @@
from pip._internal import wheel_builder
from pip._internal.models.link import Link
-from pip._internal.operations.build.wheel_legacy import format_command_result
from pip._internal.req.req_install import InstallRequirement
from pip._internal.vcs.git import Git
@@ -43,52 +41,13 @@ class ReqMock:
link: Link | None = None
constraint: bool = False
source_dir: str | None = "/tmp/pip-install-123/pendulum"
- use_pep517: bool = True
supports_pyproject_editable: bool = False
@pytest.mark.parametrize(
"req, expected",
[
- # We build, whether pep 517 is enabled or not.
- (ReqMock(use_pep517=True), True),
- (ReqMock(use_pep517=False), True),
- # We don't build reqs that are already wheels.
- (ReqMock(is_wheel=True), False),
- # We build editables if the backend supports PEP 660.
- (ReqMock(editable=True, use_pep517=False), False),
- (
- ReqMock(editable=True, use_pep517=True, supports_pyproject_editable=True),
- True,
- ),
- (
- ReqMock(editable=True, use_pep517=True, supports_pyproject_editable=False),
- False,
- ),
- # By default (i.e. when binaries are allowed), VCS requirements
- # should be built in install mode.
- (
- ReqMock(link=Link("git+https://g.c/org/repo"), use_pep517=True),
- True,
- ),
- (
- ReqMock(link=Link("git+https://g.c/org/repo"), use_pep517=False),
- True,
- ),
- ],
-)
-def test_should_build_for_install_command(req: ReqMock, expected: bool) -> None:
- should_build = wheel_builder.should_build_for_install_command(
- cast(InstallRequirement, req),
- )
- assert should_build is expected
-
-
-@pytest.mark.parametrize(
- "req, expected",
- [
- (ReqMock(editable=True, use_pep517=False), False),
- (ReqMock(editable=True, use_pep517=True), False),
+ (ReqMock(editable=True), False),
(ReqMock(source_dir=None), False),
(ReqMock(link=Link("git+https://g.c/org/repo")), False),
(ReqMock(link=Link("https://g.c/dist.tgz")), False),
@@ -112,56 +71,3 @@ def test_should_cache_git_sha(tmpdir: Path) -> None:
url = "git+https://g.c/o/r@master#egg=mypkg"
req = ReqMock(link=Link(url), source_dir=repo_path)
assert not wheel_builder._should_cache(cast(InstallRequirement, req))
-
-
-def test_format_command_result__INFO(caplog: pytest.LogCaptureFixture) -> None:
- caplog.set_level(logging.INFO)
- actual = format_command_result(
- # Include an argument with a space to test argument quoting.
- command_args=["arg1", "second arg"],
- command_output="output line 1\noutput line 2\n",
- )
- assert actual.splitlines() == [
- "Command arguments: arg1 'second arg'",
- "Command output: [use --verbose to show]",
- ]
-
-
-@pytest.mark.parametrize(
- "command_output",
- [
- # Test trailing newline.
- "output line 1\noutput line 2\n",
- # Test no trailing newline.
- "output line 1\noutput line 2",
- ],
-)
-def test_format_command_result__DEBUG(
- caplog: pytest.LogCaptureFixture, command_output: str
-) -> None:
- caplog.set_level(logging.DEBUG)
- actual = format_command_result(
- command_args=["arg1", "arg2"],
- command_output=command_output,
- )
- assert actual.splitlines() == [
- "Command arguments: arg1 arg2",
- "Command output:",
- "output line 1",
- "output line 2",
- ]
-
-
-@pytest.mark.parametrize("log_level", ["DEBUG", "INFO"])
-def test_format_command_result__empty_output(
- caplog: pytest.LogCaptureFixture, log_level: str
-) -> None:
- caplog.set_level(log_level)
- actual = format_command_result(
- command_args=["arg1", "arg2"],
- command_output="",
- )
- assert actual.splitlines() == [
- "Command arguments: arg1 arg2",
- "Command output: None",
- ]