-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix PEP 660 metadata preparation fallback #10577
Merged
uranusjr
merged 7 commits into
pypa:main
from
sbidoul:fix-pep660-metadata-preparation-fallback
Oct 21, 2021
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
d362431
Add TODO
sbidoul ddfeaae
Reject projects that have neither a pyproject.toml nor a setup.py
sbidoul 619b257
Add failing tests for issue 10573
sbidoul b0eb95b
Upgrade pep517 to 0.12.0
sbidoul ae51289
Prepare legacy editable metadata in isolated env
sbidoul b07a956
Split _setup_isolation for readability
sbidoul 106042f
Simplify "Preparing metadata" logging
sbidoul File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Always refuse installing or building projects that have no ``pyproject.toml`` nor | ||
``setup.py``. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
When installing projects with a ``pyproject.toml`` in editable mode, and the build | ||
backend does not support :pep:`660`, prepare metadata using | ||
``prepare_metadata_for_build_wheel`` instead of ``setup.py egg_info``. Also, refuse | ||
installing projects that only have a ``setup.cfg`` and no ``setup.py`` nor | ||
``pyproject.toml``. These restore the pre-21.3 behaviour. | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Upgrade pep517 to 0.12.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
# The following comment should be removed at some point in the future. | ||
# mypy: strict-optional=False | ||
|
||
import functools | ||
import logging | ||
import os | ||
import shutil | ||
|
@@ -16,7 +17,7 @@ | |
from pip._vendor.packaging.utils import canonicalize_name | ||
from pip._vendor.packaging.version import Version | ||
from pip._vendor.packaging.version import parse as parse_version | ||
from pip._vendor.pep517.wrappers import HookMissing, Pep517HookCaller | ||
from pip._vendor.pep517.wrappers import Pep517HookCaller | ||
from pip._vendor.pkg_resources import Distribution | ||
|
||
from pip._internal.build_env import BuildEnvironment, NoOpBuildEnvironment | ||
|
@@ -53,6 +54,7 @@ | |
redact_auth_from_url, | ||
) | ||
from pip._internal.utils.packaging import get_metadata | ||
from pip._internal.utils.subprocess import runner_with_spinner_message | ||
from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds | ||
from pip._internal.utils.virtualenv import running_under_virtualenv | ||
from pip._internal.vcs import vcs | ||
|
@@ -196,11 +198,6 @@ def __init__( | |
# but after loading this flag should be treated as read only. | ||
self.use_pep517 = use_pep517 | ||
|
||
# supports_pyproject_editable will be set to True or False when we try | ||
# to prepare editable metadata or build an editable wheel. None means | ||
# "we don't know yet". | ||
self.supports_pyproject_editable: Optional[bool] = None | ||
|
||
# This requirement needs more preparation before it can be built | ||
self.needs_more_preparation = False | ||
|
||
|
@@ -247,6 +244,18 @@ def name(self) -> Optional[str]: | |
return None | ||
return pkg_resources.safe_name(self.req.name) | ||
|
||
@functools.lru_cache() # use cached_property in python 3.8+ | ||
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( | ||
"Checking if build backend supports build_editable" | ||
) | ||
with self.pep517_backend.subprocess_runner(runner): | ||
return "build_editable" in self.pep517_backend._supported_features() | ||
|
||
@property | ||
def specifier(self) -> SpecifierSet: | ||
return self.req.specifier | ||
|
@@ -503,93 +512,59 @@ def load_pyproject_toml(self) -> None: | |
backend_path=backend_path, | ||
) | ||
|
||
def _generate_editable_metadata(self) -> str: | ||
"""Invokes metadata generator functions, with the required arguments.""" | ||
if self.use_pep517: | ||
assert self.pep517_backend is not None | ||
try: | ||
metadata_directory = generate_editable_metadata( | ||
build_env=self.build_env, | ||
backend=self.pep517_backend, | ||
) | ||
except HookMissing as e: | ||
self.supports_pyproject_editable = False | ||
if not os.path.exists(self.setup_py_path) and not os.path.exists( | ||
self.setup_cfg_path | ||
): | ||
raise InstallationError( | ||
f"Project {self} has a 'pyproject.toml' and its build " | ||
f"backend is missing the {e} hook. Since it does not " | ||
f"have a 'setup.py' nor a 'setup.cfg', " | ||
f"it cannot be installed in editable mode. " | ||
f"Consider using a build backend that supports PEP 660." | ||
) | ||
# At this point we have determined that the build_editable hook | ||
# is missing, and there is a setup.py or setup.cfg | ||
# so we fallback to the legacy metadata generation | ||
logger.info( | ||
"Build backend does not support editables, " | ||
"falling back to setup.py egg_info." | ||
) | ||
else: | ||
self.supports_pyproject_editable = True | ||
return metadata_directory | ||
elif not os.path.exists(self.setup_py_path) and not os.path.exists( | ||
self.setup_cfg_path | ||
): | ||
raise InstallationError( | ||
f"File 'setup.py' or 'setup.cfg' not found " | ||
f"for legacy project {self}. " | ||
f"It cannot be installed in editable mode." | ||
) | ||
|
||
return generate_metadata_legacy( | ||
build_env=self.build_env, | ||
setup_py_path=self.setup_py_path, | ||
source_dir=self.unpacked_source_directory, | ||
isolated=self.isolated, | ||
details=self.name or f"from {self.link}", | ||
) | ||
def isolated_editable_sanity_check(self) -> None: | ||
"""Check that an editable requirement if valid for use with PEP 517/518. | ||
|
||
def _generate_metadata(self) -> str: | ||
"""Invokes metadata generator functions, with the required arguments.""" | ||
if self.use_pep517: | ||
assert self.pep517_backend is not None | ||
try: | ||
return generate_metadata( | ||
build_env=self.build_env, | ||
backend=self.pep517_backend, | ||
) | ||
except HookMissing as e: | ||
raise InstallationError( | ||
f"Project {self} has a pyproject.toml but its build " | ||
f"backend is missing the required {e} hook." | ||
) | ||
elif not os.path.exists(self.setup_py_path): | ||
This verifies that an editable that has a pyproject.toml either supports PEP 660 | ||
or as a setup.py or a setup.cfg | ||
""" | ||
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) | ||
): | ||
raise InstallationError( | ||
f"File 'setup.py' not found for legacy project {self}." | ||
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"it cannot be installed in editable mode. " | ||
f"Consider using a build backend that supports PEP 660." | ||
) | ||
|
||
return generate_metadata_legacy( | ||
build_env=self.build_env, | ||
setup_py_path=self.setup_py_path, | ||
source_dir=self.unpacked_source_directory, | ||
isolated=self.isolated, | ||
details=self.name or f"from {self.link}", | ||
) | ||
|
||
def prepare_metadata(self) -> None: | ||
"""Ensure that project metadata is available. | ||
|
||
Under PEP 517, call the backend hook to prepare the metadata. | ||
Under PEP 517 and PEP 660, call the backend hook to prepare the metadata. | ||
Under legacy processing, call setup.py egg-info. | ||
""" | ||
assert self.source_dir | ||
|
||
if self.editable and self.permit_editable_wheels: | ||
self.metadata_directory = self._generate_editable_metadata() | ||
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, | ||
) | ||
else: | ||
self.metadata_directory = generate_metadata( | ||
build_env=self.build_env, | ||
backend=self.pep517_backend, | ||
) | ||
else: | ||
self.metadata_directory = self._generate_metadata() | ||
self.metadata_directory = generate_metadata_legacy( | ||
build_env=self.build_env, | ||
setup_py_path=self.setup_py_path, | ||
source_dir=self.unpacked_source_directory, | ||
isolated=self.isolated, | ||
details=self.name or f"from {self.link}", | ||
) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At least |
||
|
||
# Act on the newly generated metadata, based on the name and version. | ||
if not self.name: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
"""Wrappers to build Python packages using PEP 517 hooks | ||
""" | ||
|
||
__version__ = '0.11.0' | ||
__version__ = '0.12.0' | ||
|
||
from .wrappers import * # noqa: F401, F403 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the second sentence (the Also one) duplicating the 10531 fragment? I feel it should appeat only once (unfortunately Towncrier does not offer a natural way to reference two issues in one fragment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It overlaps yes. This second one specifically covers editables and accepting it was a regression in 21.3 whereas 10531 is a fix of something introduced in 21.1 or 21.2.