Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complete type annotations in "pip._internal.{build_env,self_outdated_check,exceptions}" #8296

Merged
merged 7 commits into from
May 31, 2020
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
38 changes: 29 additions & 9 deletions src/pip/_internal/build_env.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
"""Build Environment used for isolation during sdist building
"""

# The following comment should be removed at some point in the future.
# mypy: strict-optional=False
# mypy: disallow-untyped-defs=False

import logging
import os
import sys
Expand All @@ -22,7 +18,8 @@
from pip._internal.utils.typing import MYPY_CHECK_RUNNING

if MYPY_CHECK_RUNNING:
from typing import Tuple, Set, Iterable, Optional, List
from types import TracebackType
from typing import Tuple, Set, Iterable, Optional, List, Type
from pip._internal.index.package_finder import PackageFinder

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -110,6 +107,7 @@ def __init__(self):
).format(system_sites=system_sites, lib_dirs=self._lib_dirs))

def __enter__(self):
# type: () -> None
self._save_env = {
name: os.environ.get(name, None)
for name in ('PATH', 'PYTHONNOUSERSITE', 'PYTHONPATH')
Expand All @@ -128,7 +126,13 @@ def __enter__(self):
'PYTHONPATH': os.pathsep.join(pythonpath),
})

def __exit__(self, exc_type, exc_val, exc_tb):
def __exit__(
self,
exc_type, # type: Optional[Type[BaseException]]
exc_val, # type: Optional[BaseException]
exc_tb # type: Optional[TracebackType]
):
# type: (...) -> None
pradyunsg marked this conversation as resolved.
Show resolved Hide resolved
for varname, old_value in self._save_env.items():
if old_value is None:
os.environ.pop(varname, None)
Expand Down Expand Up @@ -159,7 +163,7 @@ def install_requirements(
finder, # type: PackageFinder
requirements, # type: Iterable[str]
prefix_as_string, # type: str
message # type: Optional[str]
message # type: str
):
# type: (...) -> None
prefix = self._prefixes[prefix_as_string]
Expand Down Expand Up @@ -204,16 +208,32 @@ class NoOpBuildEnvironment(BuildEnvironment):
"""

def __init__(self):
# type: () -> None
pass

def __enter__(self):
# type: () -> None
pass

def __exit__(self, exc_type, exc_val, exc_tb):
def __exit__(
self,
exc_type, # type: Optional[Type[BaseException]]
exc_val, # type: Optional[BaseException]
exc_tb # type: Optional[TracebackType]
):
# type: (...) -> None
pass

def cleanup(self):
# type: () -> None
pass

def install_requirements(self, finder, requirements, prefix, message):
def install_requirements(
self,
finder, # type: PackageFinder
requirements, # type: Iterable[str]
prefix_as_string, # type: str
message # type: str
):
# type: (...) -> None
raise NotImplementedError()
41 changes: 31 additions & 10 deletions src/pip/_internal/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
"""Exceptions used throughout package"""

# The following comment should be removed at some point in the future.
# mypy: disallow-untyped-defs=False

from __future__ import absolute_import

from itertools import chain, groupby, repeat
Expand All @@ -12,9 +9,15 @@
from pip._internal.utils.typing import MYPY_CHECK_RUNNING

if MYPY_CHECK_RUNNING:
from typing import Optional
from typing import Optional, List, Dict
from pip._vendor.pkg_resources import Distribution
from pip._vendor.six.moves import configparser
from pip._internal.req.req_install import InstallRequirement
from pip._vendor.six import PY3
if PY3:
from hashlib import _Hash
else:
from hashlib import _hash as _Hash


class PipError(Exception):
Expand Down Expand Up @@ -100,24 +103,30 @@ class HashErrors(InstallationError):
"""Multiple HashError instances rolled into one for reporting"""

def __init__(self):
self.errors = []
# type: () -> None
self.errors = [] # type: List[HashError]

def append(self, error):
# type: (HashError) -> None
self.errors.append(error)

def __str__(self):
# type: () -> str
lines = []
self.errors.sort(key=lambda e: e.order)
for cls, errors_of_cls in groupby(self.errors, lambda e: e.__class__):
lines.append(cls.head)
lines.extend(e.body() for e in errors_of_cls)
if lines:
return '\n'.join(lines)
return ''

def __nonzero__(self):
# type: () -> bool
return bool(self.errors)

def __bool__(self):
# type: () -> bool
return self.__nonzero__()


Expand All @@ -139,8 +148,10 @@ class HashError(InstallationError):
"""
req = None # type: Optional[InstallRequirement]
head = ''
order = None # type: Optional[int]

def body(self):
# type: () -> str
"""Return a summary of me for display under the heading.

This default implementation simply prints a description of the
Expand All @@ -153,9 +164,11 @@ def body(self):
return ' {}'.format(self._requirement_name())

def __str__(self):
# type: () -> str
return '{}\n{}'.format(self.head, self.body())

def _requirement_name(self):
# type: () -> str
"""Return a description of the requirement that triggered me.

This default implementation returns long description of the req, with
Expand Down Expand Up @@ -196,13 +209,15 @@ class HashMissing(HashError):
'has a hash.)')

def __init__(self, gotten_hash):
# type: (str) -> None
"""
:param gotten_hash: The hash of the (possibly malicious) archive we
just downloaded
"""
self.gotten_hash = gotten_hash
self.gotten_hash = gotten_hash # type: str

def body(self):
# type: () -> str
# Dodge circular import.
from pip._internal.utils.hashes import FAVORITE_HASH

Expand Down Expand Up @@ -245,20 +260,23 @@ class HashMismatch(HashError):
'someone may have tampered with them.')

def __init__(self, allowed, gots):
# type: (Dict[str, List[str]], Dict[str, _Hash]) -> None
"""
:param allowed: A dict of algorithm names pointing to lists of allowed
hex digests
:param gots: A dict of algorithm names pointing to hashes we
actually got from the files under suspicion
"""
self.allowed = allowed
self.gots = gots
self.allowed = allowed # type: Dict[str, List[str]]
self.gots = gots # type: Dict[str, _Hash]
deveshks marked this conversation as resolved.
Show resolved Hide resolved

def body(self):
# type: () -> str
return ' {}:\n{}'.format(self._requirement_name(),
self._hash_comparison())

def _hash_comparison(self):
# type: () -> str
"""
Return a comparison of actual and expected hash values.

Expand All @@ -270,11 +288,12 @@ def _hash_comparison(self):

"""
def hash_then_or(hash_name):
# type: (str) -> chain[str]
# For now, all the decent hashes have 6-char names, so we can get
# away with hard-coding space literals.
return chain([hash_name], repeat(' or'))

lines = []
lines = [] # type: List[str]
for hash_name, expecteds in iteritems(self.allowed):
prefix = hash_then_or(hash_name)
lines.extend((' Expected {} {}'.format(next(prefix), e))
Expand All @@ -294,15 +313,17 @@ class ConfigurationFileCouldNotBeLoaded(ConfigurationError):
"""

def __init__(self, reason="could not be loaded", fname=None, error=None):
# type: (str, Optional[str], Optional[configparser.Error]) -> None
super(ConfigurationFileCouldNotBeLoaded, self).__init__(error)
self.reason = reason
self.fname = fname
self.error = error

def __str__(self):
# type: () -> str
if self.fname is not None:
message_part = " in {}.".format(self.fname)
else:
assert self.error is not None
message_part = ".\n{}\n".format(self.error.message)
message_part = ".\n{}\n".format(self.error)
return "Configuration file {}{}".format(self.reason, message_part)
4 changes: 1 addition & 3 deletions src/pip/_internal/self_outdated_check.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# The following comment should be removed at some point in the future.
# mypy: disallow-untyped-defs=False

from __future__ import absolute_import

import datetime
Expand Down Expand Up @@ -104,6 +101,7 @@ def __init__(self, cache_dir):

@property
def key(self):
# type: () -> str
return sys.prefix

def save(self, pypi_version, current_time):
Expand Down