mirror of https://github.com/pypa/pip
Move Link to models
This commit is contained in:
parent
f1cf9a06e9
commit
39995b32db
|
@ -11,6 +11,7 @@ from pip._vendor.packaging.utils import canonicalize_name
|
||||||
from pip._internal import index
|
from pip._internal import index
|
||||||
from pip._internal.compat import expanduser
|
from pip._internal.compat import expanduser
|
||||||
from pip._internal.download import path_to_url
|
from pip._internal.download import path_to_url
|
||||||
|
from pip._internal.models.link import Link
|
||||||
from pip._internal.utils.temp_dir import TempDirectory
|
from pip._internal.utils.temp_dir import TempDirectory
|
||||||
from pip._internal.wheel import InvalidWheelFilename, Wheel
|
from pip._internal.wheel import InvalidWheelFilename, Wheel
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ class Cache(object):
|
||||||
root = self.get_path_for_link(link)
|
root = self.get_path_for_link(link)
|
||||||
path = os.path.join(root, candidate)
|
path = os.path.join(root, candidate)
|
||||||
|
|
||||||
return index.Link(path_to_url(path))
|
return Link(path_to_url(path))
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -29,12 +29,13 @@ from pip._internal.exceptions import (
|
||||||
)
|
)
|
||||||
from pip._internal.models.index import PyPI
|
from pip._internal.models.index import PyPI
|
||||||
from pip._internal.models.candidate import InstallationCandidate
|
from pip._internal.models.candidate import InstallationCandidate
|
||||||
|
from pip._internal.models.link import Link
|
||||||
from pip._internal.pep425tags import get_supported
|
from pip._internal.pep425tags import get_supported
|
||||||
from pip._internal.utils.deprecation import RemovedInPip11Warning
|
from pip._internal.utils.deprecation import RemovedInPip11Warning
|
||||||
from pip._internal.utils.logging import indent_log
|
from pip._internal.utils.logging import indent_log
|
||||||
from pip._internal.utils.misc import (
|
from pip._internal.utils.misc import (
|
||||||
ARCHIVE_EXTENSIONS, SUPPORTED_EXTENSIONS, cached_property, normalize_path,
|
ARCHIVE_EXTENSIONS, SUPPORTED_EXTENSIONS, cached_property, normalize_path,
|
||||||
remove_auth_from_url, splitext,
|
remove_auth_from_url,
|
||||||
)
|
)
|
||||||
from pip._internal.utils.packaging import check_requires_python
|
from pip._internal.utils.packaging import check_requires_python
|
||||||
from pip._internal.wheel import Wheel, wheel_ext
|
from pip._internal.wheel import Wheel, wheel_ext
|
||||||
|
@ -868,166 +869,6 @@ class HTMLPage(object):
|
||||||
lambda match: '%%%2x' % ord(match.group(0)), url)
|
lambda match: '%%%2x' % ord(match.group(0)), url)
|
||||||
|
|
||||||
|
|
||||||
class Link(object):
|
|
||||||
|
|
||||||
def __init__(self, url, comes_from=None, requires_python=None):
|
|
||||||
"""
|
|
||||||
Object representing a parsed link from https://pypi.org/simple/*
|
|
||||||
|
|
||||||
url:
|
|
||||||
url of the resource pointed to (href of the link)
|
|
||||||
comes_from:
|
|
||||||
instance of HTMLPage where the link was found, or string.
|
|
||||||
requires_python:
|
|
||||||
String containing the `Requires-Python` metadata field, specified
|
|
||||||
in PEP 345. This may be specified by a data-requires-python
|
|
||||||
attribute in the HTML link tag, as described in PEP 503.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# url can be a UNC windows share
|
|
||||||
if url.startswith('\\\\'):
|
|
||||||
url = path_to_url(url)
|
|
||||||
|
|
||||||
self.url = url
|
|
||||||
self.comes_from = comes_from
|
|
||||||
self.requires_python = requires_python if requires_python else None
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
if self.requires_python:
|
|
||||||
rp = ' (requires-python:%s)' % self.requires_python
|
|
||||||
else:
|
|
||||||
rp = ''
|
|
||||||
if self.comes_from:
|
|
||||||
return '%s (from %s)%s' % (self.url, self.comes_from, rp)
|
|
||||||
else:
|
|
||||||
return str(self.url)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return '<Link %s>' % self
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
if not isinstance(other, Link):
|
|
||||||
return NotImplemented
|
|
||||||
return self.url == other.url
|
|
||||||
|
|
||||||
def __ne__(self, other):
|
|
||||||
if not isinstance(other, Link):
|
|
||||||
return NotImplemented
|
|
||||||
return self.url != other.url
|
|
||||||
|
|
||||||
def __lt__(self, other):
|
|
||||||
if not isinstance(other, Link):
|
|
||||||
return NotImplemented
|
|
||||||
return self.url < other.url
|
|
||||||
|
|
||||||
def __le__(self, other):
|
|
||||||
if not isinstance(other, Link):
|
|
||||||
return NotImplemented
|
|
||||||
return self.url <= other.url
|
|
||||||
|
|
||||||
def __gt__(self, other):
|
|
||||||
if not isinstance(other, Link):
|
|
||||||
return NotImplemented
|
|
||||||
return self.url > other.url
|
|
||||||
|
|
||||||
def __ge__(self, other):
|
|
||||||
if not isinstance(other, Link):
|
|
||||||
return NotImplemented
|
|
||||||
return self.url >= other.url
|
|
||||||
|
|
||||||
def __hash__(self):
|
|
||||||
return hash(self.url)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def filename(self):
|
|
||||||
_, netloc, path, _, _ = urllib_parse.urlsplit(self.url)
|
|
||||||
name = posixpath.basename(path.rstrip('/')) or netloc
|
|
||||||
name = urllib_parse.unquote(name)
|
|
||||||
assert name, ('URL %r produced no filename' % self.url)
|
|
||||||
return name
|
|
||||||
|
|
||||||
@property
|
|
||||||
def scheme(self):
|
|
||||||
return urllib_parse.urlsplit(self.url)[0]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def netloc(self):
|
|
||||||
return urllib_parse.urlsplit(self.url)[1]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def path(self):
|
|
||||||
return urllib_parse.unquote(urllib_parse.urlsplit(self.url)[2])
|
|
||||||
|
|
||||||
def splitext(self):
|
|
||||||
return splitext(posixpath.basename(self.path.rstrip('/')))
|
|
||||||
|
|
||||||
@property
|
|
||||||
def ext(self):
|
|
||||||
return self.splitext()[1]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def url_without_fragment(self):
|
|
||||||
scheme, netloc, path, query, fragment = urllib_parse.urlsplit(self.url)
|
|
||||||
return urllib_parse.urlunsplit((scheme, netloc, path, query, None))
|
|
||||||
|
|
||||||
_egg_fragment_re = re.compile(r'[#&]egg=([^&]*)')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def egg_fragment(self):
|
|
||||||
match = self._egg_fragment_re.search(self.url)
|
|
||||||
if not match:
|
|
||||||
return None
|
|
||||||
return match.group(1)
|
|
||||||
|
|
||||||
_subdirectory_fragment_re = re.compile(r'[#&]subdirectory=([^&]*)')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def subdirectory_fragment(self):
|
|
||||||
match = self._subdirectory_fragment_re.search(self.url)
|
|
||||||
if not match:
|
|
||||||
return None
|
|
||||||
return match.group(1)
|
|
||||||
|
|
||||||
_hash_re = re.compile(
|
|
||||||
r'(sha1|sha224|sha384|sha256|sha512|md5)=([a-f0-9]+)'
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def hash(self):
|
|
||||||
match = self._hash_re.search(self.url)
|
|
||||||
if match:
|
|
||||||
return match.group(2)
|
|
||||||
return None
|
|
||||||
|
|
||||||
@property
|
|
||||||
def hash_name(self):
|
|
||||||
match = self._hash_re.search(self.url)
|
|
||||||
if match:
|
|
||||||
return match.group(1)
|
|
||||||
return None
|
|
||||||
|
|
||||||
@property
|
|
||||||
def show_url(self):
|
|
||||||
return posixpath.basename(self.url.split('#', 1)[0].split('?', 1)[0])
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_wheel(self):
|
|
||||||
return self.ext == wheel_ext
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_artifact(self):
|
|
||||||
"""
|
|
||||||
Determines if this points to an actual artifact (e.g. a tarball) or if
|
|
||||||
it points to an "abstract" thing like a path or a VCS location.
|
|
||||||
"""
|
|
||||||
from pip._internal.vcs import vcs
|
|
||||||
|
|
||||||
if self.scheme in vcs.all_schemes:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
FormatControl = namedtuple('FormatControl', 'no_binary only_binary')
|
FormatControl = namedtuple('FormatControl', 'no_binary only_binary')
|
||||||
"""This object has two fields, no_binary and only_binary.
|
"""This object has two fields, no_binary and only_binary.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
import posixpath
|
||||||
|
import re
|
||||||
|
|
||||||
|
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||||
|
|
||||||
|
from pip._internal.download import path_to_url
|
||||||
|
from pip._internal.utils.misc import splitext
|
||||||
|
from pip._internal.wheel import wheel_ext
|
||||||
|
|
||||||
|
|
||||||
|
class Link(object):
|
||||||
|
"""Represents a parsed link from a Package Index's simple URL
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, url, comes_from=None, requires_python=None):
|
||||||
|
"""
|
||||||
|
url:
|
||||||
|
url of the resource pointed to (href of the link)
|
||||||
|
comes_from:
|
||||||
|
instance of HTMLPage where the link was found, or string.
|
||||||
|
requires_python:
|
||||||
|
String containing the `Requires-Python` metadata field, specified
|
||||||
|
in PEP 345. This may be specified by a data-requires-python
|
||||||
|
attribute in the HTML link tag, as described in PEP 503.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# url can be a UNC windows share
|
||||||
|
if url.startswith('\\\\'):
|
||||||
|
url = path_to_url(url)
|
||||||
|
|
||||||
|
self.url = url
|
||||||
|
self.comes_from = comes_from
|
||||||
|
self.requires_python = requires_python if requires_python else None
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if self.requires_python:
|
||||||
|
rp = ' (requires-python:%s)' % self.requires_python
|
||||||
|
else:
|
||||||
|
rp = ''
|
||||||
|
if self.comes_from:
|
||||||
|
return '%s (from %s)%s' % (self.url, self.comes_from, rp)
|
||||||
|
else:
|
||||||
|
return str(self.url)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '<Link %s>' % self
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if not isinstance(other, Link):
|
||||||
|
return NotImplemented
|
||||||
|
return self.url == other.url
|
||||||
|
|
||||||
|
def __ne__(self, other):
|
||||||
|
if not isinstance(other, Link):
|
||||||
|
return NotImplemented
|
||||||
|
return self.url != other.url
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
if not isinstance(other, Link):
|
||||||
|
return NotImplemented
|
||||||
|
return self.url < other.url
|
||||||
|
|
||||||
|
def __le__(self, other):
|
||||||
|
if not isinstance(other, Link):
|
||||||
|
return NotImplemented
|
||||||
|
return self.url <= other.url
|
||||||
|
|
||||||
|
def __gt__(self, other):
|
||||||
|
if not isinstance(other, Link):
|
||||||
|
return NotImplemented
|
||||||
|
return self.url > other.url
|
||||||
|
|
||||||
|
def __ge__(self, other):
|
||||||
|
if not isinstance(other, Link):
|
||||||
|
return NotImplemented
|
||||||
|
return self.url >= other.url
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash(self.url)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def filename(self):
|
||||||
|
_, netloc, path, _, _ = urllib_parse.urlsplit(self.url)
|
||||||
|
name = posixpath.basename(path.rstrip('/')) or netloc
|
||||||
|
name = urllib_parse.unquote(name)
|
||||||
|
assert name, ('URL %r produced no filename' % self.url)
|
||||||
|
return name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def scheme(self):
|
||||||
|
return urllib_parse.urlsplit(self.url)[0]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def netloc(self):
|
||||||
|
return urllib_parse.urlsplit(self.url)[1]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def path(self):
|
||||||
|
return urllib_parse.unquote(urllib_parse.urlsplit(self.url)[2])
|
||||||
|
|
||||||
|
def splitext(self):
|
||||||
|
return splitext(posixpath.basename(self.path.rstrip('/')))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ext(self):
|
||||||
|
return self.splitext()[1]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def url_without_fragment(self):
|
||||||
|
scheme, netloc, path, query, fragment = urllib_parse.urlsplit(self.url)
|
||||||
|
return urllib_parse.urlunsplit((scheme, netloc, path, query, None))
|
||||||
|
|
||||||
|
_egg_fragment_re = re.compile(r'[#&]egg=([^&]*)')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def egg_fragment(self):
|
||||||
|
match = self._egg_fragment_re.search(self.url)
|
||||||
|
if not match:
|
||||||
|
return None
|
||||||
|
return match.group(1)
|
||||||
|
|
||||||
|
_subdirectory_fragment_re = re.compile(r'[#&]subdirectory=([^&]*)')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def subdirectory_fragment(self):
|
||||||
|
match = self._subdirectory_fragment_re.search(self.url)
|
||||||
|
if not match:
|
||||||
|
return None
|
||||||
|
return match.group(1)
|
||||||
|
|
||||||
|
_hash_re = re.compile(
|
||||||
|
r'(sha1|sha224|sha384|sha256|sha512|md5)=([a-f0-9]+)'
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def hash(self):
|
||||||
|
match = self._hash_re.search(self.url)
|
||||||
|
if match:
|
||||||
|
return match.group(2)
|
||||||
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def hash_name(self):
|
||||||
|
match = self._hash_re.search(self.url)
|
||||||
|
if match:
|
||||||
|
return match.group(1)
|
||||||
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def show_url(self):
|
||||||
|
return posixpath.basename(self.url.split('#', 1)[0].split('?', 1)[0])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_wheel(self):
|
||||||
|
return self.ext == wheel_ext
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_artifact(self):
|
||||||
|
"""
|
||||||
|
Determines if this points to an actual artifact (e.g. a tarball) or if
|
||||||
|
it points to an "abstract" thing like a path or a VCS location.
|
||||||
|
"""
|
||||||
|
from pip._internal.vcs import vcs
|
||||||
|
|
||||||
|
if self.scheme in vcs.all_schemes:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
|
@ -137,7 +137,7 @@ class InstallRequirement(object):
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_editable(cls, editable_req, comes_from=None, isolated=False,
|
def from_editable(cls, editable_req, comes_from=None, isolated=False,
|
||||||
options=None, wheel_cache=None, constraint=False):
|
options=None, wheel_cache=None, constraint=False):
|
||||||
from pip._internal.index import Link
|
from pip._internal.models.link import Link # TODO: move this to top
|
||||||
|
|
||||||
name, url, extras_override = parse_editable(editable_req)
|
name, url, extras_override = parse_editable(editable_req)
|
||||||
if url.startswith('file:'):
|
if url.startswith('file:'):
|
||||||
|
|
|
@ -6,7 +6,7 @@ import re
|
||||||
|
|
||||||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||||
|
|
||||||
from pip._internal.index import Link
|
from pip._internal.models.link import Link
|
||||||
from pip._internal.utils.logging import indent_log
|
from pip._internal.utils.logging import indent_log
|
||||||
from pip._internal.utils.misc import display_path, remove_auth_from_url, rmtree
|
from pip._internal.utils.misc import display_path, remove_auth_from_url, rmtree
|
||||||
from pip._internal.vcs import VersionControl, vcs
|
from pip._internal.vcs import VersionControl, vcs
|
||||||
|
|
|
@ -710,6 +710,7 @@ class WheelBuilder(object):
|
||||||
:return: True if all the wheels built correctly.
|
:return: True if all the wheels built correctly.
|
||||||
"""
|
"""
|
||||||
from pip._internal import index
|
from pip._internal import index
|
||||||
|
from pip._internal.models.link import Link
|
||||||
|
|
||||||
building_is_possible = self._wheel_dir or (
|
building_is_possible = self._wheel_dir or (
|
||||||
autobuilding and self.wheel_cache.cache_dir
|
autobuilding and self.wheel_cache.cache_dir
|
||||||
|
@ -802,7 +803,7 @@ class WheelBuilder(object):
|
||||||
self.preparer.build_dir
|
self.preparer.build_dir
|
||||||
)
|
)
|
||||||
# Update the link for this.
|
# Update the link for this.
|
||||||
req.link = index.Link(path_to_url(wheel_file))
|
req.link = Link(path_to_url(wheel_file))
|
||||||
assert req.link.is_wheel
|
assert req.link.is_wheel
|
||||||
# extract the wheel into the dir
|
# extract the wheel into the dir
|
||||||
unpack_url(
|
unpack_url(
|
||||||
|
|
Loading…
Reference in New Issue