mirror of
https://github.com/pypa/pip
synced 2023-12-13 21:30:23 +01:00
Add DictMetadata for adapting zip data to Distribution
pkg_resources.Distribution classes delegate to the IMetadataProvider implementation provided at construction. This is the one we'll use for adapting a ZipFile to pkg_resources.DistInfoDistribution.
This commit is contained in:
parent
c3ab0a0b13
commit
20706eb93f
2 changed files with 101 additions and 0 deletions
44
src/pip/_internal/utils/pkg_resources.py
Normal file
44
src/pip/_internal/utils/pkg_resources.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
from pip._vendor.pkg_resources import yield_lines
|
||||
from pip._vendor.six import ensure_str
|
||||
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from typing import Dict, Iterable, List
|
||||
|
||||
|
||||
class DictMetadata(object):
|
||||
"""IMetadataProvider that reads metadata files from a dictionary.
|
||||
"""
|
||||
def __init__(self, metadata):
|
||||
# type: (Dict[str, bytes]) -> None
|
||||
self._metadata = metadata
|
||||
|
||||
def has_metadata(self, name):
|
||||
# type: (str) -> bool
|
||||
return name in self._metadata
|
||||
|
||||
def get_metadata(self, name):
|
||||
# type: (str) -> str
|
||||
try:
|
||||
return ensure_str(self._metadata[name])
|
||||
except UnicodeDecodeError as e:
|
||||
# Mirrors handling done in pkg_resources.NullProvider.
|
||||
e.reason += " in {} file".format(name)
|
||||
raise
|
||||
|
||||
def get_metadata_lines(self, name):
|
||||
# type: (str) -> Iterable[str]
|
||||
return yield_lines(self.get_metadata(name))
|
||||
|
||||
def metadata_isdir(self, name):
|
||||
# type: (str) -> bool
|
||||
return False
|
||||
|
||||
def metadata_listdir(self, name):
|
||||
# type: (str) -> List[str]
|
||||
return []
|
||||
|
||||
def run_script(self, script_name, namespace):
|
||||
# type: (str, str) -> None
|
||||
pass
|
57
tests/unit/test_utils_pkg_resources.py
Normal file
57
tests/unit/test_utils_pkg_resources.py
Normal file
|
@ -0,0 +1,57 @@
|
|||
from email.message import Message
|
||||
|
||||
import pytest
|
||||
from pip._vendor.pkg_resources import DistInfoDistribution, Requirement
|
||||
from pip._vendor.six import ensure_binary
|
||||
|
||||
from pip._internal.utils.packaging import get_metadata, get_requires_python
|
||||
from pip._internal.utils.pkg_resources import DictMetadata
|
||||
from tests.lib import skip_if_python2
|
||||
|
||||
|
||||
def test_dict_metadata_works():
|
||||
name = "simple"
|
||||
version = "0.1.0"
|
||||
require_a = "a==1.0"
|
||||
require_b = "b==1.1; extra == 'also_b'"
|
||||
requires = [require_a, require_b, "c==1.2; extra == 'also_c'"]
|
||||
extras = ["also_b", "also_c"]
|
||||
requires_python = ">=3"
|
||||
|
||||
metadata = Message()
|
||||
metadata["Name"] = name
|
||||
metadata["Version"] = version
|
||||
for require in requires:
|
||||
metadata["Requires-Dist"] = require
|
||||
for extra in extras:
|
||||
metadata["Provides-Extra"] = extra
|
||||
metadata["Requires-Python"] = requires_python
|
||||
|
||||
inner_metadata = DictMetadata({
|
||||
"METADATA": ensure_binary(metadata.as_string())
|
||||
})
|
||||
dist = DistInfoDistribution(
|
||||
location="<in-memory>", metadata=inner_metadata, project_name=name
|
||||
)
|
||||
|
||||
assert name == dist.project_name
|
||||
assert version == dist.version
|
||||
assert set(extras) == set(dist.extras)
|
||||
assert [Requirement.parse(require_a)] == dist.requires([])
|
||||
assert [
|
||||
Requirement.parse(require_a), Requirement.parse(require_b)
|
||||
] == dist.requires(["also_b"])
|
||||
assert metadata.as_string() == get_metadata(dist).as_string()
|
||||
assert requires_python == get_requires_python(dist)
|
||||
|
||||
|
||||
# Metadata is not decoded on Python 2, so no chance for error.
|
||||
@skip_if_python2
|
||||
def test_dict_metadata_throws_on_bad_unicode():
|
||||
metadata = DictMetadata({
|
||||
"METADATA": b"\xff"
|
||||
})
|
||||
|
||||
with pytest.raises(UnicodeDecodeError) as e:
|
||||
metadata.get_metadata("METADATA")
|
||||
assert "METADATA" in str(e.value)
|
Loading…
Reference in a new issue