debug.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. """Inspect a target Python interpreter virtual environment wise."""
  2. from __future__ import annotations
  3. import sys # built-in
  4. def encode_path(value: object) -> str | None:
  5. if value is None:
  6. return None
  7. if not isinstance(value, (str, bytes)):
  8. value = repr(value) if isinstance(value, type) else repr(type(value))
  9. if isinstance(value, bytes):
  10. value = value.decode(sys.getfilesystemencoding())
  11. return value
  12. def encode_list_path(value: list[object]) -> list[str | None]:
  13. return [encode_path(i) for i in value]
  14. def run() -> None: # noqa: C901
  15. """Print debug data about the virtual environment."""
  16. try:
  17. from collections import OrderedDict # noqa: PLC0415
  18. except ImportError: # pragma: no cover
  19. # this is possible if the standard library cannot be accessed
  20. OrderedDict = dict # type: ignore[misc] # pragma: no cover # noqa: N806
  21. result: dict = OrderedDict([("sys", OrderedDict())])
  22. path_keys = (
  23. "executable",
  24. "_base_executable",
  25. "prefix",
  26. "base_prefix",
  27. "real_prefix",
  28. "exec_prefix",
  29. "base_exec_prefix",
  30. "path",
  31. "meta_path",
  32. )
  33. for key in path_keys:
  34. value = getattr(sys, key, None)
  35. value = encode_list_path(value) if isinstance(value, list) else encode_path(value)
  36. result["sys"][key] = value
  37. result["sys"]["fs_encoding"] = sys.getfilesystemencoding()
  38. result["sys"]["io_encoding"] = getattr(sys.stdout, "encoding", None)
  39. result["version"] = sys.version
  40. try:
  41. import sysconfig # noqa: PLC0415
  42. # https://bugs.python.org/issue22199
  43. makefile = getattr(sysconfig, "get_makefile_filename", getattr(sysconfig, "_get_makefile_filename", None))
  44. if makefile is not None:
  45. result["makefile_filename"] = encode_path(makefile())
  46. except ImportError:
  47. pass
  48. import os # landmark # noqa: PLC0415
  49. result["os"] = repr(os)
  50. try:
  51. import site # site # noqa: PLC0415
  52. result["site"] = repr(site)
  53. except ImportError as exception: # pragma: no cover
  54. result["site"] = repr(exception) # pragma: no cover
  55. try:
  56. import datetime # site # noqa: PLC0415
  57. result["datetime"] = repr(datetime)
  58. except ImportError as exception: # pragma: no cover
  59. result["datetime"] = repr(exception) # pragma: no cover
  60. try:
  61. import math # site # noqa: PLC0415
  62. result["math"] = repr(math)
  63. except ImportError as exception: # pragma: no cover
  64. result["math"] = repr(exception) # pragma: no cover
  65. # try to print out, this will validate if other core modules are available (json in this case)
  66. try:
  67. import json # noqa: PLC0415
  68. result["json"] = repr(json)
  69. except ImportError as exception:
  70. result["json"] = repr(exception)
  71. else:
  72. try:
  73. content = json.dumps(result, indent=2)
  74. sys.stdout.write(content)
  75. except (ValueError, TypeError) as exception: # pragma: no cover
  76. sys.stderr.write(repr(exception))
  77. sys.stdout.write(repr(result)) # pragma: no cover
  78. raise SystemExit(1) # noqa: B904 # pragma: no cover
  79. if __name__ == "__main__":
  80. run()