mirror of https://github.com/pypa/pip
Complete typing of some tests/lib/* files
This commit is contained in:
parent
ed9c0d96ec
commit
34a3838b73
|
@ -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)
|
||||
|
||||
|
|
|
@ -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"$"
|
||||
)
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue