diff --git a/src/pip/_internal/operations/build/__init__.py b/src/pip/_internal/operations/build/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/pip/_internal/operations/build/metadata.py b/src/pip/_internal/operations/build/metadata.py new file mode 100644 index 000000000..66b59eb51 --- /dev/null +++ b/src/pip/_internal/operations/build/metadata.py @@ -0,0 +1,58 @@ +"""Metadata generation logic for source distributions. +""" + +import atexit +import logging +import os + +from pip._internal.operations.build.metadata_legacy import \ + generate_metadata as _generate_metadata_legacy +from pip._internal.utils.subprocess import runner_with_spinner_message +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Callable + + from pip._internal.req.req_install import InstallRequirement + +logger = logging.getLogger(__name__) + + +def get_metadata_generator(install_req): + # type: (InstallRequirement) -> Callable[[InstallRequirement], str] + """Return a callable metadata generator for this InstallRequirement. + + A metadata generator takes an InstallRequirement (install_req) as an input, + generates metadata via the appropriate process for that install_req and + returns the generated metadata directory. + """ + if not install_req.use_pep517: + return _generate_metadata_legacy + + return _generate_metadata + + +def _generate_metadata(install_req): + # type: (InstallRequirement) -> str + assert install_req.pep517_backend is not None + build_env = install_req.build_env + backend = install_req.pep517_backend + + # NOTE: This needs to be refactored to stop using atexit + metadata_tmpdir = TempDirectory(kind="modern-metadata") + atexit.register(metadata_tmpdir.cleanup) + + metadata_dir = metadata_tmpdir.path + + with build_env: + # Note that Pep517HookCaller implements a fallback for + # prepare_metadata_for_build_wheel, so we don't have to + # consider the possibility that this hook doesn't exist. + runner = runner_with_spinner_message("Preparing wheel metadata") + with backend.subprocess_runner(runner): + distinfo_dir = backend.prepare_metadata_for_build_wheel( + metadata_dir + ) + + return os.path.join(metadata_dir, distinfo_dir) diff --git a/src/pip/_internal/operations/generate_metadata.py b/src/pip/_internal/operations/build/metadata_legacy.py similarity index 68% rename from src/pip/_internal/operations/generate_metadata.py rename to src/pip/_internal/operations/build/metadata_legacy.py index 04e5ace12..ba6265db7 100644 --- a/src/pip/_internal/operations/generate_metadata.py +++ b/src/pip/_internal/operations/build/metadata_legacy.py @@ -1,43 +1,24 @@ -"""Metadata generation logic for source distributions. +"""Metadata generation logic for legacy source distributions. """ -import atexit import logging import os from pip._internal.exceptions import InstallationError from pip._internal.utils.misc import ensure_dir from pip._internal.utils.setuptools_build import make_setuptools_egg_info_args -from pip._internal.utils.subprocess import ( - call_subprocess, - runner_with_spinner_message, -) -from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.subprocess import call_subprocess from pip._internal.utils.typing import MYPY_CHECK_RUNNING from pip._internal.vcs import vcs if MYPY_CHECK_RUNNING: - from typing import Callable, List, Optional + from typing import List, Optional from pip._internal.req.req_install import InstallRequirement logger = logging.getLogger(__name__) -def get_metadata_generator(install_req): - # type: (InstallRequirement) -> Callable[[InstallRequirement], str] - """Return a callable metadata generator for this InstallRequirement. - - A metadata generator takes an InstallRequirement (install_req) as an input, - generates metadata via the appropriate process for that install_req and - returns the generated metadata directory. - """ - if not install_req.use_pep517: - return _generate_metadata_legacy - - return _generate_metadata - - def _find_egg_info(source_directory, is_editable): # type: (str, bool) -> str """Find an .egg-info in `source_directory`, based on `is_editable`. @@ -97,8 +78,10 @@ def _find_egg_info(source_directory, is_editable): return os.path.join(base, filenames[0]) -def _generate_metadata_legacy(install_req): +def generate_metadata(install_req): # type: (InstallRequirement) -> str + assert install_req.unpacked_source_directory + req_details_str = install_req.name or "from {}".format(install_req.link) logger.debug( 'Running setup.py (path:%s) egg_info for package %s', @@ -135,28 +118,3 @@ def _generate_metadata_legacy(install_req): install_req.unpacked_source_directory, install_req.editable, ) - - -def _generate_metadata(install_req): - # type: (InstallRequirement) -> str - assert install_req.pep517_backend is not None - build_env = install_req.build_env - backend = install_req.pep517_backend - - # NOTE: This needs to be refactored to stop using atexit - metadata_tmpdir = TempDirectory(kind="modern-metadata") - atexit.register(metadata_tmpdir.cleanup) - - metadata_dir = metadata_tmpdir.path - - with build_env: - # Note that Pep517HookCaller implements a fallback for - # prepare_metadata_for_build_wheel, so we don't have to - # consider the possibility that this hook doesn't exist. - runner = runner_with_spinner_message("Preparing wheel metadata") - with backend.subprocess_runner(runner): - distinfo_dir = backend.prepare_metadata_for_build_wheel( - metadata_dir - ) - - return os.path.join(metadata_dir, distinfo_dir) diff --git a/src/pip/_internal/req/req_install.py b/src/pip/_internal/req/req_install.py index 4437d1eac..fe0f8b4c7 100644 --- a/src/pip/_internal/req/req_install.py +++ b/src/pip/_internal/req/req_install.py @@ -24,7 +24,7 @@ from pip._internal.build_env import NoOpBuildEnvironment from pip._internal.exceptions import InstallationError from pip._internal.locations import distutils_scheme from pip._internal.models.link import Link -from pip._internal.operations.generate_metadata import get_metadata_generator +from pip._internal.operations.build.metadata import get_metadata_generator from pip._internal.pyproject import load_pyproject_toml, make_pyproject_path from pip._internal.req.req_uninstall import UninstallPathSet from pip._internal.utils.compat import native_str