135 lines
3.8 KiB
Python
135 lines
3.8 KiB
Python
"""Module containing bug report helper(s)."""
|
|
|
|
import json
|
|
import platform
|
|
import ssl
|
|
import sys
|
|
|
|
import idna
|
|
import urllib3
|
|
|
|
from . import __version__ as requests_version
|
|
|
|
try:
|
|
import charset_normalizer
|
|
except ImportError:
|
|
charset_normalizer = None
|
|
|
|
try:
|
|
import chardet
|
|
except ImportError:
|
|
chardet = None
|
|
|
|
try:
|
|
from urllib3.contrib import pyopenssl
|
|
except ImportError:
|
|
pyopenssl = None
|
|
OpenSSL = None
|
|
cryptography = None
|
|
else:
|
|
import cryptography
|
|
import OpenSSL
|
|
|
|
|
|
def _implementation():
|
|
"""Return a dict with the Python implementation and version.
|
|
|
|
Provide both the name and the version of the Python implementation
|
|
currently running. For example, on CPython 3.10.3 it will return
|
|
{'name': 'CPython', 'version': '3.10.3'}.
|
|
|
|
This function works best on CPython and PyPy: in particular, it probably
|
|
doesn't work for Jython or IronPython. Future investigation should be done
|
|
to work out the correct shape of the code for those platforms.
|
|
"""
|
|
implementation = platform.python_implementation()
|
|
|
|
if implementation == "CPython":
|
|
implementation_version = platform.python_version()
|
|
elif implementation == "PyPy":
|
|
implementation_version = "{}.{}.{}".format(
|
|
sys.pypy_version_info.major,
|
|
sys.pypy_version_info.minor,
|
|
sys.pypy_version_info.micro,
|
|
)
|
|
if sys.pypy_version_info.releaselevel != "final":
|
|
implementation_version = "".join(
|
|
[implementation_version, sys.pypy_version_info.releaselevel]
|
|
)
|
|
elif implementation == "Jython":
|
|
implementation_version = platform.python_version() # Complete Guess
|
|
elif implementation == "IronPython":
|
|
implementation_version = platform.python_version() # Complete Guess
|
|
else:
|
|
implementation_version = "Unknown"
|
|
|
|
return {"name": implementation, "version": implementation_version}
|
|
|
|
|
|
def info():
|
|
"""Generate information for a bug report."""
|
|
try:
|
|
platform_info = {
|
|
"system": platform.system(),
|
|
"release": platform.release(),
|
|
}
|
|
except OSError:
|
|
platform_info = {
|
|
"system": "Unknown",
|
|
"release": "Unknown",
|
|
}
|
|
|
|
implementation_info = _implementation()
|
|
urllib3_info = {"version": urllib3.__version__}
|
|
charset_normalizer_info = {"version": None}
|
|
chardet_info = {"version": None}
|
|
if charset_normalizer:
|
|
charset_normalizer_info = {"version": charset_normalizer.__version__}
|
|
if chardet:
|
|
chardet_info = {"version": chardet.__version__}
|
|
|
|
pyopenssl_info = {
|
|
"version": None,
|
|
"openssl_version": "",
|
|
}
|
|
if OpenSSL:
|
|
pyopenssl_info = {
|
|
"version": OpenSSL.__version__,
|
|
"openssl_version": f"{OpenSSL.SSL.OPENSSL_VERSION_NUMBER:x}",
|
|
}
|
|
cryptography_info = {
|
|
"version": getattr(cryptography, "__version__", ""),
|
|
}
|
|
idna_info = {
|
|
"version": getattr(idna, "__version__", ""),
|
|
}
|
|
|
|
system_ssl = ssl.OPENSSL_VERSION_NUMBER
|
|
system_ssl_info = {"version": f"{system_ssl:x}" if system_ssl is not None else ""}
|
|
|
|
return {
|
|
"platform": platform_info,
|
|
"implementation": implementation_info,
|
|
"system_ssl": system_ssl_info,
|
|
"using_pyopenssl": pyopenssl is not None,
|
|
"using_charset_normalizer": chardet is None,
|
|
"pyOpenSSL": pyopenssl_info,
|
|
"urllib3": urllib3_info,
|
|
"chardet": chardet_info,
|
|
"charset_normalizer": charset_normalizer_info,
|
|
"cryptography": cryptography_info,
|
|
"idna": idna_info,
|
|
"requests": {
|
|
"version": requests_version,
|
|
},
|
|
}
|
|
|
|
|
|
def main():
|
|
"""Pretty-print the bug information as JSON."""
|
|
print(json.dumps(info(), sort_keys=True, indent=2))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|