Skip to content

Commit d6ed2af

Browse files
committed
Remove unused code from pip._internal
There is still some pip-specific code left but it should be a lot easier to further clean-up and adjust pip's vcs module for fetchcode needs. Signed-off-by: Alexander Mazuruk <a.mazuruk@samsung.com>
1 parent c0a91c7 commit d6ed2af

File tree

6 files changed

+8
-643
lines changed

6 files changed

+8
-643
lines changed
Lines changed: 4 additions & 279 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,20 @@
11
"""Exceptions used throughout package"""
22

3-
import configparser
4-
from itertools import chain, groupby, repeat
5-
from typing import TYPE_CHECKING, Dict, List, Optional
3+
from itertools import groupby
4+
from typing import TYPE_CHECKING, Dict, List
65

7-
from fetchcode.vcs.pip._vendor.pkg_resources import Distribution
86
from fetchcode.vcs.pip._vendor.requests.models import Request, Response
97

108
if TYPE_CHECKING:
119
from hashlib import _Hash
1210

13-
from fetchcode.vcs.pip._internal.req.req_install import InstallRequirement
14-
15-
1611
class PipError(Exception):
1712
"""Base pip exception"""
1813

19-
20-
class ConfigurationError(PipError):
21-
"""General exception in configuration"""
22-
23-
2414
class InstallationError(PipError):
2515
"""General exception during installation"""
2616

2717

28-
class UninstallationError(PipError):
29-
"""General exception during uninstallation"""
30-
31-
32-
class NoneMetadataError(PipError):
33-
"""
34-
Raised when accessing "METADATA" or "PKG-INFO" metadata for a
35-
pip._vendor.pkg_resources.Distribution object and
36-
`dist.has_metadata('METADATA')` returns True but
37-
`dist.get_metadata('METADATA')` returns None (and similarly for
38-
"PKG-INFO").
39-
"""
40-
41-
def __init__(self, dist, metadata_name):
42-
# type: (Distribution, str) -> None
43-
"""
44-
:param dist: A Distribution object.
45-
:param metadata_name: The name of the metadata being accessed
46-
(can be "METADATA" or "PKG-INFO").
47-
"""
48-
self.dist = dist
49-
self.metadata_name = metadata_name
50-
51-
def __str__(self):
52-
# type: () -> str
53-
# Use `dist` in the error message because its stringification
54-
# includes more information, like the version and location.
55-
return (
56-
'None {} metadata found for distribution: {}'.format(
57-
self.metadata_name, self.dist,
58-
)
59-
)
60-
61-
62-
class UserInstallationInvalid(InstallationError):
63-
"""A --user install is requested on an environment without user site."""
64-
65-
def __str__(self):
66-
# type: () -> str
67-
return "User base directory is not specified"
68-
69-
70-
class InvalidSchemeCombination(InstallationError):
71-
def __str__(self):
72-
# type: () -> str
73-
before = ", ".join(str(a) for a in self.args[:-1])
74-
return f"Cannot set {before} and {self.args[-1]} together"
75-
76-
77-
class DistributionNotFound(InstallationError):
78-
"""Raised when a distribution cannot be found to satisfy a requirement"""
79-
80-
81-
class RequirementsFileParseError(InstallationError):
82-
"""Raised when a general error occurs parsing a requirements file line."""
83-
84-
85-
class BestVersionAlreadyInstalled(PipError):
86-
"""Raised when the most up-to-date version of a package is already
87-
installed."""
88-
89-
9018
class BadCommand(PipError):
9119
"""Raised when virtualenv or a command is not found"""
9220

@@ -95,10 +23,6 @@ class CommandError(PipError):
9523
"""Raised when there is an error in command-line arguments"""
9624

9725

98-
class PreviousBuildDirError(PipError):
99-
"""Raised when there's a previous conflicting build directory"""
100-
101-
10226
class NetworkConnectionError(PipError):
10327
"""HTTP connection error"""
10428

@@ -121,37 +45,6 @@ def __str__(self):
12145
return str(self.error_msg)
12246

12347

124-
class InvalidWheelFilename(InstallationError):
125-
"""Invalid wheel filename."""
126-
127-
128-
class UnsupportedWheel(InstallationError):
129-
"""Unsupported wheel."""
130-
131-
132-
class MetadataInconsistent(InstallationError):
133-
"""Built metadata contains inconsistent information.
134-
135-
This is raised when the metadata contains values (e.g. name and version)
136-
that do not match the information previously obtained from sdist filename
137-
or user-supplied ``#egg=`` value.
138-
"""
139-
def __init__(self, ireq, field, f_val, m_val):
140-
# type: (InstallRequirement, str, str, str) -> None
141-
self.ireq = ireq
142-
self.field = field
143-
self.f_val = f_val
144-
self.m_val = m_val
145-
146-
def __str__(self):
147-
# type: () -> str
148-
template = (
149-
"Requested {} has inconsistent {}: "
150-
"filename has {!r}, but metadata has {!r}"
151-
)
152-
return template.format(self.ireq, self.field, self.f_val, self.m_val)
153-
154-
15548
class InstallationSubprocessError(InstallationError):
15649
"""A subprocess call failed during installation."""
15750
def __init__(self, returncode, description):
@@ -207,43 +100,16 @@ class HashError(InstallationError):
207100
about unpinned packages when he has deeper issues, like VCS
208101
dependencies, to deal with. Also keeps error reports in a
209102
deterministic order.
210-
:cvar head: A section heading for display above potentially many
103+
:cvar head: A section heading for display in potentially many
211104
exceptions of this kind
212-
:ivar req: The InstallRequirement that triggered this error. This is
213-
pasted on after the exception is instantiated, because it's not
214-
typically available earlier.
215105
216106
"""
217-
req = None # type: Optional[InstallRequirement]
218107
head = ''
219108
order = -1 # type: int
220109

221-
def body(self):
222-
# type: () -> str
223-
"""Return a summary of me for display under the heading.
224-
225-
This default implementation simply prints a description of the
226-
triggering requirement.
227-
228-
:param req: The InstallRequirement that provoked this error, with
229-
its link already populated by the resolver's _populate_link().
230-
231-
"""
232-
return f' {self._requirement_name()}'
233-
234110
def __str__(self):
235111
# type: () -> str
236-
return f'{self.head}\n{self.body()}'
237-
238-
def _requirement_name(self):
239-
# type: () -> str
240-
"""Return a description of the requirement that triggered me.
241-
242-
This default implementation returns long description of the req, with
243-
line numbers
244-
245-
"""
246-
return str(self.req) if self.req else 'unknown package'
112+
return f'{self.head}'
247113

248114

249115
class VcsHashUnsupported(HashError):
@@ -254,144 +120,3 @@ class VcsHashUnsupported(HashError):
254120
head = ("Can't verify hashes for these requirements because we don't "
255121
"have a way to hash version control repositories:")
256122

257-
258-
class DirectoryUrlHashUnsupported(HashError):
259-
"""A hash was provided for a version-control-system-based requirement, but
260-
we don't have a method for hashing those."""
261-
262-
order = 1
263-
head = ("Can't verify hashes for these file:// requirements because they "
264-
"point to directories:")
265-
266-
267-
class HashMissing(HashError):
268-
"""A hash was needed for a requirement but is absent."""
269-
270-
order = 2
271-
head = ('Hashes are required in --require-hashes mode, but they are '
272-
'missing from some requirements. Here is a list of those '
273-
'requirements along with the hashes their downloaded archives '
274-
'actually had. Add lines like these to your requirements files to '
275-
'prevent tampering. (If you did not enable --require-hashes '
276-
'manually, note that it turns on automatically when any package '
277-
'has a hash.)')
278-
279-
def __init__(self, gotten_hash):
280-
# type: (str) -> None
281-
"""
282-
:param gotten_hash: The hash of the (possibly malicious) archive we
283-
just downloaded
284-
"""
285-
self.gotten_hash = gotten_hash
286-
287-
def body(self):
288-
# type: () -> str
289-
# Dodge circular import.
290-
from fetchcode.vcs.pip._internal.utils.hashes import FAVORITE_HASH
291-
292-
package = None
293-
if self.req:
294-
# In the case of URL-based requirements, display the original URL
295-
# seen in the requirements file rather than the package name,
296-
# so the output can be directly copied into the requirements file.
297-
package = (self.req.original_link if self.req.original_link
298-
# In case someone feeds something downright stupid
299-
# to InstallRequirement's constructor.
300-
else getattr(self.req, 'req', None))
301-
return ' {} --hash={}:{}'.format(package or 'unknown package',
302-
FAVORITE_HASH,
303-
self.gotten_hash)
304-
305-
306-
class HashUnpinned(HashError):
307-
"""A requirement had a hash specified but was not pinned to a specific
308-
version."""
309-
310-
order = 3
311-
head = ('In --require-hashes mode, all requirements must have their '
312-
'versions pinned with ==. These do not:')
313-
314-
315-
class HashMismatch(HashError):
316-
"""
317-
Distribution file hash values don't match.
318-
319-
:ivar package_name: The name of the package that triggered the hash
320-
mismatch. Feel free to write to this after the exception is raise to
321-
improve its error message.
322-
323-
"""
324-
order = 4
325-
head = ('THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS '
326-
'FILE. If you have updated the package versions, please update '
327-
'the hashes. Otherwise, examine the package contents carefully; '
328-
'someone may have tampered with them.')
329-
330-
def __init__(self, allowed, gots):
331-
# type: (Dict[str, List[str]], Dict[str, _Hash]) -> None
332-
"""
333-
:param allowed: A dict of algorithm names pointing to lists of allowed
334-
hex digests
335-
:param gots: A dict of algorithm names pointing to hashes we
336-
actually got from the files under suspicion
337-
"""
338-
self.allowed = allowed
339-
self.gots = gots
340-
341-
def body(self):
342-
# type: () -> str
343-
return ' {}:\n{}'.format(self._requirement_name(),
344-
self._hash_comparison())
345-
346-
def _hash_comparison(self):
347-
# type: () -> str
348-
"""
349-
Return a comparison of actual and expected hash values.
350-
351-
Example::
352-
353-
Expected sha256 abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde
354-
or 123451234512345123451234512345123451234512345
355-
Got bcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdef
356-
357-
"""
358-
def hash_then_or(hash_name):
359-
# type: (str) -> chain[str]
360-
# For now, all the decent hashes have 6-char names, so we can get
361-
# away with hard-coding space literals.
362-
return chain([hash_name], repeat(' or'))
363-
364-
lines = [] # type: List[str]
365-
for hash_name, expecteds in self.allowed.items():
366-
prefix = hash_then_or(hash_name)
367-
lines.extend((' Expected {} {}'.format(next(prefix), e))
368-
for e in expecteds)
369-
lines.append(' Got {}\n'.format(
370-
self.gots[hash_name].hexdigest()))
371-
return '\n'.join(lines)
372-
373-
374-
class UnsupportedPythonVersion(InstallationError):
375-
"""Unsupported python version according to Requires-Python package
376-
metadata."""
377-
378-
379-
class ConfigurationFileCouldNotBeLoaded(ConfigurationError):
380-
"""When there are errors while loading a configuration file
381-
"""
382-
383-
def __init__(self, reason="could not be loaded", fname=None, error=None):
384-
# type: (str, Optional[str], Optional[configparser.Error]) -> None
385-
super().__init__(error)
386-
self.reason = reason
387-
self.fname = fname
388-
self.error = error
389-
390-
def __str__(self):
391-
# type: () -> str
392-
if self.fname is not None:
393-
message_part = f" in {self.fname}."
394-
else:
395-
assert self.error is not None
396-
message_part = f".\n{self.error}\n"
397-
return f"Configuration file {self.reason}{message_part}"

0 commit comments

Comments
 (0)