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