-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7539 from chrahunt/refactor/get-dist-from-zip
Use wheelfile-based pkg_resources.Distribution for metadata
- Loading branch information
Showing
8 changed files
with
240 additions
and
43 deletions.
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
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,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 |
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 |
---|---|---|
@@ -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) |
Oops, something went wrong.