~ibmcharmers/charms/xenial/ibm-cinder-storwize-svc/trunk

« back to all changes in this revision

Viewing changes to .tox/py35/lib/python3.5/site-packages/pip/exceptions.py

  • Committer: Ankammarao
  • Date: 2017-03-06 05:11:42 UTC
  • Revision ID: achittet@in.ibm.com-20170306051142-dpg27z4es1k56hfn
Marked tests folder executable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""Exceptions used throughout package"""
 
2
from __future__ import absolute_import
 
3
 
 
4
from itertools import chain, groupby, repeat
 
5
 
 
6
from pip._vendor.six import iteritems
 
7
 
 
8
 
 
9
class PipError(Exception):
 
10
    """Base pip exception"""
 
11
 
 
12
 
 
13
class InstallationError(PipError):
 
14
    """General exception during installation"""
 
15
 
 
16
 
 
17
class UninstallationError(PipError):
 
18
    """General exception during uninstallation"""
 
19
 
 
20
 
 
21
class DistributionNotFound(InstallationError):
 
22
    """Raised when a distribution cannot be found to satisfy a requirement"""
 
23
 
 
24
 
 
25
class RequirementsFileParseError(InstallationError):
 
26
    """Raised when a general error occurs parsing a requirements file line."""
 
27
 
 
28
 
 
29
class BestVersionAlreadyInstalled(PipError):
 
30
    """Raised when the most up-to-date version of a package is already
 
31
    installed."""
 
32
 
 
33
 
 
34
class BadCommand(PipError):
 
35
    """Raised when virtualenv or a command is not found"""
 
36
 
 
37
 
 
38
class CommandError(PipError):
 
39
    """Raised when there is an error in command-line arguments"""
 
40
 
 
41
 
 
42
class PreviousBuildDirError(PipError):
 
43
    """Raised when there's a previous conflicting build directory"""
 
44
 
 
45
 
 
46
class InvalidWheelFilename(InstallationError):
 
47
    """Invalid wheel filename."""
 
48
 
 
49
 
 
50
class UnsupportedWheel(InstallationError):
 
51
    """Unsupported wheel."""
 
52
 
 
53
 
 
54
class HashErrors(InstallationError):
 
55
    """Multiple HashError instances rolled into one for reporting"""
 
56
 
 
57
    def __init__(self):
 
58
        self.errors = []
 
59
 
 
60
    def append(self, error):
 
61
        self.errors.append(error)
 
62
 
 
63
    def __str__(self):
 
64
        lines = []
 
65
        self.errors.sort(key=lambda e: e.order)
 
66
        for cls, errors_of_cls in groupby(self.errors, lambda e: e.__class__):
 
67
            lines.append(cls.head)
 
68
            lines.extend(e.body() for e in errors_of_cls)
 
69
        if lines:
 
70
            return '\n'.join(lines)
 
71
 
 
72
    def __nonzero__(self):
 
73
        return bool(self.errors)
 
74
 
 
75
    def __bool__(self):
 
76
        return self.__nonzero__()
 
77
 
 
78
 
 
79
class HashError(InstallationError):
 
80
    """
 
81
    A failure to verify a package against known-good hashes
 
82
 
 
83
    :cvar order: An int sorting hash exception classes by difficulty of
 
84
        recovery (lower being harder), so the user doesn't bother fretting
 
85
        about unpinned packages when he has deeper issues, like VCS
 
86
        dependencies, to deal with. Also keeps error reports in a
 
87
        deterministic order.
 
88
    :cvar head: A section heading for display above potentially many
 
89
        exceptions of this kind
 
90
    :ivar req: The InstallRequirement that triggered this error. This is
 
91
        pasted on after the exception is instantiated, because it's not
 
92
        typically available earlier.
 
93
 
 
94
    """
 
95
    req = None
 
96
    head = ''
 
97
 
 
98
    def body(self):
 
99
        """Return a summary of me for display under the heading.
 
100
 
 
101
        This default implementation simply prints a description of the
 
102
        triggering requirement.
 
103
 
 
104
        :param req: The InstallRequirement that provoked this error, with
 
105
            populate_link() having already been called
 
106
 
 
107
        """
 
108
        return '    %s' % self._requirement_name()
 
109
 
 
110
    def __str__(self):
 
111
        return '%s\n%s' % (self.head, self.body())
 
112
 
 
113
    def _requirement_name(self):
 
114
        """Return a description of the requirement that triggered me.
 
115
 
 
116
        This default implementation returns long description of the req, with
 
117
        line numbers
 
118
 
 
119
        """
 
120
        return str(self.req) if self.req else 'unknown package'
 
121
 
 
122
 
 
123
class VcsHashUnsupported(HashError):
 
124
    """A hash was provided for a version-control-system-based requirement, but
 
125
    we don't have a method for hashing those."""
 
126
 
 
127
    order = 0
 
128
    head = ("Can't verify hashes for these requirements because we don't "
 
129
            "have a way to hash version control repositories:")
 
130
 
 
131
 
 
132
class DirectoryUrlHashUnsupported(HashError):
 
133
    """A hash was provided for a version-control-system-based requirement, but
 
134
    we don't have a method for hashing those."""
 
135
 
 
136
    order = 1
 
137
    head = ("Can't verify hashes for these file:// requirements because they "
 
138
            "point to directories:")
 
139
 
 
140
 
 
141
class HashMissing(HashError):
 
142
    """A hash was needed for a requirement but is absent."""
 
143
 
 
144
    order = 2
 
145
    head = ('Hashes are required in --require-hashes mode, but they are '
 
146
            'missing from some requirements. Here is a list of those '
 
147
            'requirements along with the hashes their downloaded archives '
 
148
            'actually had. Add lines like these to your requirements files to '
 
149
            'prevent tampering. (If you did not enable --require-hashes '
 
150
            'manually, note that it turns on automatically when any package '
 
151
            'has a hash.)')
 
152
 
 
153
    def __init__(self, gotten_hash):
 
154
        """
 
155
        :param gotten_hash: The hash of the (possibly malicious) archive we
 
156
            just downloaded
 
157
        """
 
158
        self.gotten_hash = gotten_hash
 
159
 
 
160
    def body(self):
 
161
        from pip.utils.hashes import FAVORITE_HASH  # Dodge circular import.
 
162
 
 
163
        package = None
 
164
        if self.req:
 
165
            # In the case of URL-based requirements, display the original URL
 
166
            # seen in the requirements file rather than the package name,
 
167
            # so the output can be directly copied into the requirements file.
 
168
            package = (self.req.original_link if self.req.original_link
 
169
                       # In case someone feeds something downright stupid
 
170
                       # to InstallRequirement's constructor.
 
171
                       else getattr(self.req, 'req', None))
 
172
        return '    %s --hash=%s:%s' % (package or 'unknown package',
 
173
                                        FAVORITE_HASH,
 
174
                                        self.gotten_hash)
 
175
 
 
176
 
 
177
class HashUnpinned(HashError):
 
178
    """A requirement had a hash specified but was not pinned to a specific
 
179
    version."""
 
180
 
 
181
    order = 3
 
182
    head = ('In --require-hashes mode, all requirements must have their '
 
183
            'versions pinned with ==. These do not:')
 
184
 
 
185
 
 
186
class HashMismatch(HashError):
 
187
    """
 
188
    Distribution file hash values don't match.
 
189
 
 
190
    :ivar package_name: The name of the package that triggered the hash
 
191
        mismatch. Feel free to write to this after the exception is raise to
 
192
        improve its error message.
 
193
 
 
194
    """
 
195
    order = 4
 
196
    head = ('THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS '
 
197
            'FILE. If you have updated the package versions, please update '
 
198
            'the hashes. Otherwise, examine the package contents carefully; '
 
199
            'someone may have tampered with them.')
 
200
 
 
201
    def __init__(self, allowed, gots):
 
202
        """
 
203
        :param allowed: A dict of algorithm names pointing to lists of allowed
 
204
            hex digests
 
205
        :param gots: A dict of algorithm names pointing to hashes we
 
206
            actually got from the files under suspicion
 
207
        """
 
208
        self.allowed = allowed
 
209
        self.gots = gots
 
210
 
 
211
    def body(self):
 
212
        return '    %s:\n%s' % (self._requirement_name(),
 
213
                                self._hash_comparison())
 
214
 
 
215
    def _hash_comparison(self):
 
216
        """
 
217
        Return a comparison of actual and expected hash values.
 
218
 
 
219
        Example::
 
220
 
 
221
               Expected sha256 abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde
 
222
                            or 123451234512345123451234512345123451234512345
 
223
                    Got        bcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdef
 
224
 
 
225
        """
 
226
        def hash_then_or(hash_name):
 
227
            # For now, all the decent hashes have 6-char names, so we can get
 
228
            # away with hard-coding space literals.
 
229
            return chain([hash_name], repeat('    or'))
 
230
 
 
231
        lines = []
 
232
        for hash_name, expecteds in iteritems(self.allowed):
 
233
            prefix = hash_then_or(hash_name)
 
234
            lines.extend(('        Expected %s %s' % (next(prefix), e))
 
235
                         for e in expecteds)
 
236
            lines.append('             Got        %s\n' %
 
237
                         self.gots[hash_name].hexdigest())
 
238
            prefix = '    or'
 
239
        return '\n'.join(lines)
 
240
 
 
241
 
 
242
class UnsupportedPythonVersion(InstallationError):
 
243
    """Unsupported python version according to Requires-Python package
 
244
    metadata."""