/ src / aria2p / debug.py
debug.py
  1  """Debugging utilities."""
  2  
  3  from __future__ import annotations
  4  
  5  import os
  6  import platform
  7  import sys
  8  from dataclasses import dataclass
  9  from importlib import metadata
 10  
 11  
 12  @dataclass
 13  class Variable:
 14      """Dataclass describing an environment variable."""
 15  
 16      name: str
 17      """Variable name."""
 18      value: str
 19      """Variable value."""
 20  
 21  
 22  @dataclass
 23  class Package:
 24      """Dataclass describing a Python package."""
 25  
 26      name: str
 27      """Package name."""
 28      version: str
 29      """Package version."""
 30  
 31  
 32  @dataclass
 33  class Environment:
 34      """Dataclass to store environment information."""
 35  
 36      interpreter_name: str
 37      """Python interpreter name."""
 38      interpreter_version: str
 39      """Python interpreter version."""
 40      interpreter_path: str
 41      """Path to Python executable."""
 42      platform: str
 43      """Operating System."""
 44      packages: list[Package]
 45      """Installed packages."""
 46      variables: list[Variable]
 47      """Environment variables."""
 48  
 49  
 50  def _interpreter_name_version() -> tuple[str, str]:
 51      if hasattr(sys, "implementation"):
 52          impl = sys.implementation.version
 53          version = f"{impl.major}.{impl.minor}.{impl.micro}"
 54          kind = impl.releaselevel
 55          if kind != "final":
 56              version += kind[0] + str(impl.serial)
 57          return sys.implementation.name, version
 58      return "", "0.0.0"
 59  
 60  
 61  def get_version(dist: str = "aria2p") -> str:
 62      """Get version of the given distribution.
 63  
 64      Parameters:
 65          dist: A distribution name.
 66  
 67      Returns:
 68          A version number.
 69      """
 70      try:
 71          return metadata.version(dist)
 72      except metadata.PackageNotFoundError:
 73          return "0.0.0"
 74  
 75  
 76  def get_debug_info() -> Environment:
 77      """Get debug/environment information.
 78  
 79      Returns:
 80          Environment information.
 81      """
 82      py_name, py_version = _interpreter_name_version()
 83      packages = ["aria2p"]
 84      variables = ["PYTHONPATH", *[var for var in os.environ if var.startswith("ARIA2P")]]
 85      return Environment(
 86          interpreter_name=py_name,
 87          interpreter_version=py_version,
 88          interpreter_path=sys.executable,
 89          platform=platform.platform(),
 90          variables=[Variable(var, val) for var in variables if (val := os.getenv(var))],
 91          packages=[Package(pkg, get_version(pkg)) for pkg in packages],
 92      )
 93  
 94  
 95  def print_debug_info() -> None:
 96      """Print debug/environment information."""
 97      info = get_debug_info()
 98      print(f"- __System__: {info.platform}")
 99      print(f"- __Python__: {info.interpreter_name} {info.interpreter_version} ({info.interpreter_path})")
100      print("- __Environment variables__:")
101      for var in info.variables:
102          print(f"  - `{var.name}`: `{var.value}`")
103      print("- __Installed packages__:")
104      for pkg in info.packages:
105          print(f"  - `{pkg.name}` v{pkg.version}")
106  
107  
108  if __name__ == "__main__":
109      print_debug_info()