initial commit
This commit is contained in:
		| @@ -0,0 +1,21 @@ | ||||
| from pip._internal.distributions.base import AbstractDistribution | ||||
| from pip._internal.distributions.sdist import SourceDistribution | ||||
| from pip._internal.distributions.wheel import WheelDistribution | ||||
| from pip._internal.req.req_install import InstallRequirement | ||||
|  | ||||
|  | ||||
| def make_distribution_for_install_requirement( | ||||
|     install_req: InstallRequirement, | ||||
| ) -> AbstractDistribution: | ||||
|     """Returns a Distribution for the given InstallRequirement""" | ||||
|     # Editable requirements will always be source distributions. They use the | ||||
|     # legacy logic until we create a modern standard for them. | ||||
|     if install_req.editable: | ||||
|         return SourceDistribution(install_req) | ||||
|  | ||||
|     # If it's a wheel, it's a WheelDistribution | ||||
|     if install_req.is_wheel: | ||||
|         return WheelDistribution(install_req) | ||||
|  | ||||
|     # Otherwise, a SourceDistribution | ||||
|     return SourceDistribution(install_req) | ||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -0,0 +1,39 @@ | ||||
| import abc | ||||
|  | ||||
| from pip._internal.index.package_finder import PackageFinder | ||||
| from pip._internal.metadata.base import BaseDistribution | ||||
| from pip._internal.req import InstallRequirement | ||||
|  | ||||
|  | ||||
| class AbstractDistribution(metaclass=abc.ABCMeta): | ||||
|     """A base class for handling installable artifacts. | ||||
|  | ||||
|     The requirements for anything installable are as follows: | ||||
|  | ||||
|      - we must be able to determine the requirement name | ||||
|        (or we can't correctly handle the non-upgrade case). | ||||
|  | ||||
|      - for packages with setup requirements, we must also be able | ||||
|        to determine their requirements without installing additional | ||||
|        packages (for the same reason as run-time dependencies) | ||||
|  | ||||
|      - we must be able to create a Distribution object exposing the | ||||
|        above metadata. | ||||
|     """ | ||||
|  | ||||
|     def __init__(self, req: InstallRequirement) -> None: | ||||
|         super().__init__() | ||||
|         self.req = req | ||||
|  | ||||
|     @abc.abstractmethod | ||||
|     def get_metadata_distribution(self) -> BaseDistribution: | ||||
|         raise NotImplementedError() | ||||
|  | ||||
|     @abc.abstractmethod | ||||
|     def prepare_distribution_metadata( | ||||
|         self, | ||||
|         finder: PackageFinder, | ||||
|         build_isolation: bool, | ||||
|         check_build_deps: bool, | ||||
|     ) -> None: | ||||
|         raise NotImplementedError() | ||||
| @@ -0,0 +1,23 @@ | ||||
| from pip._internal.distributions.base import AbstractDistribution | ||||
| from pip._internal.index.package_finder import PackageFinder | ||||
| from pip._internal.metadata import BaseDistribution | ||||
|  | ||||
|  | ||||
| class InstalledDistribution(AbstractDistribution): | ||||
|     """Represents an installed package. | ||||
|  | ||||
|     This does not need any preparation as the required information has already | ||||
|     been computed. | ||||
|     """ | ||||
|  | ||||
|     def get_metadata_distribution(self) -> BaseDistribution: | ||||
|         assert self.req.satisfied_by is not None, "not actually installed" | ||||
|         return self.req.satisfied_by | ||||
|  | ||||
|     def prepare_distribution_metadata( | ||||
|         self, | ||||
|         finder: PackageFinder, | ||||
|         build_isolation: bool, | ||||
|         check_build_deps: bool, | ||||
|     ) -> None: | ||||
|         pass | ||||
| @@ -0,0 +1,150 @@ | ||||
| import logging | ||||
| from typing import Iterable, Set, Tuple | ||||
|  | ||||
| from pip._internal.build_env import BuildEnvironment | ||||
| from pip._internal.distributions.base import AbstractDistribution | ||||
| from pip._internal.exceptions import InstallationError | ||||
| from pip._internal.index.package_finder import PackageFinder | ||||
| from pip._internal.metadata import BaseDistribution | ||||
| from pip._internal.utils.subprocess import runner_with_spinner_message | ||||
|  | ||||
| logger = logging.getLogger(__name__) | ||||
|  | ||||
|  | ||||
| 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`. | ||||
|     """ | ||||
|  | ||||
|     def get_metadata_distribution(self) -> BaseDistribution: | ||||
|         return self.req.get_dist() | ||||
|  | ||||
|     def prepare_distribution_metadata( | ||||
|         self, | ||||
|         finder: PackageFinder, | ||||
|         build_isolation: bool, | ||||
|         check_build_deps: bool, | ||||
|     ) -> None: | ||||
|         # Load pyproject.toml, to determine whether PEP 517 is to be used | ||||
|         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: | ||||
|             # Setup an isolated environment and install the build backend static | ||||
|             # requirements in it. | ||||
|             self._prepare_build_backend(finder) | ||||
|             # Check that if the requirement is editable, it either supports PEP 660 or | ||||
|             # has a setup.py or a setup.cfg. This cannot be done earlier because we need | ||||
|             # to setup the build backend to verify it supports build_editable, nor can | ||||
|             # it be done later, because we want to avoid installing build requirements | ||||
|             # needlessly. Doing it here also works around setuptools generating | ||||
|             # UNKNOWN.egg-info when running get_requires_for_build_wheel on a directory | ||||
|             # without setup.py nor setup.cfg. | ||||
|             self.req.isolated_editable_sanity_check() | ||||
|             # Install the dynamic build requirements. | ||||
|             self._install_build_reqs(finder) | ||||
|         # Check if the current environment provides build dependencies | ||||
|         should_check_deps = self.req.use_pep517 and check_build_deps | ||||
|         if should_check_deps: | ||||
|             pyproject_requires = self.req.pyproject_requires | ||||
|             assert pyproject_requires is not None | ||||
|             conflicting, missing = self.req.build_env.check_requirements( | ||||
|                 pyproject_requires | ||||
|             ) | ||||
|             if conflicting: | ||||
|                 self._raise_conflicts("the backend dependencies", conflicting) | ||||
|             if missing: | ||||
|                 self._raise_missing_reqs(missing) | ||||
|         self.req.prepare_metadata() | ||||
|  | ||||
|     def _prepare_build_backend(self, finder: PackageFinder) -> None: | ||||
|         # Isolate in a BuildEnvironment and install the build-time | ||||
|         # requirements. | ||||
|         pyproject_requires = self.req.pyproject_requires | ||||
|         assert pyproject_requires is not None | ||||
|  | ||||
|         self.req.build_env = BuildEnvironment() | ||||
|         self.req.build_env.install_requirements( | ||||
|             finder, pyproject_requires, "overlay", kind="build dependencies" | ||||
|         ) | ||||
|         conflicting, missing = self.req.build_env.check_requirements( | ||||
|             self.req.requirements_to_check | ||||
|         ) | ||||
|         if conflicting: | ||||
|             self._raise_conflicts("PEP 517/518 supported requirements", conflicting) | ||||
|         if missing: | ||||
|             logger.warning( | ||||
|                 "Missing build requirements in pyproject.toml for %s.", | ||||
|                 self.req, | ||||
|             ) | ||||
|             logger.warning( | ||||
|                 "The project does not specify a build backend, and " | ||||
|                 "pip cannot fall back to setuptools without %s.", | ||||
|                 " and ".join(map(repr, sorted(missing))), | ||||
|             ) | ||||
|  | ||||
|     def _get_build_requires_wheel(self) -> Iterable[str]: | ||||
|         with self.req.build_env: | ||||
|             runner = runner_with_spinner_message("Getting requirements to build wheel") | ||||
|             backend = self.req.pep517_backend | ||||
|             assert backend is not None | ||||
|             with backend.subprocess_runner(runner): | ||||
|                 return backend.get_requires_for_build_wheel() | ||||
|  | ||||
|     def _get_build_requires_editable(self) -> Iterable[str]: | ||||
|         with self.req.build_env: | ||||
|             runner = runner_with_spinner_message( | ||||
|                 "Getting requirements to build editable" | ||||
|             ) | ||||
|             backend = self.req.pep517_backend | ||||
|             assert backend is not None | ||||
|             with backend.subprocess_runner(runner): | ||||
|                 return backend.get_requires_for_build_editable() | ||||
|  | ||||
|     def _install_build_reqs(self, finder: PackageFinder) -> None: | ||||
|         # Install any extra build dependencies that the backend requests. | ||||
|         # This must be done in a second pass, as the pyproject.toml | ||||
|         # dependencies must be installed before we can call the backend. | ||||
|         if ( | ||||
|             self.req.editable | ||||
|             and self.req.permit_editable_wheels | ||||
|             and self.req.supports_pyproject_editable() | ||||
|         ): | ||||
|             build_reqs = self._get_build_requires_editable() | ||||
|         else: | ||||
|             build_reqs = self._get_build_requires_wheel() | ||||
|         conflicting, missing = self.req.build_env.check_requirements(build_reqs) | ||||
|         if conflicting: | ||||
|             self._raise_conflicts("the backend dependencies", conflicting) | ||||
|         self.req.build_env.install_requirements( | ||||
|             finder, missing, "normal", kind="backend dependencies" | ||||
|         ) | ||||
|  | ||||
|     def _raise_conflicts( | ||||
|         self, conflicting_with: str, conflicting_reqs: Set[Tuple[str, str]] | ||||
|     ) -> None: | ||||
|         format_string = ( | ||||
|             "Some build dependencies for {requirement} " | ||||
|             "conflict with {conflicting_with}: {description}." | ||||
|         ) | ||||
|         error_message = format_string.format( | ||||
|             requirement=self.req, | ||||
|             conflicting_with=conflicting_with, | ||||
|             description=", ".join( | ||||
|                 f"{installed} is incompatible with {wanted}" | ||||
|                 for installed, wanted in sorted(conflicting_reqs) | ||||
|             ), | ||||
|         ) | ||||
|         raise InstallationError(error_message) | ||||
|  | ||||
|     def _raise_missing_reqs(self, missing: Set[str]) -> None: | ||||
|         format_string = ( | ||||
|             "Some build dependencies for {requirement} are missing: {missing}." | ||||
|         ) | ||||
|         error_message = format_string.format( | ||||
|             requirement=self.req, missing=", ".join(map(repr, sorted(missing))) | ||||
|         ) | ||||
|         raise InstallationError(error_message) | ||||
| @@ -0,0 +1,34 @@ | ||||
| from pip._vendor.packaging.utils import canonicalize_name | ||||
|  | ||||
| from pip._internal.distributions.base import AbstractDistribution | ||||
| from pip._internal.index.package_finder import PackageFinder | ||||
| from pip._internal.metadata import ( | ||||
|     BaseDistribution, | ||||
|     FilesystemWheel, | ||||
|     get_wheel_distribution, | ||||
| ) | ||||
|  | ||||
|  | ||||
| class WheelDistribution(AbstractDistribution): | ||||
|     """Represents a wheel distribution. | ||||
|  | ||||
|     This does not need any preparation as wheels can be directly unpacked. | ||||
|     """ | ||||
|  | ||||
|     def get_metadata_distribution(self) -> BaseDistribution: | ||||
|         """Loads the metadata from the wheel file into memory and returns a | ||||
|         Distribution that uses it, not relying on the wheel file or | ||||
|         requirement. | ||||
|         """ | ||||
|         assert self.req.local_file_path, "Set as part of preparation during download" | ||||
|         assert self.req.name, "Wheels are never unnamed" | ||||
|         wheel = FilesystemWheel(self.req.local_file_path) | ||||
|         return get_wheel_distribution(wheel, canonicalize_name(self.req.name)) | ||||
|  | ||||
|     def prepare_distribution_metadata( | ||||
|         self, | ||||
|         finder: PackageFinder, | ||||
|         build_isolation: bool, | ||||
|         check_build_deps: bool, | ||||
|     ) -> None: | ||||
|         pass | ||||
		Reference in New Issue
	
	Block a user
	 klein panic
					klein panic