2021-07-13 12:14:58 +02:00
|
|
|
import logging
|
2022-06-04 11:12:18 +02:00
|
|
|
from pathlib import Path
|
2021-08-30 00:43:28 +02:00
|
|
|
from typing import cast
|
|
|
|
from unittest import mock
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
from pip._vendor.packaging.utils import NormalizedName
|
2021-07-13 12:14:58 +02:00
|
|
|
|
2022-06-04 11:12:18 +02:00
|
|
|
from pip._internal.metadata import BaseDistribution, get_directory_distribution
|
2021-07-22 09:55:20 +02:00
|
|
|
from pip._internal.models.direct_url import DIRECT_URL_METADATA_NAME, ArchiveInfo
|
2021-07-13 12:14:58 +02:00
|
|
|
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
@mock.patch.object(BaseDistribution, "read_text", side_effect=FileNotFoundError)
|
|
|
|
def test_dist_get_direct_url_no_metadata(mock_read_text: mock.Mock) -> None:
|
|
|
|
class FakeDistribution(BaseDistribution):
|
|
|
|
pass
|
|
|
|
|
|
|
|
dist = FakeDistribution()
|
2021-07-13 12:14:58 +02:00
|
|
|
assert dist.direct_url is None
|
|
|
|
mock_read_text.assert_called_once_with(DIRECT_URL_METADATA_NAME)
|
|
|
|
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
@mock.patch.object(BaseDistribution, "read_text", return_value="{}")
|
|
|
|
def test_dist_get_direct_url_invalid_json(
|
|
|
|
mock_read_text: mock.Mock, caplog: pytest.LogCaptureFixture
|
|
|
|
) -> None:
|
2021-07-13 12:14:58 +02:00
|
|
|
class FakeDistribution(BaseDistribution):
|
2021-08-30 00:43:28 +02:00
|
|
|
canonical_name = cast(NormalizedName, "whatever") # Needed for error logging.
|
2021-07-13 12:14:58 +02:00
|
|
|
|
|
|
|
dist = FakeDistribution()
|
|
|
|
with caplog.at_level(logging.WARNING):
|
|
|
|
assert dist.direct_url is None
|
|
|
|
|
|
|
|
mock_read_text.assert_called_once_with(DIRECT_URL_METADATA_NAME)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert (
|
|
|
|
caplog.records[-1]
|
|
|
|
.getMessage()
|
|
|
|
.startswith(
|
|
|
|
"Error parsing direct_url.json for whatever:",
|
|
|
|
)
|
2021-07-13 12:14:58 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2022-06-04 11:12:18 +02:00
|
|
|
def test_metadata_reads_egg_info_requires_txt(tmp_path: Path) -> None:
|
|
|
|
"""Check Requires-Dist is obtained from requires.txt if absent in PKG-INFO."""
|
|
|
|
egg_info_path = tmp_path / "whatever.egg-info"
|
|
|
|
egg_info_path.mkdir()
|
|
|
|
dist = get_directory_distribution(str(egg_info_path))
|
|
|
|
assert dist.installed_with_setuptools_egg_info
|
|
|
|
pkg_info_path = egg_info_path / "PKG-INFO"
|
|
|
|
pkg_info_path.write_text("Name: whatever\n")
|
|
|
|
egg_info_path.joinpath("requires.txt").write_text("pkga\npkgb\n")
|
|
|
|
assert dist.metadata.get_all("Requires-Dist") == ["pkga", "pkgb"]
|
|
|
|
|
|
|
|
|
|
|
|
def test_metadata_pkg_info_requires_priority(tmp_path: Path) -> None:
|
|
|
|
"""Check Requires-Dist in PKG-INFO has priority over requires.txt."""
|
|
|
|
egg_info_path = tmp_path / "whatever.egg-info"
|
|
|
|
egg_info_path.mkdir()
|
|
|
|
dist = get_directory_distribution(str(egg_info_path))
|
|
|
|
assert dist.installed_with_setuptools_egg_info
|
|
|
|
pkg_info_path = egg_info_path / "PKG-INFO"
|
|
|
|
pkg_info_path.write_text(
|
|
|
|
"Name: whatever\nRequires-Dist: pkgc\nRequires-Dist: pkgd\n"
|
|
|
|
)
|
|
|
|
egg_info_path.joinpath("requires.txt").write_text("pkga\npkgb\n")
|
|
|
|
assert dist.metadata.get_all("Requires-Dist") == ["pkgc", "pkgd"]
|
|
|
|
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
@mock.patch.object(
|
2021-07-13 12:14:58 +02:00
|
|
|
BaseDistribution,
|
|
|
|
"read_text",
|
|
|
|
return_value='{"url": "https://e.c/p.tgz", "archive_info": {}}',
|
|
|
|
)
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_dist_get_direct_url_valid_metadata(mock_read_text: mock.Mock) -> None:
|
|
|
|
class FakeDistribution(BaseDistribution):
|
|
|
|
pass
|
|
|
|
|
|
|
|
dist = FakeDistribution()
|
2021-07-13 12:14:58 +02:00
|
|
|
direct_url = dist.direct_url
|
2021-08-30 00:43:28 +02:00
|
|
|
assert direct_url is not None
|
2021-07-13 12:14:58 +02:00
|
|
|
mock_read_text.assert_called_once_with(DIRECT_URL_METADATA_NAME)
|
|
|
|
assert direct_url.url == "https://e.c/p.tgz"
|
|
|
|
assert isinstance(direct_url.info, ArchiveInfo)
|