/
niceSOFT
/
python3-wheel
Обзор
Документация
Войти
/
niceSOFT
/
python3-wheel
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
tests/commands/test_info.py
200 строк
6 KB
Quaylyn Rimer
Added the wheel info subcommand (#669)
15 фев 2026, 21:18
Не верифицирован
15 фев 2026, 21:18
0ce509e
Код
Авторство
О чём код?
from __future__ import annotations import base64 import hashlib import os import shutil import sys import zipfile from io import StringIO from unittest.mock import patch import pytest from wheel._commands.info import info from .util import run_command THISDIR = os.path.dirname(__file__) TESTWHEEL_NAME = "test-1.0-py2.py3-none-any.whl" TESTWHEEL_PATH = os.path.join(THISDIR, "..", "testdata", TESTWHEEL_NAME) def _build_wheel_with_modified_metadata( src_whl: str, dest_dir: os.PathLike[str], wheel_content: str ) -> str: """Copy a wheel and replace its WHEEL metadata, updating the RECORD hash. Returns the path to the new wheel file. """ dest_whl = os.path.join(dest_dir, os.path.basename(src_whl)) shutil.copy2(src_whl, dest_whl) with zipfile.ZipFile(dest_whl, "r") as zr: wheel_path = record_path = None for name in zr.namelist(): if name.endswith("/WHEEL"): wheel_path = name elif name.endswith("/RECORD"): record_path = name assert wheel_path is not None assert record_path is not None original_record = zr.read(record_path).decode() modified_bytes = wheel_content.encode() # Compute new hash and size for the WHEEL file digest = hashlib.sha256(modified_bytes).digest() hash_str = "sha256=" + base64.urlsafe_b64encode(digest).rstrip(b"=").decode() size_str = str(len(modified_bytes)) # Update the RECORD with the new hash for the WHEEL file new_record_lines = [] for line in original_record.splitlines(): if line.startswith(wheel_path): new_record_lines.append(f"{wheel_path},{hash_str},{size_str}") else: new_record_lines.append(line) modified_record = "\n".join(new_record_lines) + "\n" # Rewrite the wheel with the modified WHEEL file and updated RECORD tmp_whl = os.path.join(dest_dir, "tmp.whl") with zipfile.ZipFile(dest_whl, "r") as zr, zipfile.ZipFile(tmp_whl, "w") as zw: for item in zr.infolist(): if item.filename == wheel_path: zw.writestr(item, modified_bytes) elif item.filename == record_path: zw.writestr(item, modified_record.encode()) else: zw.writestr(item, zr.read(item.filename)) os.replace(tmp_whl, dest_whl) return dest_whl def _capture_info_output(wheel_path: str, verbose: bool = False) -> str: """Run info() and capture its stdout.""" stdout = StringIO() with patch.object(sys, "stdout", stdout): info(wheel_path, verbose=verbose) return stdout.getvalue() def test_info_basic() -> None: """Test basic wheel info display.""" output = run_command("info", TESTWHEEL_PATH) # Check basic package information is displayed assert "Name: test" in output assert "Version: 1.0" in output assert "Wheel-Version: 1.0" in output assert "Root-Is-Purelib: false" in output # Check tags are displayed assert "Tags:" in output assert "py2-none-any" in output assert "py3-none-any" in output # Check metadata is displayed assert "Summary: Test module" in output assert "Author: Paul Moore" in output assert "Author-email: test@example.com" in output assert "Home-page: http://test.example.com/" in output assert "License: MIT License" in output # Check file information assert "Files: 14" in output assert "Size: 8,114 bytes" in output def test_info_generator() -> None: """Test that a single Generator value is displayed.""" output = run_command("info", TESTWHEEL_PATH) assert "Generator: bdist_wheel (0.30.0)" in output def test_info_multiple_generators(tmp_path: os.PathLike[str]) -> None: """Test that multiple Generator values are each displayed on their own line.""" wheel_content = ( "Wheel-Version: 1.0\n" "Generator: bdist_wheel (0.30.0)\n" "Generator: auditwheel (6.0.0)\n" "Root-Is-Purelib: false\n" "Tag: py2-none-any\n" "Tag: py3-none-any\n" ) whl = _build_wheel_with_modified_metadata( TESTWHEEL_PATH, str(tmp_path), wheel_content ) output = _capture_info_output(whl) assert "Generator: bdist_wheel (0.30.0)" in output assert "Generator: auditwheel (6.0.0)" in output # Ensure exactly two Generator lines are printed assert output.count("Generator:") == 2 def test_info_no_generator(tmp_path: os.PathLike[str]) -> None: """Test that missing Generator values produce no Generator lines.""" wheel_content = ( "Wheel-Version: 1.0\n" "Root-Is-Purelib: false\n" "Tag: py2-none-any\n" "Tag: py3-none-any\n" ) whl = _build_wheel_with_modified_metadata( TESTWHEEL_PATH, str(tmp_path), wheel_content ) output = _capture_info_output(whl) assert "Generator" not in output def test_info_verbose() -> None: """Test verbose wheel info display with file listing.""" output = run_command("info", "--verbose", TESTWHEEL_PATH) # Check that basic info is still there assert "Name: test" in output assert "Version: 1.0" in output # Check that file listing is included assert "File listing:" in output assert "hello/hello.py" in output assert "hello.pyd" in output assert "test-1.0.dist-info/METADATA" in output assert "test-1.0.dist-info/WHEEL" in output assert "test-1.0.dist-info/RECORD" in output # Check file sizes are displayed assert "6,656 bytes" in output # hello.pyd assert "42 bytes" in output # hello.py def test_info_nonexistent_file() -> None: """Test info command with non-existent wheel file.""" from wheel._commands.info import info with pytest.raises( FileNotFoundError, match="Wheel file not found: nonexistent.whl" ): info("nonexistent.whl") def test_info_help() -> None: """Test info command help.""" output = run_command("info", "--help") assert "info" in output assert "Wheel file to show information for" in output assert "wheelfile" in output assert "--verbose" in output def test_info_short_verbose_flag() -> None: """Test that -v works as alias for --verbose.""" output = run_command("info", "-v", TESTWHEEL_PATH) # Should include file listing like --verbose assert "File listing:" in output assert "hello/hello.py" in output