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 ) |