help.py 3.9 KB

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