Mercurial > repos > guerler > springsuite
comparison planemo/lib/python3.7/site-packages/pip/_internal/utils/outdated.py @ 1:56ad4e20f292 draft
"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
| author | guerler |
|---|---|
| date | Fri, 31 Jul 2020 00:32:28 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:d30785e31577 | 1:56ad4e20f292 |
|---|---|
| 1 from __future__ import absolute_import | |
| 2 | |
| 3 import datetime | |
| 4 import json | |
| 5 import logging | |
| 6 import os.path | |
| 7 import sys | |
| 8 | |
| 9 from pip._vendor import lockfile, pkg_resources | |
| 10 from pip._vendor.packaging import version as packaging_version | |
| 11 | |
| 12 from pip._internal.cli.cmdoptions import make_search_scope | |
| 13 from pip._internal.index import PackageFinder | |
| 14 from pip._internal.models.selection_prefs import SelectionPreferences | |
| 15 from pip._internal.utils.compat import WINDOWS | |
| 16 from pip._internal.utils.filesystem import check_path_owner | |
| 17 from pip._internal.utils.misc import ensure_dir, get_installed_version | |
| 18 from pip._internal.utils.packaging import get_installer | |
| 19 from pip._internal.utils.typing import MYPY_CHECK_RUNNING | |
| 20 | |
| 21 if MYPY_CHECK_RUNNING: | |
| 22 import optparse | |
| 23 from typing import Any, Dict | |
| 24 from pip._internal.download import PipSession | |
| 25 | |
| 26 | |
| 27 SELFCHECK_DATE_FMT = "%Y-%m-%dT%H:%M:%SZ" | |
| 28 | |
| 29 | |
| 30 logger = logging.getLogger(__name__) | |
| 31 | |
| 32 | |
| 33 class SelfCheckState(object): | |
| 34 def __init__(self, cache_dir): | |
| 35 # type: (str) -> None | |
| 36 self.state = {} # type: Dict[str, Any] | |
| 37 self.statefile_path = None | |
| 38 | |
| 39 # Try to load the existing state | |
| 40 if cache_dir: | |
| 41 self.statefile_path = os.path.join(cache_dir, "selfcheck.json") | |
| 42 try: | |
| 43 with open(self.statefile_path) as statefile: | |
| 44 self.state = json.load(statefile)[sys.prefix] | |
| 45 except (IOError, ValueError, KeyError): | |
| 46 # Explicitly suppressing exceptions, since we don't want to | |
| 47 # error out if the cache file is invalid. | |
| 48 pass | |
| 49 | |
| 50 def save(self, pypi_version, current_time): | |
| 51 # type: (str, datetime.datetime) -> None | |
| 52 # If we do not have a path to cache in, don't bother saving. | |
| 53 if not self.statefile_path: | |
| 54 return | |
| 55 | |
| 56 # Check to make sure that we own the directory | |
| 57 if not check_path_owner(os.path.dirname(self.statefile_path)): | |
| 58 return | |
| 59 | |
| 60 # Now that we've ensured the directory is owned by this user, we'll go | |
| 61 # ahead and make sure that all our directories are created. | |
| 62 ensure_dir(os.path.dirname(self.statefile_path)) | |
| 63 | |
| 64 # Attempt to write out our version check file | |
| 65 with lockfile.LockFile(self.statefile_path): | |
| 66 if os.path.exists(self.statefile_path): | |
| 67 with open(self.statefile_path) as statefile: | |
| 68 state = json.load(statefile) | |
| 69 else: | |
| 70 state = {} | |
| 71 | |
| 72 state[sys.prefix] = { | |
| 73 "last_check": current_time.strftime(SELFCHECK_DATE_FMT), | |
| 74 "pypi_version": pypi_version, | |
| 75 } | |
| 76 | |
| 77 with open(self.statefile_path, "w") as statefile: | |
| 78 json.dump(state, statefile, sort_keys=True, | |
| 79 separators=(",", ":")) | |
| 80 | |
| 81 | |
| 82 def was_installed_by_pip(pkg): | |
| 83 # type: (str) -> bool | |
| 84 """Checks whether pkg was installed by pip | |
| 85 | |
| 86 This is used not to display the upgrade message when pip is in fact | |
| 87 installed by system package manager, such as dnf on Fedora. | |
| 88 """ | |
| 89 try: | |
| 90 dist = pkg_resources.get_distribution(pkg) | |
| 91 return "pip" == get_installer(dist) | |
| 92 except pkg_resources.DistributionNotFound: | |
| 93 return False | |
| 94 | |
| 95 | |
| 96 def pip_version_check(session, options): | |
| 97 # type: (PipSession, optparse.Values) -> None | |
| 98 """Check for an update for pip. | |
| 99 | |
| 100 Limit the frequency of checks to once per week. State is stored either in | |
| 101 the active virtualenv or in the user's USER_CACHE_DIR keyed off the prefix | |
| 102 of the pip script path. | |
| 103 """ | |
| 104 installed_version = get_installed_version("pip") | |
| 105 if not installed_version: | |
| 106 return | |
| 107 | |
| 108 pip_version = packaging_version.parse(installed_version) | |
| 109 pypi_version = None | |
| 110 | |
| 111 try: | |
| 112 state = SelfCheckState(cache_dir=options.cache_dir) | |
| 113 | |
| 114 current_time = datetime.datetime.utcnow() | |
| 115 # Determine if we need to refresh the state | |
| 116 if "last_check" in state.state and "pypi_version" in state.state: | |
| 117 last_check = datetime.datetime.strptime( | |
| 118 state.state["last_check"], | |
| 119 SELFCHECK_DATE_FMT | |
| 120 ) | |
| 121 if (current_time - last_check).total_seconds() < 7 * 24 * 60 * 60: | |
| 122 pypi_version = state.state["pypi_version"] | |
| 123 | |
| 124 # Refresh the version if we need to or just see if we need to warn | |
| 125 if pypi_version is None: | |
| 126 # Lets use PackageFinder to see what the latest pip version is | |
| 127 search_scope = make_search_scope(options, suppress_no_index=True) | |
| 128 | |
| 129 # Pass allow_yanked=False so we don't suggest upgrading to a | |
| 130 # yanked version. | |
| 131 selection_prefs = SelectionPreferences( | |
| 132 allow_yanked=False, | |
| 133 allow_all_prereleases=False, # Explicitly set to False | |
| 134 ) | |
| 135 | |
| 136 finder = PackageFinder.create( | |
| 137 search_scope=search_scope, | |
| 138 selection_prefs=selection_prefs, | |
| 139 trusted_hosts=options.trusted_hosts, | |
| 140 session=session, | |
| 141 ) | |
| 142 candidate = finder.find_candidates("pip").get_best() | |
| 143 if candidate is None: | |
| 144 return | |
| 145 pypi_version = str(candidate.version) | |
| 146 | |
| 147 # save that we've performed a check | |
| 148 state.save(pypi_version, current_time) | |
| 149 | |
| 150 remote_version = packaging_version.parse(pypi_version) | |
| 151 | |
| 152 local_version_is_older = ( | |
| 153 pip_version < remote_version and | |
| 154 pip_version.base_version != remote_version.base_version and | |
| 155 was_installed_by_pip('pip') | |
| 156 ) | |
| 157 | |
| 158 # Determine if our pypi_version is older | |
| 159 if not local_version_is_older: | |
| 160 return | |
| 161 | |
| 162 # Advise "python -m pip" on Windows to avoid issues | |
| 163 # with overwriting pip.exe. | |
| 164 if WINDOWS: | |
| 165 pip_cmd = "python -m pip" | |
| 166 else: | |
| 167 pip_cmd = "pip" | |
| 168 logger.warning( | |
| 169 "You are using pip version %s, however version %s is " | |
| 170 "available.\nYou should consider upgrading via the " | |
| 171 "'%s install --upgrade pip' command.", | |
| 172 pip_version, pypi_version, pip_cmd | |
| 173 ) | |
| 174 except Exception: | |
| 175 logger.debug( | |
| 176 "There was an error checking the latest version of pip", | |
| 177 exc_info=True, | |
| 178 ) |
