diff options
| author | Kyle Benesch <4b796c65+github@gmail.com> | 2022-10-26 12:23:10 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-26 22:23:10 +0300 |
| commit | edcb32592a057012f7116f8ebdba530c44ced7d8 (patch) | |
| tree | 6f3cc9be4d7f2441d9766ecec29b8840941b9074 | |
| parent | 9f2bfc62c76a5e646b533b8cc3ae7e4a67f68445 (diff) | |
| download | wheel-git-edcb32592a057012f7116f8ebdba530c44ced7d8.tar.gz | |
Added tests to type checking and finish annotations. (#477)
| -rw-r--r-- | setup.cfg | 6 | ||||
| -rw-r--r-- | src/wheel/__main__.py | 5 | ||||
| -rw-r--r-- | src/wheel/_bdist_wheel.py | 28 | ||||
| -rw-r--r-- | src/wheel/_cli/__init__.py | 14 | ||||
| -rwxr-xr-x | src/wheel/_cli/convert.py | 2 | ||||
| -rw-r--r-- | src/wheel/_cli/pack.py | 4 | ||||
| -rw-r--r-- | src/wheel/_cli/unpack.py | 2 | ||||
| -rw-r--r-- | src/wheel/_macosx_libfile.py | 4 | ||||
| -rw-r--r-- | src/wheel/_metadata.py | 2 | ||||
| -rw-r--r-- | src/wheel/_wheelfile.py | 31 | ||||
| -rw-r--r-- | tests/cli/test_pack.py | 4 | ||||
| -rw-r--r-- | tests/cli/test_unpack.py | 6 | ||||
| -rw-r--r-- | tests/conftest.py | 6 | ||||
| -rw-r--r-- | tests/test_macosx_libfile.py | 21 | ||||
| -rw-r--r-- | tests/test_metadata.py | 4 |
15 files changed, 81 insertions, 58 deletions
@@ -43,7 +43,8 @@ test = setuptools >= 57 types = mypy >= 0.982 - types-setuptools >= 65.5.0.1 + pytest >= 6.2 + types-setuptools >= 65.5.0.2 [options.entry_points] console_scripts = @@ -71,8 +72,9 @@ omit = */vendored/* show_missing = true [mypy] -files = src +files = src,tests python_version = 3.7 +exclude = testdata/ [mypy-wheel.vendored.*] ignore_errors = True diff --git a/src/wheel/__main__.py b/src/wheel/__main__.py index 2371845..a4b5e0d 100644 --- a/src/wheel/__main__.py +++ b/src/wheel/__main__.py @@ -5,9 +5,10 @@ Wheel command line tool (enable python -m wheel syntax) from __future__ import annotations import sys +from typing import NoReturn -def main(): # needed for console script +def main() -> NoReturn: # needed for console script if __package__ == "": # To be able to run 'python wheel-0.9.whl/wheel': import os.path @@ -20,4 +21,4 @@ def main(): # needed for console script if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/src/wheel/_bdist_wheel.py b/src/wheel/_bdist_wheel.py index adc7736..b2e9ea3 100644 --- a/src/wheel/_bdist_wheel.py +++ b/src/wheel/_bdist_wheel.py @@ -17,6 +17,8 @@ from logging import getLogger from pathlib import Path from shutil import rmtree from sysconfig import get_config_var +from types import TracebackType +from typing import Any, Callable import pkg_resources from setuptools import Command @@ -109,7 +111,11 @@ def safer_version(version: str) -> str: return safe_version(version).replace("-", "_") -def remove_readonly(func, path, excinfo) -> None: +def remove_readonly( + func: Callable[..., Any], + path: Any, + excinfo: tuple[type[BaseException], BaseException, TracebackType], +) -> None: print(str(excinfo[1])) os.chmod(path, stat.S_IWRITE) func(path) @@ -171,22 +177,22 @@ class bdist_wheel(Command): boolean_options = ["keep-temp", "skip-build", "relative", "universal"] - def initialize_options(self): - self.bdist_dir = None - self.data_dir = None - self.plat_name = None - self.plat_tag = None + def initialize_options(self) -> None: + self.bdist_dir: Any = None + self.data_dir: Any = None + self.plat_name: Any = None + self.plat_tag: Any = None self.keep_temp = False - self.dist_dir = None - self.egginfo_dir = None - self.root_is_pure = None - self.skip_build = None + self.dist_dir: Any = None + self.egginfo_dir: Any = None + self.root_is_pure: Any = None + self.skip_build: None | bool = None self.relative = False self.universal = False self.compression = "deflated" self.python_tag = python_tag() self.build_number = None - self.py_limited_api = False + self.py_limited_api: Any = False self.plat_name_supplied = False def finalize_options(self) -> None: diff --git a/src/wheel/_cli/__init__.py b/src/wheel/_cli/__init__.py index d8dfda2..957da24 100644 --- a/src/wheel/_cli/__init__.py +++ b/src/wheel/_cli/__init__.py @@ -4,41 +4,41 @@ Wheel command-line utility. from __future__ import annotations -import argparse import os import sys +from argparse import ArgumentParser, Namespace class WheelError(Exception): pass -def unpack_f(args): +def unpack_f(args: Namespace) -> None: from .unpack import unpack unpack(args.wheelfile, args.dest) -def pack_f(args): +def pack_f(args: Namespace) -> None: from .pack import pack pack(args.directory, args.dest_dir, args.build_number) -def convert_f(args): +def convert_f(args: Namespace) -> None: from .convert import convert convert(args.files, args.dest_dir, args.verbose) -def version_f(args): +def version_f(args: Namespace) -> None: from .. import __version__ print(f"wheel {__version__}") -def parser(): - p = argparse.ArgumentParser() +def parser() -> ArgumentParser: + p = ArgumentParser() s = p.add_subparsers(help="commands") unpack_parser = s.add_parser("unpack", help="Unpack wheel") diff --git a/src/wheel/_cli/convert.py b/src/wheel/_cli/convert.py index 1b1bf7f..bdcf6a8 100755 --- a/src/wheel/_cli/convert.py +++ b/src/wheel/_cli/convert.py @@ -102,7 +102,7 @@ def egg2wheel(egg_path: Path, dest_dir: Path) -> None: def convert( - files: Iterable[str | PathLike], dest_dir: str | PathLike, verbose: bool + files: Iterable[str | PathLike[str]], dest_dir: str | PathLike[str], verbose: bool ) -> None: dest_path = Path(dest_dir) paths: list[Path] = [] diff --git a/src/wheel/_cli/pack.py b/src/wheel/_cli/pack.py index 0bc14b6..eb12056 100644 --- a/src/wheel/_cli/pack.py +++ b/src/wheel/_cli/pack.py @@ -12,7 +12,9 @@ BUILD_NUM_RE = re.compile(rb"Build: (\d\w*)$") def pack( - directory: str | PathLike, dest_dir: str | PathLike, build_number: str | None = None + directory: str | PathLike[str], + dest_dir: str | PathLike[str], + build_number: str | None = None, ) -> None: """Repack a previously unpacked wheel directory into a new wheel file. diff --git a/src/wheel/_cli/unpack.py b/src/wheel/_cli/unpack.py index 530179a..9b14b49 100644 --- a/src/wheel/_cli/unpack.py +++ b/src/wheel/_cli/unpack.py @@ -6,7 +6,7 @@ from pathlib import Path from .. import WheelReader -def unpack(path: str | PathLike, dest: str | PathLike = ".") -> None: +def unpack(path: str | PathLike[str], dest: str | PathLike[str] = ".") -> None: """Unpack a wheel. Wheel content will be unpacked to {dest}/{name}-{ver}, where {name} diff --git a/src/wheel/_macosx_libfile.py b/src/wheel/_macosx_libfile.py index 348d673..2b9e636 100644 --- a/src/wheel/_macosx_libfile.py +++ b/src/wheel/_macosx_libfile.py @@ -273,7 +273,9 @@ def get_base_class_and_magic_number( return BaseClass, magic_number -def read_data(struct_class: type[ctypes.Structure], lib_file: BinaryIO): +def read_data( + struct_class: type[ctypes.Structure], lib_file: BinaryIO +) -> ctypes.Structure: return struct_class.from_buffer_copy(lib_file.read(ctypes.sizeof(struct_class))) diff --git a/src/wheel/_metadata.py b/src/wheel/_metadata.py index 980c963..a6a6bb5 100644 --- a/src/wheel/_metadata.py +++ b/src/wheel/_metadata.py @@ -83,8 +83,6 @@ def pkginfo_to_metadata(pkginfo_path: Path) -> list[tuple[str, str]]: requires = requires_path.read_text() parsed_requirements = sorted(split_sections(requires), key=lambda x: x[0] or "") for extra, reqs in parsed_requirements: - # Remove assert when https://github.com/python/typeshed/pull/8975 is merged. - assert isinstance(reqs, list) for key, value in generate_requirements({extra or "": reqs}): if (key, value) not in pkg_info.items(): pkg_info[key] = value diff --git a/src/wheel/_wheelfile.py b/src/wheel/_wheelfile.py index c34d2e6..63ef550 100644 --- a/src/wheel/_wheelfile.py +++ b/src/wheel/_wheelfile.py @@ -25,9 +25,9 @@ from .vendored.packaging.tags import Tag from .vendored.packaging.utils import ( InvalidWheelFilename, NormalizedName, - Version, parse_wheel_filename, ) +from .vendored.packaging.version import Version _DIST_NAME_RE = re.compile(r"[^A-Za-z0-9.]+") _EXCLUDE_FILENAMES = ("RECORD", "RECORD.jws", "RECORD.p7s") @@ -124,10 +124,15 @@ class WheelArchiveFile: return data - def __enter__(self): + def __enter__(self) -> WheelArchiveFile: return self - def __exit__(self, exc_type, exc_val, exc_tb): + def __exit__( + self, + exc_type: type[BaseException], + exc_val: BaseException, + exc_tb: TracebackType, + ) -> None: self._fp.close() def __repr__(self) -> str: @@ -140,7 +145,7 @@ class WheelReader: _zip: ZipFile _record_entries: OrderedDict[str, WheelRecordEntry] - def __init__(self, path_or_fd: str | PathLike | IO[bytes]): + def __init__(self, path_or_fd: str | PathLike[str] | IO[bytes]): self.path_or_fd = path_or_fd if isinstance(path_or_fd, (str, PathLike)): @@ -219,11 +224,11 @@ class WheelReader: return entries @property - def dist_info_dir(self): + def dist_info_dir(self) -> str: return self._dist_info_dir @property - def data_dir(self): + def data_dir(self) -> str: return self._data_dir @property @@ -274,7 +279,7 @@ class WheelReader: if hash_.digest() != record.hash_value: raise WheelError(f"Hash mismatch for file {zinfo.filename!r}") - def extractall(self, base_path: str | PathLike) -> None: + def extractall(self, base_path: str | PathLike[str]) -> None: basedir = Path(base_path) if not basedir.exists(): raise WheelError(f"{basedir} does not exist") @@ -315,14 +320,14 @@ class WheelReader: archive_path = self._dist_info_dir + "/" + filename.strip("/") return self._read_file(archive_path) - def __repr__(self): + def __repr__(self) -> str: return f"{self.__class__.__name__}({self.path_or_fd})" class WheelWriter: def __init__( self, - path_or_fd: str | PathLike | IO[bytes], + path_or_fd: str | PathLike[str] | IO[bytes], metadata: WheelMetadata | None = None, *, generator: str | None = None, @@ -431,7 +436,7 @@ class WheelWriter: def write_file( self, name: str | PurePath, - contents: bytes | str | PathLike | IO[bytes], + contents: bytes | str | PathLike[str] | IO[bytes], timestamp: datetime = DEFAULT_TIMESTAMP, ) -> None: arcname = PurePath(name).as_posix() @@ -474,7 +479,7 @@ class WheelWriter: self.hash_algorithm, hash_.digest(), file_size ) - def write_files_from_directory(self, directory: str | PathLike) -> None: + def write_files_from_directory(self, directory: str | PathLike[str]) -> None: basedir = Path(directory) if not basedir.exists(): raise WheelError(f"{basedir} does not exist") @@ -491,7 +496,7 @@ class WheelWriter: def write_data_file( self, filename: str, - contents: bytes | str | PathLike | IO[bytes], + contents: bytes | str | PathLike[str] | IO[bytes], timestamp: datetime = DEFAULT_TIMESTAMP, ) -> None: archive_path = self._data_dir + "/" + filename.strip("/") @@ -506,5 +511,5 @@ class WheelWriter: archive_path = self._dist_info_dir + "/" + filename.strip() self.write_file(archive_path, contents, timestamp) - def __repr__(self): + def __repr__(self) -> str: return f"{self.__class__.__name__}({self.path_or_fd!r})" diff --git a/tests/cli/test_pack.py b/tests/cli/test_pack.py index 67db32c..74fd937 100644 --- a/tests/cli/test_pack.py +++ b/tests/cli/test_pack.py @@ -81,5 +81,5 @@ def test_pack( if expected_build_num: expected_wheel_content += "Build: %s\r\n" % expected_build_num - expected_wheel_content = expected_wheel_content.encode("ascii") - assert new_wheel_file_content == expected_wheel_content + expected_wheel_content_bytes = expected_wheel_content.encode("ascii") + assert new_wheel_file_content == expected_wheel_content_bytes diff --git a/tests/cli/test_unpack.py b/tests/cli/test_unpack.py index dcbc4c1..ce28ff0 100644 --- a/tests/cli/test_unpack.py +++ b/tests/cli/test_unpack.py @@ -1,12 +1,14 @@ from __future__ import annotations +from pathlib import Path + from wheel._cli.unpack import unpack -def test_unpack(wheel_paths, tmp_path): +def test_unpack(wheel_paths: list[Path], tmp_path: Path) -> None: """ Make sure 'wheel unpack' works. This also verifies the integrity of our testing wheel files. """ for wheel_path in wheel_paths: - unpack(wheel_path, str(tmp_path)) + unpack(wheel_path, tmp_path) diff --git a/tests/conftest.py b/tests/conftest.py index af1d1fd..546706a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -16,17 +16,17 @@ from pytest import TempPathFactory @pytest.fixture(scope="session") def wheels_and_eggs(tmp_path_factory: TempPathFactory) -> list[Path]: """Build wheels and eggs from test distributions.""" - test_distributions = ( + test_distributions = [ "complex-dist", "simple.dist", "headers.dist", "commasinfilenames.dist", "unicode.dist", - ) + ] if sys.platform != "win32": # ABI3 extensions don't really work on Windows - test_distributions += ("abi3extension.dist",) + test_distributions.append("abi3extension.dist") this_dir = Path(__file__).parent build_dir = tmp_path_factory.mktemp("build") diff --git a/tests/test_macosx_libfile.py b/tests/test_macosx_libfile.py index b122928..a49e720 100644 --- a/tests/test_macosx_libfile.py +++ b/tests/test_macosx_libfile.py @@ -4,13 +4,15 @@ import os import sys import sysconfig from collections.abc import Callable -from typing import Any +from typing import Any, TypeVar from pytest import CaptureFixture, MonkeyPatch from wheel._bdist_wheel import get_platform from wheel._macosx_libfile import extract_macosx_min_system_version +T = TypeVar("T") + def test_read_from_dylib() -> None: dirname = os.path.dirname(__file__) @@ -34,6 +36,7 @@ def test_read_from_dylib() -> None: extracted = extract_macosx_min_system_version( os.path.join(dylib_dir, file_name) ) + assert extracted str_ver = ".".join([str(x) for x in extracted]) assert str_ver == ver assert ( @@ -44,8 +47,8 @@ def test_read_from_dylib() -> None: ) -def return_factory(return_val) -> Callable: - def fun(*args: Any, **kwargs: Any): +def return_factory(return_val: T) -> Callable[..., T]: + def fun(*args: Any, **kwargs: Any) -> T: return return_val return fun @@ -61,7 +64,7 @@ class TestGetPlatformMacosx: assert get_platform(dylib_dir) == "macosx_11_0_x86_64" def test_version_bump( - self, monkeypatch: MonkeyPatch, capsys: CaptureFixture + self, monkeypatch: MonkeyPatch, capsys: CaptureFixture[str] ) -> None: dirname = os.path.dirname(__file__) dylib_dir = os.path.join(dirname, "testdata", "macosx_minimal_system_version") @@ -73,7 +76,7 @@ class TestGetPlatformMacosx: assert "[WARNING] This wheel needs a higher macOS version than" in captured.err def test_information_about_problematic_files_python_version( - self, monkeypatch: MonkeyPatch, capsys: CaptureFixture + self, monkeypatch: MonkeyPatch, capsys: CaptureFixture[str] ) -> None: dirname = os.path.dirname(__file__) dylib_dir = os.path.join(dirname, "testdata", "macosx_minimal_system_version") @@ -96,7 +99,7 @@ class TestGetPlatformMacosx: assert "test_lib_10_10_fat.dylib" in captured.err def test_information_about_problematic_files_env_variable( - self, monkeypatch: MonkeyPatch, capsys: CaptureFixture + self, monkeypatch: MonkeyPatch, capsys: CaptureFixture[str] ) -> None: dirname = os.path.dirname(__file__) dylib_dir = os.path.join(dirname, "testdata", "macosx_minimal_system_version") @@ -118,7 +121,7 @@ class TestGetPlatformMacosx: assert "test_lib_10_10_fat.dylib" in captured.err def test_bump_platform_tag_by_env_variable( - self, monkeypatch: MonkeyPatch, capsys: CaptureFixture + self, monkeypatch: MonkeyPatch, capsys: CaptureFixture[str] ) -> None: dirname = os.path.dirname(__file__) dylib_dir = os.path.join(dirname, "testdata", "macosx_minimal_system_version") @@ -139,7 +142,7 @@ class TestGetPlatformMacosx: assert captured.err == "" def test_bugfix_release_platform_tag( - self, monkeypatch: MonkeyPatch, capsys: CaptureFixture + self, monkeypatch: MonkeyPatch, capsys: CaptureFixture[str] ) -> None: dirname = os.path.dirname(__file__) dylib_dir = os.path.join(dirname, "testdata", "macosx_minimal_system_version") @@ -172,7 +175,7 @@ class TestGetPlatformMacosx: assert "This wheel needs a higher macOS version than" in captured.err def test_warning_on_to_low_env_variable( - self, monkeypatch: MonkeyPatch, capsys: CaptureFixture + self, monkeypatch: MonkeyPatch, capsys: CaptureFixture[str] ) -> None: dirname = os.path.dirname(__file__) dylib_dir = os.path.join(dirname, "testdata", "macosx_minimal_system_version") diff --git a/tests/test_metadata.py b/tests/test_metadata.py index c463953..249c741 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -1,9 +1,11 @@ from __future__ import annotations +from pathlib import Path + from wheel._metadata import pkginfo_to_metadata -def test_pkginfo_to_metadata(tmp_path): +def test_pkginfo_to_metadata(tmp_path: Path) -> None: expected_metadata = [ ("Metadata-Version", "2.1"), ("Name", "spam"), |
