python (3.12.0)
1 """Module containing bug report helper(s)."""
2
3 import json
4 import platform
5 import ssl
6 import sys
7
8 from pip._vendor import idna
9 from pip._vendor import urllib3
10
11 from . import __version__ as requests_version
12
13 charset_normalizer = None
14
15 try:
16 from pip._vendor import chardet
17 except ImportError:
18 chardet = None
19
20 try:
21 from pip._vendor.urllib3.contrib import pyopenssl
22 except ImportError:
23 pyopenssl = None
24 OpenSSL = None
25 cryptography = None
26 else:
27 import cryptography
28 import OpenSSL
29
30
31 def _implementation():
32 """Return a dict with the Python implementation and version.
33
34 Provide both the name and the version of the Python implementation
35 currently running. For example, on CPython 3.10.3 it will return
36 {'name': 'CPython', 'version': '3.10.3'}.
37
38 This function works best on CPython and PyPy: in particular, it probably
39 doesn't work for Jython or IronPython. Future investigation should be done
40 to work out the correct shape of the code for those platforms.
41 """
42 implementation = platform.python_implementation()
43
44 if implementation == "CPython":
45 implementation_version = platform.python_version()
46 elif implementation == "PyPy":
47 implementation_version = "{}.{}.{}".format(
48 sys.pypy_version_info.major,
49 sys.pypy_version_info.minor,
50 sys.pypy_version_info.micro,
51 )
52 if sys.pypy_version_info.releaselevel != "final":
53 implementation_version = "".join(
54 [implementation_version, sys.pypy_version_info.releaselevel]
55 )
56 elif implementation == "Jython":
57 implementation_version = platform.python_version() # Complete Guess
58 elif implementation == "IronPython":
59 implementation_version = platform.python_version() # Complete Guess
60 else:
61 implementation_version = "Unknown"
62
63 return {"name": implementation, "version": implementation_version}
64
65
66 def info():
67 """Generate information for a bug report."""
68 try:
69 platform_info = {
70 "system": platform.system(),
71 "release": platform.release(),
72 }
73 except OSError:
74 platform_info = {
75 "system": "Unknown",
76 "release": "Unknown",
77 }
78
79 implementation_info = _implementation()
80 urllib3_info = {"version": urllib3.__version__}
81 charset_normalizer_info = {"version": None}
82 chardet_info = {"version": None}
83 if charset_normalizer:
84 charset_normalizer_info = {"version": charset_normalizer.__version__}
85 if chardet:
86 chardet_info = {"version": chardet.__version__}
87
88 pyopenssl_info = {
89 "version": None,
90 "openssl_version": "",
91 }
92 if OpenSSL:
93 pyopenssl_info = {
94 "version": OpenSSL.__version__,
95 "openssl_version": f"{OpenSSL.SSL.OPENSSL_VERSION_NUMBER:x}",
96 }
97 cryptography_info = {
98 "version": getattr(cryptography, "__version__", ""),
99 }
100 idna_info = {
101 "version": getattr(idna, "__version__", ""),
102 }
103
104 system_ssl = ssl.OPENSSL_VERSION_NUMBER
105 system_ssl_info = {"version": f"{system_ssl:x}" if system_ssl is not None else ""}
106
107 return {
108 "platform": platform_info,
109 "implementation": implementation_info,
110 "system_ssl": system_ssl_info,
111 "using_pyopenssl": pyopenssl is not None,
112 "using_charset_normalizer": chardet is None,
113 "pyOpenSSL": pyopenssl_info,
114 "urllib3": urllib3_info,
115 "chardet": chardet_info,
116 "charset_normalizer": charset_normalizer_info,
117 "cryptography": cryptography_info,
118 "idna": idna_info,
119 "requests": {
120 "version": requests_version,
121 },
122 }
123
124
125 def main():
126 """Pretty-print the bug information as JSON."""
127 print(json.dumps(info(), sort_keys=True, indent=2))
128
129
130 if __name__ == "__main__":
131 main()