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