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