help.py 3.8 KB

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