Skip to content

Commit

Permalink
Merge pull request #8296 from deveshks/mypy-pip-internal
Browse files Browse the repository at this point in the history
Complete type annotations in "pip._internal.{build_env,self_outdated_check,exceptions}"
  • Loading branch information
sbidoul authored May 31, 2020
2 parents d01bfcf + 5c24a1e commit 69a4cb3
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 19 deletions.
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
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 @@ -206,16 +210,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()
35 changes: 28 additions & 7 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 @@ -105,24 +108,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 @@ -144,8 +153,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 @@ -158,9 +169,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 @@ -201,13 +214,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

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

Expand Down Expand Up @@ -250,6 +265,7 @@ 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
Expand All @@ -260,10 +276,12 @@ def __init__(self, allowed, gots):
self.gots = gots

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 @@ -275,11 +293,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 @@ -299,15 +318,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

0 comments on commit 69a4cb3

Please sign in to comment.