add python3.6 modules
This commit is contained in:
parent
7080253073
commit
e9dacd2bf3
228 changed files with 10923 additions and 6804 deletions
|
|
@ -135,7 +135,7 @@ def process_line(line, filename, line_number, finder=None, comes_from=None,
|
|||
defaults.format_control = finder.format_control
|
||||
args_str, options_str = break_args_options(line)
|
||||
if sys.version_info < (2, 7, 3):
|
||||
# Priori to 2.7.3, shlex can not deal with unicode entries
|
||||
# Prior to 2.7.3, shlex cannot deal with unicode entries
|
||||
options_str = options_str.encode('utf8')
|
||||
opts, _ = parser.parse_args(shlex.split(options_str), defaults)
|
||||
|
||||
|
|
|
|||
|
|
@ -15,9 +15,11 @@ from distutils.util import change_root
|
|||
from email.parser import FeedParser
|
||||
|
||||
from pip._vendor import pkg_resources, six
|
||||
from pip._vendor.distlib.markers import interpret as markers_interpret
|
||||
from pip._vendor.packaging import specifiers
|
||||
from pip._vendor.packaging.markers import Marker
|
||||
from pip._vendor.packaging.requirements import InvalidRequirement, Requirement
|
||||
from pip._vendor.packaging.utils import canonicalize_name
|
||||
from pip._vendor.packaging.version import Version, parse as parse_version
|
||||
from pip._vendor.six.moves import configparser
|
||||
|
||||
import pip.wheel
|
||||
|
|
@ -25,7 +27,7 @@ import pip.wheel
|
|||
from pip.compat import native_str, get_stdlib, WINDOWS
|
||||
from pip.download import is_url, url_to_path, path_to_url, is_archive_file
|
||||
from pip.exceptions import (
|
||||
InstallationError, UninstallationError, UnsupportedWheel,
|
||||
InstallationError, UninstallationError,
|
||||
)
|
||||
from pip.locations import (
|
||||
bin_py, running_under_virtualenv, PIP_DELETE_MARKER_FILENAME, bin_user,
|
||||
|
|
@ -38,14 +40,13 @@ from pip.utils import (
|
|||
)
|
||||
|
||||
from pip.utils.hashes import Hashes
|
||||
from pip.utils.deprecation import RemovedInPip9Warning, RemovedInPip10Warning
|
||||
from pip.utils.deprecation import RemovedInPip10Warning
|
||||
from pip.utils.logging import indent_log
|
||||
from pip.utils.setuptools_build import SETUPTOOLS_SHIM
|
||||
from pip.utils.ui import open_spinner
|
||||
from pip.req.req_uninstall import UninstallPathSet
|
||||
from pip.vcs import vcs
|
||||
from pip.wheel import move_wheel_files, Wheel
|
||||
from pip._vendor.packaging.version import Version
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
@ -65,6 +66,10 @@ def _strip_extras(path):
|
|||
return path_no_extras, extras
|
||||
|
||||
|
||||
def _safe_extras(extras):
|
||||
return set(pkg_resources.safe_extra(extra) for extra in extras)
|
||||
|
||||
|
||||
class InstallRequirement(object):
|
||||
|
||||
def __init__(self, req, comes_from, source_dir=None, editable=False,
|
||||
|
|
@ -74,8 +79,8 @@ class InstallRequirement(object):
|
|||
self.extras = ()
|
||||
if isinstance(req, six.string_types):
|
||||
try:
|
||||
req = pkg_resources.Requirement.parse(req)
|
||||
except pkg_resources.RequirementParseError:
|
||||
req = Requirement(req)
|
||||
except InvalidRequirement:
|
||||
if os.path.sep in req:
|
||||
add_msg = "It looks like a path. Does it exist ?"
|
||||
elif '=' in req and not any(op in req for op in operators):
|
||||
|
|
@ -84,7 +89,7 @@ class InstallRequirement(object):
|
|||
add_msg = traceback.format_exc()
|
||||
raise InstallationError(
|
||||
"Invalid requirement: '%s'\n%s" % (req, add_msg))
|
||||
self.extras = req.extras
|
||||
self.extras = _safe_extras(req.extras)
|
||||
|
||||
self.req = req
|
||||
self.comes_from = comes_from
|
||||
|
|
@ -95,7 +100,10 @@ class InstallRequirement(object):
|
|||
self._wheel_cache = wheel_cache
|
||||
self.link = self.original_link = link
|
||||
self.as_egg = as_egg
|
||||
self.markers = markers
|
||||
if markers is not None:
|
||||
self.markers = markers
|
||||
else:
|
||||
self.markers = req and req.marker
|
||||
self._egg_info_path = None
|
||||
# This holds the pkg_resources.Distribution object if this requirement
|
||||
# is already available:
|
||||
|
|
@ -148,7 +156,7 @@ class InstallRequirement(object):
|
|||
wheel_cache=wheel_cache)
|
||||
|
||||
if extras_override is not None:
|
||||
res.extras = extras_override
|
||||
res.extras = _safe_extras(extras_override)
|
||||
|
||||
return res
|
||||
|
||||
|
|
@ -170,6 +178,8 @@ class InstallRequirement(object):
|
|||
markers = markers.strip()
|
||||
if not markers:
|
||||
markers = None
|
||||
else:
|
||||
markers = Marker(markers)
|
||||
else:
|
||||
markers = None
|
||||
name = name.strip()
|
||||
|
|
@ -209,11 +219,6 @@ class InstallRequirement(object):
|
|||
# wheel file
|
||||
if link.is_wheel:
|
||||
wheel = Wheel(link.filename) # can raise InvalidWheelFilename
|
||||
if not wheel.supported():
|
||||
raise UnsupportedWheel(
|
||||
"%s is not a supported wheel on this platform." %
|
||||
wheel.filename
|
||||
)
|
||||
req = "%s==%s" % (wheel.name, wheel.version)
|
||||
else:
|
||||
# set the req to the egg fragment. when it's not there, this
|
||||
|
|
@ -230,8 +235,8 @@ class InstallRequirement(object):
|
|||
wheel_cache=wheel_cache, constraint=constraint)
|
||||
|
||||
if extras:
|
||||
res.extras = pkg_resources.Requirement.parse('__placeholder__' +
|
||||
extras).extras
|
||||
res.extras = _safe_extras(
|
||||
Requirement('placeholder' + extras).extras)
|
||||
|
||||
return res
|
||||
|
||||
|
|
@ -312,7 +317,12 @@ class InstallRequirement(object):
|
|||
# package is not available yet so we create a temp directory
|
||||
# Once run_egg_info will have run, we'll be able
|
||||
# to fix it via _correct_build_location
|
||||
self._temp_build_dir = tempfile.mkdtemp('-build', 'pip-')
|
||||
# Some systems have /tmp as a symlink which confuses custom
|
||||
# builds (such as numpy). Thus, we ensure that the real path
|
||||
# is returned.
|
||||
self._temp_build_dir = os.path.realpath(
|
||||
tempfile.mkdtemp('-build', 'pip-')
|
||||
)
|
||||
self._ideal_build_dir = build_dir
|
||||
return self._temp_build_dir
|
||||
if self.editable:
|
||||
|
|
@ -362,7 +372,7 @@ class InstallRequirement(object):
|
|||
def name(self):
|
||||
if self.req is None:
|
||||
return None
|
||||
return native_str(self.req.project_name)
|
||||
return native_str(pkg_resources.safe_name(self.req.name))
|
||||
|
||||
@property
|
||||
def setup_py_dir(self):
|
||||
|
|
@ -426,33 +436,31 @@ class InstallRequirement(object):
|
|||
egg_info_cmd + egg_base_option,
|
||||
cwd=self.setup_py_dir,
|
||||
show_stdout=False,
|
||||
command_level=logging.DEBUG,
|
||||
command_desc='python setup.py egg_info')
|
||||
|
||||
if not self.req:
|
||||
if isinstance(
|
||||
pkg_resources.parse_version(self.pkg_info()["Version"]),
|
||||
Version):
|
||||
if isinstance(parse_version(self.pkg_info()["Version"]), Version):
|
||||
op = "=="
|
||||
else:
|
||||
op = "==="
|
||||
self.req = pkg_resources.Requirement.parse(
|
||||
self.req = Requirement(
|
||||
"".join([
|
||||
self.pkg_info()["Name"],
|
||||
op,
|
||||
self.pkg_info()["Version"],
|
||||
]))
|
||||
])
|
||||
)
|
||||
self._correct_build_location()
|
||||
else:
|
||||
metadata_name = canonicalize_name(self.pkg_info()["Name"])
|
||||
if canonicalize_name(self.req.project_name) != metadata_name:
|
||||
if canonicalize_name(self.req.name) != metadata_name:
|
||||
logger.warning(
|
||||
'Running setup.py (path:%s) egg_info for package %s '
|
||||
'produced metadata for project name %s. Fix your '
|
||||
'#egg=%s fragments.',
|
||||
self.setup_py, self.name, metadata_name, self.name
|
||||
)
|
||||
self.req = pkg_resources.Requirement.parse(metadata_name)
|
||||
self.req = Requirement(metadata_name)
|
||||
|
||||
def egg_info_data(self, filename):
|
||||
if self.satisfied_by is not None:
|
||||
|
|
@ -486,7 +494,7 @@ class InstallRequirement(object):
|
|||
# Don't search in anything that looks like a virtualenv
|
||||
# environment
|
||||
if (
|
||||
os.path.exists(
|
||||
os.path.lexists(
|
||||
os.path.join(root, dir, 'bin', 'python')
|
||||
) or
|
||||
os.path.exists(
|
||||
|
|
@ -540,7 +548,7 @@ class InstallRequirement(object):
|
|||
def assert_source_matches_version(self):
|
||||
assert self.source_dir
|
||||
version = self.pkg_info()['version']
|
||||
if version not in self.req:
|
||||
if self.req.specifier and version not in self.req.specifier:
|
||||
logger.warning(
|
||||
'Requested %s, but installing version %s',
|
||||
self,
|
||||
|
|
@ -682,6 +690,10 @@ class InstallRequirement(object):
|
|||
'easy-install.pth')
|
||||
paths_to_remove.add_pth(easy_install_pth, './' + easy_install_egg)
|
||||
|
||||
elif egg_info_exists and dist.egg_info.endswith('.dist-info'):
|
||||
for path in pip.wheel.uninstallation_paths(dist):
|
||||
paths_to_remove.add(path)
|
||||
|
||||
elif develop_egg_link:
|
||||
# develop egg
|
||||
with open(develop_egg_link, 'r') as fh:
|
||||
|
|
@ -695,10 +707,6 @@ class InstallRequirement(object):
|
|||
'easy-install.pth')
|
||||
paths_to_remove.add_pth(easy_install_pth, dist.location)
|
||||
|
||||
elif egg_info_exists and dist.egg_info.endswith('.dist-info'):
|
||||
for path in pip.wheel.uninstallation_paths(dist):
|
||||
paths_to_remove.add(path)
|
||||
|
||||
else:
|
||||
logger.debug(
|
||||
'Not sure how to uninstall: %s - Check: %s',
|
||||
|
|
@ -769,8 +777,8 @@ class InstallRequirement(object):
|
|||
archive_path = os.path.join(build_dir, archive_name)
|
||||
if os.path.exists(archive_path):
|
||||
response = ask_path_exists(
|
||||
'The file %s exists. (i)gnore, (w)ipe, (b)ackup ' %
|
||||
display_path(archive_path), ('i', 'w', 'b'))
|
||||
'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)bort ' %
|
||||
display_path(archive_path), ('i', 'w', 'b', 'a'))
|
||||
if response == 'i':
|
||||
create_archive = False
|
||||
elif response == 'w':
|
||||
|
|
@ -784,6 +792,8 @@ class InstallRequirement(object):
|
|||
display_path(dest_file),
|
||||
)
|
||||
shutil.move(archive_path, dest_file)
|
||||
elif response == 'a':
|
||||
sys.exit(-1)
|
||||
if create_archive:
|
||||
zip = zipfile.ZipFile(
|
||||
archive_path, 'w', zipfile.ZIP_DEFLATED,
|
||||
|
|
@ -816,9 +826,15 @@ class InstallRequirement(object):
|
|||
name = name.replace(os.path.sep, '/')
|
||||
return name
|
||||
|
||||
def match_markers(self):
|
||||
def match_markers(self, extras_requested=None):
|
||||
if not extras_requested:
|
||||
# Provide an extra to safely evaluate the markers
|
||||
# without matching any extra
|
||||
extras_requested = ('',)
|
||||
if self.markers is not None:
|
||||
return markers_interpret(self.markers)
|
||||
return any(
|
||||
self.markers.evaluate({'extra': extra})
|
||||
for extra in extras_requested)
|
||||
else:
|
||||
return True
|
||||
|
||||
|
|
@ -850,30 +866,8 @@ class InstallRequirement(object):
|
|||
temp_location = tempfile.mkdtemp('-record', 'pip-')
|
||||
record_filename = os.path.join(temp_location, 'install-record.txt')
|
||||
try:
|
||||
install_args = [sys.executable, "-u"]
|
||||
install_args.append('-c')
|
||||
install_args.append(SETUPTOOLS_SHIM % self.setup_py)
|
||||
install_args += list(global_options) + \
|
||||
['install', '--record', record_filename]
|
||||
|
||||
if not self.as_egg:
|
||||
install_args += ['--single-version-externally-managed']
|
||||
|
||||
if root is not None:
|
||||
install_args += ['--root', root]
|
||||
if prefix is not None:
|
||||
install_args += ['--prefix', prefix]
|
||||
|
||||
if self.pycompile:
|
||||
install_args += ["--compile"]
|
||||
else:
|
||||
install_args += ["--no-compile"]
|
||||
|
||||
if running_under_virtualenv():
|
||||
py_ver_str = 'python' + sysconfig.get_python_version()
|
||||
install_args += ['--install-headers',
|
||||
os.path.join(sys.prefix, 'include', 'site',
|
||||
py_ver_str, self.name)]
|
||||
install_args = self.get_install_args(
|
||||
global_options, record_filename, root, prefix)
|
||||
msg = 'Running setup.py install for %s' % (self.name,)
|
||||
with open_spinner(msg) as spinner:
|
||||
with indent_log():
|
||||
|
|
@ -946,6 +940,34 @@ class InstallRequirement(object):
|
|||
self.source_dir = self.build_location(parent_dir)
|
||||
return self.source_dir
|
||||
|
||||
def get_install_args(self, global_options, record_filename, root, prefix):
|
||||
install_args = [sys.executable, "-u"]
|
||||
install_args.append('-c')
|
||||
install_args.append(SETUPTOOLS_SHIM % self.setup_py)
|
||||
install_args += list(global_options) + \
|
||||
['install', '--record', record_filename]
|
||||
|
||||
if not self.as_egg:
|
||||
install_args += ['--single-version-externally-managed']
|
||||
|
||||
if root is not None:
|
||||
install_args += ['--root', root]
|
||||
if prefix is not None:
|
||||
install_args += ['--prefix', prefix]
|
||||
|
||||
if self.pycompile:
|
||||
install_args += ["--compile"]
|
||||
else:
|
||||
install_args += ["--no-compile"]
|
||||
|
||||
if running_under_virtualenv():
|
||||
py_ver_str = 'python' + sysconfig.get_python_version()
|
||||
install_args += ['--install-headers',
|
||||
os.path.join(sys.prefix, 'include', 'site',
|
||||
py_ver_str, self.name)]
|
||||
|
||||
return install_args
|
||||
|
||||
def remove_temporary_source(self):
|
||||
"""Remove the source files from this requirement, if they are marked
|
||||
for deletion"""
|
||||
|
|
@ -994,12 +1016,24 @@ class InstallRequirement(object):
|
|||
if self.req is None:
|
||||
return False
|
||||
try:
|
||||
self.satisfied_by = pkg_resources.get_distribution(self.req)
|
||||
# get_distribution() will resolve the entire list of requirements
|
||||
# anyway, and we've already determined that we need the requirement
|
||||
# in question, so strip the marker so that we don't try to
|
||||
# evaluate it.
|
||||
no_marker = Requirement(str(self.req))
|
||||
no_marker.marker = None
|
||||
self.satisfied_by = pkg_resources.get_distribution(str(no_marker))
|
||||
if self.editable and self.satisfied_by:
|
||||
self.conflicts_with = self.satisfied_by
|
||||
# when installing editables, nothing pre-existing should ever
|
||||
# satisfy
|
||||
self.satisfied_by = None
|
||||
return True
|
||||
except pkg_resources.DistributionNotFound:
|
||||
return False
|
||||
except pkg_resources.VersionConflict:
|
||||
existing_dist = pkg_resources.get_distribution(
|
||||
self.req.project_name
|
||||
self.req.name
|
||||
)
|
||||
if self.use_user_site:
|
||||
if dist_in_usersite(existing_dist):
|
||||
|
|
@ -1085,24 +1119,6 @@ def _strip_postfix(req):
|
|||
return req
|
||||
|
||||
|
||||
def _build_req_from_url(url):
|
||||
|
||||
parts = [p for p in url.split('#', 1)[0].split('/') if p]
|
||||
|
||||
req = None
|
||||
if len(parts) > 2 and parts[-2] in ('tags', 'branches', 'tag', 'branch'):
|
||||
req = parts[-3]
|
||||
elif len(parts) > 1 and parts[-1] == 'trunk':
|
||||
req = parts[-2]
|
||||
if req:
|
||||
warnings.warn(
|
||||
'Sniffing the requirement name from the url is deprecated and '
|
||||
'will be removed in the future. Please specify an #egg segment '
|
||||
'instead.', RemovedInPip9Warning,
|
||||
stacklevel=2)
|
||||
return req
|
||||
|
||||
|
||||
def parse_editable(editable_req, default_vcs=None):
|
||||
"""Parses an editable requirement into:
|
||||
- a requirement name
|
||||
|
|
@ -1142,9 +1158,7 @@ def parse_editable(editable_req, default_vcs=None):
|
|||
return (
|
||||
package_name,
|
||||
url_no_extras,
|
||||
pkg_resources.Requirement.parse(
|
||||
'__placeholder__' + extras
|
||||
).extras,
|
||||
Requirement("placeholder" + extras.lower()).extras,
|
||||
)
|
||||
else:
|
||||
return package_name, url_no_extras, None
|
||||
|
|
@ -1156,6 +1170,11 @@ def parse_editable(editable_req, default_vcs=None):
|
|||
|
||||
if '+' not in url:
|
||||
if default_vcs:
|
||||
warnings.warn(
|
||||
"--default-vcs has been deprecated and will be removed in "
|
||||
"the future.",
|
||||
RemovedInPip10Warning,
|
||||
)
|
||||
url = default_vcs + '+' + url
|
||||
else:
|
||||
raise InstallationError(
|
||||
|
|
@ -1174,7 +1193,9 @@ def parse_editable(editable_req, default_vcs=None):
|
|||
|
||||
package_name = Link(url).egg_fragment
|
||||
if not package_name:
|
||||
package_name = _build_req_from_url(editable_req)
|
||||
raise InstallationError(
|
||||
"Could not detect requirement name, please specify one with #egg="
|
||||
)
|
||||
if not package_name:
|
||||
raise InstallationError(
|
||||
'--editable=%s is not the right format; it must have '
|
||||
|
|
|
|||
|
|
@ -14,14 +14,16 @@ from pip.download import (is_file_url, is_dir_url, is_vcs_url, url_to_path,
|
|||
from pip.exceptions import (InstallationError, BestVersionAlreadyInstalled,
|
||||
DistributionNotFound, PreviousBuildDirError,
|
||||
HashError, HashErrors, HashUnpinned,
|
||||
DirectoryUrlHashUnsupported, VcsHashUnsupported)
|
||||
DirectoryUrlHashUnsupported, VcsHashUnsupported,
|
||||
UnsupportedPythonVersion)
|
||||
from pip.req.req_install import InstallRequirement
|
||||
from pip.utils import (
|
||||
display_path, dist_in_usersite, ensure_dir, normalize_path)
|
||||
from pip.utils.hashes import MissingHashes
|
||||
from pip.utils.logging import indent_log
|
||||
from pip.utils.packaging import check_dist_requires_python
|
||||
from pip.vcs import vcs
|
||||
|
||||
from pip.wheel import Wheel
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -140,11 +142,12 @@ class Installed(DistAbstraction):
|
|||
class RequirementSet(object):
|
||||
|
||||
def __init__(self, build_dir, src_dir, download_dir, upgrade=False,
|
||||
ignore_installed=False, as_egg=False, target_dir=None,
|
||||
ignore_dependencies=False, force_reinstall=False,
|
||||
use_user_site=False, session=None, pycompile=True,
|
||||
isolated=False, wheel_download_dir=None,
|
||||
wheel_cache=None, require_hashes=False):
|
||||
upgrade_strategy=None, ignore_installed=False, as_egg=False,
|
||||
target_dir=None, ignore_dependencies=False,
|
||||
force_reinstall=False, use_user_site=False, session=None,
|
||||
pycompile=True, isolated=False, wheel_download_dir=None,
|
||||
wheel_cache=None, require_hashes=False,
|
||||
ignore_requires_python=False):
|
||||
"""Create a RequirementSet.
|
||||
|
||||
:param wheel_download_dir: Where still-packed .whl files should be
|
||||
|
|
@ -170,6 +173,7 @@ class RequirementSet(object):
|
|||
# the wheelhouse output by 'pip wheel'.
|
||||
self.download_dir = download_dir
|
||||
self.upgrade = upgrade
|
||||
self.upgrade_strategy = upgrade_strategy
|
||||
self.ignore_installed = ignore_installed
|
||||
self.force_reinstall = force_reinstall
|
||||
self.requirements = Requirements()
|
||||
|
|
@ -177,6 +181,7 @@ class RequirementSet(object):
|
|||
self.requirement_aliases = {}
|
||||
self.unnamed_requirements = []
|
||||
self.ignore_dependencies = ignore_dependencies
|
||||
self.ignore_requires_python = ignore_requires_python
|
||||
self.successfully_downloaded = []
|
||||
self.successfully_installed = []
|
||||
self.reqs_to_cleanup = []
|
||||
|
|
@ -207,7 +212,8 @@ class RequirementSet(object):
|
|||
return ('<%s object; %d requirement(s): %s>'
|
||||
% (self.__class__.__name__, len(reqs), reqs_str))
|
||||
|
||||
def add_requirement(self, install_req, parent_req_name=None):
|
||||
def add_requirement(self, install_req, parent_req_name=None,
|
||||
extras_requested=None):
|
||||
"""Add install_req as a requirement to install.
|
||||
|
||||
:param parent_req_name: The name of the requirement that needed this
|
||||
|
|
@ -216,21 +222,35 @@ class RequirementSet(object):
|
|||
links that point outside the Requirements set. parent_req must
|
||||
already be added. Note that None implies that this is a user
|
||||
supplied requirement, vs an inferred one.
|
||||
:param extras_requested: an iterable of extras used to evaluate the
|
||||
environement markers.
|
||||
:return: Additional requirements to scan. That is either [] if
|
||||
the requirement is not applicable, or [install_req] if the
|
||||
requirement is applicable and has just been added.
|
||||
"""
|
||||
name = install_req.name
|
||||
if not install_req.match_markers():
|
||||
logger.warning("Ignoring %s: markers %r don't match your "
|
||||
if not install_req.match_markers(extras_requested):
|
||||
logger.warning("Ignoring %s: markers '%s' don't match your "
|
||||
"environment", install_req.name,
|
||||
install_req.markers)
|
||||
return []
|
||||
|
||||
# This check has to come after we filter requirements with the
|
||||
# environment markers.
|
||||
if install_req.link and install_req.link.is_wheel:
|
||||
wheel = Wheel(install_req.link.filename)
|
||||
if not wheel.supported():
|
||||
raise InstallationError(
|
||||
"%s is not a supported wheel on this platform." %
|
||||
wheel.filename
|
||||
)
|
||||
|
||||
install_req.as_egg = self.as_egg
|
||||
install_req.use_user_site = self.use_user_site
|
||||
install_req.target_dir = self.target_dir
|
||||
install_req.pycompile = self.pycompile
|
||||
install_req.is_direct = (parent_req_name is None)
|
||||
|
||||
if not name:
|
||||
# url or path requirement w/o an egg fragment
|
||||
self.unnamed_requirements.append(install_req)
|
||||
|
|
@ -243,7 +263,7 @@ class RequirementSet(object):
|
|||
if (parent_req_name is None and existing_req and not
|
||||
existing_req.constraint and
|
||||
existing_req.extras == install_req.extras and not
|
||||
existing_req.req.specs == install_req.req.specs):
|
||||
existing_req.req.specifier == install_req.req.specifier):
|
||||
raise InstallationError(
|
||||
'Double requirement given: %s (already in %s, name=%r)'
|
||||
% (install_req, existing_req, name))
|
||||
|
|
@ -365,6 +385,13 @@ class RequirementSet(object):
|
|||
if hash_errors:
|
||||
raise hash_errors
|
||||
|
||||
def _is_upgrade_allowed(self, req):
|
||||
return self.upgrade and (
|
||||
self.upgrade_strategy == "eager" or (
|
||||
self.upgrade_strategy == "only-if-needed" and req.is_direct
|
||||
)
|
||||
)
|
||||
|
||||
def _check_skip_installed(self, req_to_install, finder):
|
||||
"""Check if req_to_install should be skipped.
|
||||
|
||||
|
|
@ -386,17 +413,20 @@ class RequirementSet(object):
|
|||
# Check whether to upgrade/reinstall this req or not.
|
||||
req_to_install.check_if_exists()
|
||||
if req_to_install.satisfied_by:
|
||||
skip_reason = 'satisfied (use --upgrade to upgrade)'
|
||||
if self.upgrade:
|
||||
best_installed = False
|
||||
upgrade_allowed = self._is_upgrade_allowed(req_to_install)
|
||||
|
||||
# Is the best version is installed.
|
||||
best_installed = False
|
||||
|
||||
if upgrade_allowed:
|
||||
# For link based requirements we have to pull the
|
||||
# tree down and inspect to assess the version #, so
|
||||
# its handled way down.
|
||||
if not (self.force_reinstall or req_to_install.link):
|
||||
try:
|
||||
finder.find_requirement(req_to_install, self.upgrade)
|
||||
finder.find_requirement(
|
||||
req_to_install, upgrade_allowed)
|
||||
except BestVersionAlreadyInstalled:
|
||||
skip_reason = 'up-to-date'
|
||||
best_installed = True
|
||||
except DistributionNotFound:
|
||||
# No distribution found, so we squash the
|
||||
|
|
@ -413,6 +443,15 @@ class RequirementSet(object):
|
|||
req_to_install.conflicts_with = \
|
||||
req_to_install.satisfied_by
|
||||
req_to_install.satisfied_by = None
|
||||
|
||||
# Figure out a nice message to say why we're skipping this.
|
||||
if best_installed:
|
||||
skip_reason = 'already up-to-date'
|
||||
elif self.upgrade_strategy == "only-if-needed":
|
||||
skip_reason = 'not upgraded as not directly required'
|
||||
else:
|
||||
skip_reason = 'already satisfied'
|
||||
|
||||
return skip_reason
|
||||
else:
|
||||
return None
|
||||
|
|
@ -453,7 +492,7 @@ class RequirementSet(object):
|
|||
'req_to_install.satisfied_by is set to %r'
|
||||
% (req_to_install.satisfied_by,))
|
||||
logger.info(
|
||||
'Requirement already %s: %s', skip_reason,
|
||||
'Requirement %s: %s', skip_reason,
|
||||
req_to_install)
|
||||
else:
|
||||
if (req_to_install.link and
|
||||
|
|
@ -479,6 +518,7 @@ class RequirementSet(object):
|
|||
abstract_dist.prep_for_dist()
|
||||
if self.is_download:
|
||||
req_to_install.archive(self.download_dir)
|
||||
req_to_install.check_if_exists()
|
||||
elif req_to_install.satisfied_by:
|
||||
if require_hashes:
|
||||
logger.debug(
|
||||
|
|
@ -509,7 +549,10 @@ class RequirementSet(object):
|
|||
% (req_to_install, req_to_install.source_dir)
|
||||
)
|
||||
req_to_install.populate_link(
|
||||
finder, self.upgrade, require_hashes)
|
||||
finder,
|
||||
self._is_upgrade_allowed(req_to_install),
|
||||
require_hashes
|
||||
)
|
||||
# We can't hit this spot and have populate_link return None.
|
||||
# req_to_install.satisfied_by is None here (because we're
|
||||
# guarded) and upgrade has no impact except when satisfied_by
|
||||
|
|
@ -619,9 +662,17 @@ class RequirementSet(object):
|
|||
# # parse dependencies # #
|
||||
# ###################### #
|
||||
dist = abstract_dist.dist(finder)
|
||||
try:
|
||||
check_dist_requires_python(dist)
|
||||
except UnsupportedPythonVersion as e:
|
||||
if self.ignore_requires_python:
|
||||
logger.warning(e.args[0])
|
||||
else:
|
||||
req_to_install.remove_temporary_source()
|
||||
raise
|
||||
more_reqs = []
|
||||
|
||||
def add_req(subreq):
|
||||
def add_req(subreq, extras_requested):
|
||||
sub_install_req = InstallRequirement(
|
||||
str(subreq),
|
||||
req_to_install,
|
||||
|
|
@ -629,7 +680,8 @@ class RequirementSet(object):
|
|||
wheel_cache=self._wheel_cache,
|
||||
)
|
||||
more_reqs.extend(self.add_requirement(
|
||||
sub_install_req, req_to_install.name))
|
||||
sub_install_req, req_to_install.name,
|
||||
extras_requested=extras_requested))
|
||||
|
||||
# We add req_to_install before its dependencies, so that we
|
||||
# can refer to it when adding dependencies.
|
||||
|
|
@ -656,7 +708,7 @@ class RequirementSet(object):
|
|||
set(dist.extras) & set(req_to_install.extras)
|
||||
)
|
||||
for subreq in dist.requires(available_requested):
|
||||
add_req(subreq)
|
||||
add_req(subreq, extras_requested=available_requested)
|
||||
|
||||
# cleanup tmp src
|
||||
self.reqs_to_cleanup.append(req_to_install)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue