summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Dufresne <jon.dufresne@gmail.com>2021-08-25 07:02:26 -0700
committerJon Dufresne <jon.dufresne@gmail.com>2021-08-27 09:25:22 -0700
commit34a3838b733275e2cd221d3264a6fdf9f7160827 (patch)
tree65eaca359d18d8ff51cbdd09106c895121386317
parented9c0d96ecdea27ff0cef04dd68cc7697fba6201 (diff)
downloadpip-34a3838b733275e2cd221d3264a6fdf9f7160827.tar.gz
Complete typing of some tests/lib/* files
-rw-r--r--news/06d03f6d-b858-4973-af59-2a8bbad0f6dc.trivial.rst0
-rw-r--r--src/pip/_internal/cli/base_command.py2
-rw-r--r--tests/lib/direct_url.py4
-rw-r--r--tests/lib/filesystem.py9
-rw-r--r--tests/lib/index.py6
-rw-r--r--tests/lib/options_helpers.py11
-rw-r--r--tests/lib/path.py72
-rw-r--r--tests/lib/venv.py47
8 files changed, 89 insertions, 62 deletions
diff --git a/news/06d03f6d-b858-4973-af59-2a8bbad0f6dc.trivial.rst b/news/06d03f6d-b858-4973-af59-2a8bbad0f6dc.trivial.rst
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/news/06d03f6d-b858-4973-af59-2a8bbad0f6dc.trivial.rst
diff --git a/src/pip/_internal/cli/base_command.py b/src/pip/_internal/cli/base_command.py
index eea38306a..200b8e47e 100644
--- a/src/pip/_internal/cli/base_command.py
+++ b/src/pip/_internal/cli/base_command.py
@@ -88,7 +88,7 @@ class Command(CommandContextMixIn):
def run(self, options: Values, args: List[Any]) -> int:
raise NotImplementedError
- def parse_args(self, args: List[str]) -> Tuple[Any, Any]:
+ def parse_args(self, args: List[str]) -> Tuple[Values, List[str]]:
# factored out for testability
return self.parser.parse_args(args)
diff --git a/tests/lib/direct_url.py b/tests/lib/direct_url.py
index 497e10c6b..7f1dee8bd 100644
--- a/tests/lib/direct_url.py
+++ b/tests/lib/direct_url.py
@@ -1,9 +1,11 @@
import re
+from typing import Optional
from pip._internal.models.direct_url import DIRECT_URL_METADATA_NAME, DirectUrl
+from tests.lib import TestPipResult
-def get_created_direct_url(result, pkg):
+def get_created_direct_url(result: TestPipResult, pkg: str) -> Optional[DirectUrl]:
direct_url_metadata_re = re.compile(
pkg + r"-[\d\.]+\.dist-info." + DIRECT_URL_METADATA_NAME + r"$"
)
diff --git a/tests/lib/filesystem.py b/tests/lib/filesystem.py
index 05e2db62c..84a1c81bd 100644
--- a/tests/lib/filesystem.py
+++ b/tests/lib/filesystem.py
@@ -6,11 +6,12 @@ import subprocess
import sys
from functools import partial
from itertools import chain
+from typing import Iterator, List, Set
from .path import Path
-def make_socket_file(path):
+def make_socket_file(path: str) -> None:
# Socket paths are limited to 108 characters (sometimes less) so we
# chdir before creating it and use a relative path name.
cwd = os.getcwd()
@@ -22,7 +23,7 @@ def make_socket_file(path):
os.chdir(cwd)
-def make_unreadable_file(path):
+def make_unreadable_file(path: str) -> None:
Path(path).touch()
os.chmod(path, 0o000)
if sys.platform == "win32":
@@ -34,8 +35,8 @@ def make_unreadable_file(path):
subprocess.check_call(args)
-def get_filelist(base):
- def join(dirpath, dirnames, filenames):
+def get_filelist(base: str) -> Set[str]:
+ def join(dirpath: str, dirnames: List[str], filenames: List[str]) -> Iterator[str]:
relative_dirpath = os.path.relpath(dirpath, base)
join_dirpath = partial(os.path.join, relative_dirpath)
return chain(
diff --git a/tests/lib/index.py b/tests/lib/index.py
index dff0ac103..17282bc56 100644
--- a/tests/lib/index.py
+++ b/tests/lib/index.py
@@ -1,8 +1,12 @@
+from typing import Optional
+
from pip._internal.models.candidate import InstallationCandidate
from pip._internal.models.link import Link
-def make_mock_candidate(version, yanked_reason=None, hex_digest=None):
+def make_mock_candidate(
+ version: str, yanked_reason: Optional[str] = None, hex_digest: Optional[str] = None
+) -> InstallationCandidate:
url = f"https://example.com/pkg-{version}.tar.gz"
if hex_digest is not None:
assert len(hex_digest) == 64
diff --git a/tests/lib/options_helpers.py b/tests/lib/options_helpers.py
index 8aa105b96..31f650035 100644
--- a/tests/lib/options_helpers.py
+++ b/tests/lib/options_helpers.py
@@ -1,13 +1,18 @@
"""Provides helper classes for testing option handling in pip
"""
+from optparse import Values
+from typing import List, Tuple
+
from pip._internal.cli import cmdoptions
from pip._internal.cli.base_command import Command
from pip._internal.commands import CommandInfo, commands_dict
class FakeCommand(Command):
- def main(self, args):
+ def main( # type: ignore[override]
+ self, args: List[str]
+ ) -> Tuple[Values, List[str]]:
index_opts = cmdoptions.make_option_group(
cmdoptions.index_group,
self.parser,
@@ -17,12 +22,12 @@ class FakeCommand(Command):
class AddFakeCommandMixin:
- def setup(self):
+ def setup(self) -> None:
commands_dict["fake"] = CommandInfo(
"tests.lib.options_helpers",
"FakeCommand",
"fake summary",
)
- def teardown(self):
+ def teardown(self) -> None:
commands_dict.pop("fake")
diff --git a/tests/lib/path.py b/tests/lib/path.py
index 8ea042071..ea8c819ec 100644
--- a/tests/lib/path.py
+++ b/tests/lib/path.py
@@ -1,12 +1,7 @@
-# flake8: noqa
# Author: Aziz Köksal
import glob
import os
-
-try:
- from os import supports_fd
-except ImportError:
- supports_fd = set()
+from typing import Iterable, Iterator, Union
class Path(str):
@@ -20,12 +15,12 @@ class Path(str):
# Separator in the PATH environment variable.
pathsep = os.pathsep
- def __new__(cls, *paths):
+ def __new__(cls, *paths: str) -> "Path":
if len(paths):
return super().__new__(cls, os.path.join(*paths))
return super().__new__(cls)
- def __div__(self, path):
+ def __div__(self, path: str) -> "Path":
"""
Joins this path with another path.
@@ -36,7 +31,7 @@ class Path(str):
__truediv__ = __div__
- def __rdiv__(self, path):
+ def __rdiv__(self, path: str) -> "Path":
"""
Joins this path with another path.
@@ -46,7 +41,7 @@ class Path(str):
__rtruediv__ = __rdiv__
- def __idiv__(self, path):
+ def __idiv__(self, path: str) -> "Path":
"""
Like __div__ but also assigns to the variable.
@@ -56,52 +51,52 @@ class Path(str):
__itruediv__ = __idiv__
- def __add__(self, path):
+ def __add__(self, path: str) -> "Path":
"""
>>> Path('/home/a') + 'bc.d'
'/home/abc.d'
"""
return Path(str(self) + path)
- def __radd__(self, path):
+ def __radd__(self, path: str) -> "Path":
"""
>>> '/home/a' + Path('bc.d')
'/home/abc.d'
"""
return Path(path + str(self))
- def __repr__(self):
+ def __repr__(self) -> str:
return "Path({inner})".format(inner=str.__repr__(self))
@property
- def name(self):
+ def name(self) -> str:
"""
'/home/a/bc.d' -> 'bc.d'
"""
return os.path.basename(self)
@property
- def stem(self):
+ def stem(self) -> str:
"""
'/home/a/bc.d' -> 'bc'
"""
return Path(os.path.splitext(self)[0]).name
@property
- def suffix(self):
+ def suffix(self) -> str:
"""
'/home/a/bc.d' -> '.d'
"""
return Path(os.path.splitext(self)[1])
- def resolve(self):
+ def resolve(self) -> "Path":
"""
Resolves symbolic links.
"""
return Path(os.path.realpath(self))
@property
- def parent(self):
+ def parent(self) -> "Path":
"""
Returns the parent directory of this path.
@@ -111,13 +106,18 @@ class Path(str):
"""
return Path(os.path.dirname(self))
- def exists(self):
+ def exists(self) -> bool:
"""
Returns True if the path exists.
"""
return os.path.exists(self)
- def mkdir(self, mode=0x1FF, exist_ok=False, parents=False): # 0o777
+ def mkdir(
+ self,
+ mode: int = 0o777,
+ exist_ok: bool = False,
+ parents: bool = False,
+ ) -> None:
"""
Creates a directory, if it doesn't exist already.
@@ -131,32 +131,32 @@ class Path(str):
if not exist_ok or not os.path.isdir(self):
raise
- def unlink(self):
+ def unlink(self) -> None:
"""
Removes a file.
"""
- return os.remove(self)
+ os.remove(self)
- def rmdir(self):
+ def rmdir(self) -> None:
"""
Removes a directory.
"""
- return os.rmdir(self)
+ os.rmdir(self)
- def rename(self, to):
+ def rename(self, to: str) -> None:
"""
Renames a file or directory. May throw an OSError.
"""
- return os.rename(self, to)
+ os.rename(self, to)
- def glob(self, pattern):
+ def glob(self, pattern: str) -> Iterator["Path"]:
return (Path(i) for i in glob.iglob(self.joinpath(pattern)))
- def joinpath(self, *parts):
+ def joinpath(self, *parts: str) -> "Path":
return Path(self, *parts)
# TODO: Remove after removing inheritance from str.
- def join(self, *parts):
+ def join(self, parts: Iterable[str]) -> str:
raise RuntimeError("Path.join is invalid, use joinpath instead.")
def read_bytes(self) -> bytes:
@@ -167,23 +167,23 @@ class Path(str):
with open(self, "wb") as f:
f.write(content)
- def read_text(self):
+ def read_text(self) -> str:
with open(self, "r") as fp:
return fp.read()
- def write_text(self, content):
+ def write_text(self, content: str) -> None:
with open(self, "w") as fp:
fp.write(content)
- def touch(self):
+ def touch(self) -> None:
with open(self, "a") as fp:
- path = fp.fileno() if os.utime in supports_fd else self
- os.utime(path, None) # times is not optional on Python 2.7
+ path: Union[int, str] = fp.fileno() if os.utime in os.supports_fd else self
+ os.utime(path)
- def symlink_to(self, target):
+ def symlink_to(self, target: str) -> None:
os.symlink(target, self)
- def stat(self):
+ def stat(self) -> os.stat_result:
return os.stat(self)
diff --git a/tests/lib/venv.py b/tests/lib/venv.py
index e297d6462..8f5465ed8 100644
--- a/tests/lib/venv.py
+++ b/tests/lib/venv.py
@@ -4,11 +4,16 @@ import subprocess
import sys
import textwrap
import venv as _venv
+from typing import TYPE_CHECKING, Optional
import virtualenv as _virtualenv
from .path import Path
+if TYPE_CHECKING:
+ # Literal was introduced in Python 3.8.
+ from typing import Literal
+
class VirtualEnvironment:
"""
@@ -16,18 +21,28 @@ class VirtualEnvironment:
virtualenv but in the future it could use pyvenv.
"""
- def __init__(self, location, template=None, venv_type=None):
- assert template is None or venv_type is None
- assert venv_type in (None, "virtualenv", "venv")
+ def __init__(
+ self,
+ location: str,
+ template: Optional["VirtualEnvironment"] = None,
+ venv_type: 'Literal[None, "virtualenv", "venv"]' = None,
+ ):
self.location = Path(location)
- self._venv_type = venv_type or template._venv_type or "virtualenv"
+ assert template is None or venv_type is None
+ self._venv_type: Literal["virtualenv", "venv"]
+ if template is not None:
+ self._venv_type = template._venv_type
+ elif venv_type is not None:
+ self._venv_type = venv_type
+ else:
+ self._venv_type = "virtualenv"
self._user_site_packages = False
self._template = template
- self._sitecustomize = None
+ self._sitecustomize: Optional[str] = None
self._update_paths()
self._create()
- def _update_paths(self):
+ def _update_paths(self) -> None:
home, lib, inc, bin = _virtualenv.path_locations(self.location)
self.bin = Path(bin)
self.site = Path(lib) / "site-packages"
@@ -38,10 +53,10 @@ class VirtualEnvironment:
else:
self.lib = Path(lib)
- def __repr__(self):
+ def __repr__(self) -> str:
return f"<VirtualEnvironment {self.location}>"
- def _create(self, clear=False):
+ def _create(self, clear: bool = False) -> None:
if clear:
shutil.rmtree(self.location)
if self._template:
@@ -77,7 +92,7 @@ class VirtualEnvironment:
self.sitecustomize = self._sitecustomize
self.user_site_packages = self._user_site_packages
- def _fix_virtualenv_site_module(self):
+ def _fix_virtualenv_site_module(self) -> None:
# Patch `site.py` so user site work as expected.
site_py = self.lib / "site.py"
with open(site_py) as fp:
@@ -111,7 +126,7 @@ class VirtualEnvironment:
# Make sure bytecode is up-to-date too.
assert compileall.compile_file(str(site_py), quiet=1, force=True)
- def _customize_site(self):
+ def _customize_site(self) -> None:
contents = ""
if self._venv_type == "venv":
# Enable user site (before system).
@@ -149,29 +164,29 @@ class VirtualEnvironment:
# Make sure bytecode is up-to-date too.
assert compileall.compile_file(str(sitecustomize), quiet=1, force=True)
- def clear(self):
+ def clear(self) -> None:
self._create(clear=True)
- def move(self, location):
+ def move(self, location: str) -> None:
shutil.move(self.location, location)
self.location = Path(location)
self._update_paths()
@property
- def sitecustomize(self):
+ def sitecustomize(self) -> Optional[str]:
return self._sitecustomize
@sitecustomize.setter
- def sitecustomize(self, value):
+ def sitecustomize(self, value: str) -> None:
self._sitecustomize = value
self._customize_site()
@property
- def user_site_packages(self):
+ def user_site_packages(self) -> bool:
return self._user_site_packages
@user_site_packages.setter
- def user_site_packages(self, value):
+ def user_site_packages(self, value: bool) -> None:
self._user_site_packages = value
if self._venv_type == "virtualenv":
marker = self.lib / "no-global-site-packages.txt"