comparison env/lib/python3.9/site-packages/pip/_internal/commands/debug.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4f3585e2f14b
1 import locale
2 import logging
3 import os
4 import sys
5
6 import pip._vendor
7 from pip._vendor import pkg_resources
8 from pip._vendor.certifi import where
9 from pip._vendor.packaging.version import parse as parse_version
10
11 from pip import __file__ as pip_location
12 from pip._internal.cli import cmdoptions
13 from pip._internal.cli.base_command import Command
14 from pip._internal.cli.cmdoptions import make_target_python
15 from pip._internal.cli.status_codes import SUCCESS
16 from pip._internal.utils.logging import indent_log
17 from pip._internal.utils.misc import get_pip_version
18 from pip._internal.utils.typing import MYPY_CHECK_RUNNING
19
20 if MYPY_CHECK_RUNNING:
21 from optparse import Values
22 from types import ModuleType
23 from typing import Dict, List, Optional
24
25 from pip._internal.configuration import Configuration
26
27 logger = logging.getLogger(__name__)
28
29
30 def show_value(name, value):
31 # type: (str, Optional[str]) -> None
32 logger.info('%s: %s', name, value)
33
34
35 def show_sys_implementation():
36 # type: () -> None
37 logger.info('sys.implementation:')
38 implementation_name = sys.implementation.name
39 with indent_log():
40 show_value('name', implementation_name)
41
42
43 def create_vendor_txt_map():
44 # type: () -> Dict[str, str]
45 vendor_txt_path = os.path.join(
46 os.path.dirname(pip_location),
47 '_vendor',
48 'vendor.txt'
49 )
50
51 with open(vendor_txt_path) as f:
52 # Purge non version specifying lines.
53 # Also, remove any space prefix or suffixes (including comments).
54 lines = [line.strip().split(' ', 1)[0]
55 for line in f.readlines() if '==' in line]
56
57 # Transform into "module" -> version dict.
58 return dict(line.split('==', 1) for line in lines) # type: ignore
59
60
61 def get_module_from_module_name(module_name):
62 # type: (str) -> ModuleType
63 # Module name can be uppercase in vendor.txt for some reason...
64 module_name = module_name.lower()
65 # PATCH: setuptools is actually only pkg_resources.
66 if module_name == 'setuptools':
67 module_name = 'pkg_resources'
68
69 __import__(
70 f'pip._vendor.{module_name}',
71 globals(),
72 locals(),
73 level=0
74 )
75 return getattr(pip._vendor, module_name)
76
77
78 def get_vendor_version_from_module(module_name):
79 # type: (str) -> Optional[str]
80 module = get_module_from_module_name(module_name)
81 version = getattr(module, '__version__', None)
82
83 if not version:
84 # Try to find version in debundled module info
85 pkg_set = pkg_resources.WorkingSet([os.path.dirname(module.__file__)])
86 package = pkg_set.find(pkg_resources.Requirement.parse(module_name))
87 version = getattr(package, 'version', None)
88
89 return version
90
91
92 def show_actual_vendor_versions(vendor_txt_versions):
93 # type: (Dict[str, str]) -> None
94 """Log the actual version and print extra info if there is
95 a conflict or if the actual version could not be imported.
96 """
97 for module_name, expected_version in vendor_txt_versions.items():
98 extra_message = ''
99 actual_version = get_vendor_version_from_module(module_name)
100 if not actual_version:
101 extra_message = ' (Unable to locate actual module version, using'\
102 ' vendor.txt specified version)'
103 actual_version = expected_version
104 elif parse_version(actual_version) != parse_version(expected_version):
105 extra_message = ' (CONFLICT: vendor.txt suggests version should'\
106 ' be {})'.format(expected_version)
107 logger.info('%s==%s%s', module_name, actual_version, extra_message)
108
109
110 def show_vendor_versions():
111 # type: () -> None
112 logger.info('vendored library versions:')
113
114 vendor_txt_versions = create_vendor_txt_map()
115 with indent_log():
116 show_actual_vendor_versions(vendor_txt_versions)
117
118
119 def show_tags(options):
120 # type: (Values) -> None
121 tag_limit = 10
122
123 target_python = make_target_python(options)
124 tags = target_python.get_tags()
125
126 # Display the target options that were explicitly provided.
127 formatted_target = target_python.format_given()
128 suffix = ''
129 if formatted_target:
130 suffix = f' (target: {formatted_target})'
131
132 msg = 'Compatible tags: {}{}'.format(len(tags), suffix)
133 logger.info(msg)
134
135 if options.verbose < 1 and len(tags) > tag_limit:
136 tags_limited = True
137 tags = tags[:tag_limit]
138 else:
139 tags_limited = False
140
141 with indent_log():
142 for tag in tags:
143 logger.info(str(tag))
144
145 if tags_limited:
146 msg = (
147 '...\n'
148 '[First {tag_limit} tags shown. Pass --verbose to show all.]'
149 ).format(tag_limit=tag_limit)
150 logger.info(msg)
151
152
153 def ca_bundle_info(config):
154 # type: (Configuration) -> str
155 levels = set()
156 for key, _ in config.items():
157 levels.add(key.split('.')[0])
158
159 if not levels:
160 return "Not specified"
161
162 levels_that_override_global = ['install', 'wheel', 'download']
163 global_overriding_level = [
164 level for level in levels if level in levels_that_override_global
165 ]
166 if not global_overriding_level:
167 return 'global'
168
169 if 'global' in levels:
170 levels.remove('global')
171 return ", ".join(levels)
172
173
174 class DebugCommand(Command):
175 """
176 Display debug information.
177 """
178
179 usage = """
180 %prog <options>"""
181 ignore_require_venv = True
182
183 def add_options(self):
184 # type: () -> None
185 cmdoptions.add_target_python_options(self.cmd_opts)
186 self.parser.insert_option_group(0, self.cmd_opts)
187 self.parser.config.load()
188
189 def run(self, options, args):
190 # type: (Values, List[str]) -> int
191 logger.warning(
192 "This command is only meant for debugging. "
193 "Do not use this with automation for parsing and getting these "
194 "details, since the output and options of this command may "
195 "change without notice."
196 )
197 show_value('pip version', get_pip_version())
198 show_value('sys.version', sys.version)
199 show_value('sys.executable', sys.executable)
200 show_value('sys.getdefaultencoding', sys.getdefaultencoding())
201 show_value('sys.getfilesystemencoding', sys.getfilesystemencoding())
202 show_value(
203 'locale.getpreferredencoding', locale.getpreferredencoding(),
204 )
205 show_value('sys.platform', sys.platform)
206 show_sys_implementation()
207
208 show_value("'cert' config value", ca_bundle_info(self.parser.config))
209 show_value("REQUESTS_CA_BUNDLE", os.environ.get('REQUESTS_CA_BUNDLE'))
210 show_value("CURL_CA_BUNDLE", os.environ.get('CURL_CA_BUNDLE'))
211 show_value("pip._vendor.certifi.where()", where())
212 show_value("pip._vendor.DEBUNDLED", pip._vendor.DEBUNDLED)
213
214 show_vendor_versions()
215
216 show_tags(options)
217
218 return SUCCESS