summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Benesch <4b796c65+github@gmail.com>2022-10-26 12:23:10 -0700
committerGitHub <noreply@github.com>2022-10-26 22:23:10 +0300
commitedcb32592a057012f7116f8ebdba530c44ced7d8 (patch)
tree6f3cc9be4d7f2441d9766ecec29b8840941b9074
parent9f2bfc62c76a5e646b533b8cc3ae7e4a67f68445 (diff)
downloadwheel-git-edcb32592a057012f7116f8ebdba530c44ced7d8.tar.gz
Added tests to type checking and finish annotations. (#477)
-rw-r--r--setup.cfg6
-rw-r--r--src/wheel/__main__.py5
-rw-r--r--src/wheel/_bdist_wheel.py28
-rw-r--r--src/wheel/_cli/__init__.py14
-rwxr-xr-xsrc/wheel/_cli/convert.py2
-rw-r--r--src/wheel/_cli/pack.py4
-rw-r--r--src/wheel/_cli/unpack.py2
-rw-r--r--src/wheel/_macosx_libfile.py4
-rw-r--r--src/wheel/_metadata.py2
-rw-r--r--src/wheel/_wheelfile.py31
-rw-r--r--tests/cli/test_pack.py4
-rw-r--r--tests/cli/test_unpack.py6
-rw-r--r--tests/conftest.py6
-rw-r--r--tests/test_macosx_libfile.py21
-rw-r--r--tests/test_metadata.py4
15 files changed, 81 insertions, 58 deletions
diff --git a/setup.cfg b/setup.cfg
index 47d5a4f..966d539 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -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"),