mirror of
https://github.com/pypa/pip
synced 2023-12-13 21:30:23 +01:00
Use email.message to parse metadata
This commit is contained in:
parent
28fff1e483
commit
aee4b50021
|
@ -1,3 +1,4 @@
|
|||
import email.message
|
||||
import logging
|
||||
import re
|
||||
from typing import (
|
||||
|
@ -52,11 +53,6 @@ class BaseDistribution(Protocol):
|
|||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
def metadata_version(self) -> Optional[str]:
|
||||
"""Value of "Metadata-Version:" in the distribution, if available."""
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
def canonical_name(self) -> str:
|
||||
raise NotImplementedError()
|
||||
|
@ -89,12 +85,27 @@ class BaseDistribution(Protocol):
|
|||
"""Read a file in the .dist-info (or .egg-info) directory."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def iter_dependencies(self, extras: Collection[str]) -> Iterable[Requirement]:
|
||||
raise NotImplementedError()
|
||||
|
||||
def iter_entry_points(self) -> Iterable[BaseEntryPoint]:
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
def metadata(self) -> email.message.Message:
|
||||
"""Metadata of distribution parsed from e.g. METADATA or PKG-INFO."""
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
def metadata_version(self) -> Optional[str]:
|
||||
"""Value of "Metadata-Version:" in the distribution, if available."""
|
||||
return self.metadata.get("Metadata-Version")
|
||||
|
||||
def iter_dependencies(self, extras: Collection[str]) -> Iterable[Requirement]:
|
||||
for value in self.metadata.get_all("Requires-Dist"):
|
||||
requirement = Requirement(value)
|
||||
marker = requirement.marker
|
||||
if marker and any(marker.evaluate({"extra": extra}) for extra in extras):
|
||||
continue
|
||||
yield requirement
|
||||
|
||||
|
||||
class BaseEnvironment:
|
||||
"""An environment containing distributions to introspect."""
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import logging
|
||||
import email.message
|
||||
import zipfile
|
||||
from typing import Collection, Iterable, Iterator, List, NamedTuple, Optional
|
||||
|
||||
|
@ -10,7 +11,7 @@ from pip._vendor.packaging.version import parse as parse_version
|
|||
from pip._internal.models.direct_url import DirectUrl
|
||||
from pip._internal.utils import misc # TODO: Move definition here.
|
||||
from pip._internal.utils.direct_url_helpers import dist_get_direct_url
|
||||
from pip._internal.utils.packaging import get_installer
|
||||
from pip._internal.utils.packaging import get_installer, get_metadata
|
||||
from pip._internal.utils.wheel import pkg_resources_distribution_for_wheel
|
||||
|
||||
from .base import BaseDistribution, BaseEntryPoint, BaseEnvironment, DistributionVersion
|
||||
|
@ -38,13 +39,6 @@ class Distribution(BaseDistribution):
|
|||
def location(self) -> Optional[str]:
|
||||
return self._dist.location
|
||||
|
||||
@property
|
||||
def metadata_version(self) -> Optional[str]:
|
||||
for line in self._dist.get_metadata_lines(self._dist.PKG_INFO):
|
||||
if line.lower().startswith("metadata-version:"):
|
||||
return line.split(":", 1)[-1].strip()
|
||||
return None
|
||||
|
||||
@property
|
||||
def canonical_name(self) -> str:
|
||||
return canonicalize_name(self._dist.project_name)
|
||||
|
@ -73,18 +67,6 @@ class Distribution(BaseDistribution):
|
|||
def in_usersite(self) -> bool:
|
||||
return misc.dist_in_usersite(self._dist)
|
||||
|
||||
def iter_dependencies(self, extras: Collection[str]) -> Iterable[Requirement]:
|
||||
# pkg_resources raises on invalid extras, so we sanitize.
|
||||
requested_extras = set(extras)
|
||||
valid_extras = requested_extras & set(self._dist.extras)
|
||||
for invalid_extra in requested_extras ^ valid_extras:
|
||||
logger.warning(
|
||||
"Invalid extra %r for package %r discarded",
|
||||
invalid_extra,
|
||||
self.canonical_name,
|
||||
)
|
||||
return self._dist.requires(extras)
|
||||
|
||||
def read_text(self, name: str) -> str:
|
||||
return self._dist.get_metadata(name)
|
||||
|
||||
|
@ -94,6 +76,16 @@ class Distribution(BaseDistribution):
|
|||
name, _, value = str(entry_point).partition("=")
|
||||
yield EntryPoint(name=name.strip(), value=value.strip(), group=group)
|
||||
|
||||
@property
|
||||
def metadata(self) -> email.message.Message:
|
||||
return get_metadata(self._dist)
|
||||
|
||||
def iter_dependencies(self, extras: Collection[str]) -> Iterable[Requirement]:
|
||||
"""pkg_resources caches this for performance so we take advantage of it."""
|
||||
if extras: # pkg_resources raises on invalid extras, so we sanitize.
|
||||
extras = set(extras).intersection(self._dist.extras)
|
||||
return self._dist.requires(extras)
|
||||
|
||||
|
||||
class Environment(BaseEnvironment):
|
||||
def __init__(self, ws: pkg_resources.WorkingSet) -> None:
|
||||
|
|
Loading…
Reference in a new issue