Coverage for src/devboard/debug.py: 90.12%
61 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-03-19 20:21 +0100
« prev ^ index » next coverage.py v7.4.4, created at 2024-03-19 20:21 +0100
1"""Debugging utilities."""
3from __future__ import annotations
5import os
6import platform
7import sys
8from dataclasses import dataclass
9from importlib import metadata
12@dataclass
13class Variable:
14 """Dataclass describing an environment variable."""
16 name: str
17 """Variable name."""
18 value: str
19 """Variable value."""
22@dataclass
23class Package:
24 """Dataclass describing a Python package."""
26 name: str
27 """Package name."""
28 version: str
29 """Package version."""
32@dataclass
33class Environment:
34 """Dataclass to store environment information."""
36 interpreter_name: str
37 """Python interpreter name."""
38 interpreter_version: str
39 """Python interpreter version."""
40 platform: str
41 """Operating System."""
42 packages: list[Package]
43 """Installed packages."""
44 variables: list[Variable]
45 """Environment variables."""
48def _interpreter_name_version() -> tuple[str, str]:
49 if hasattr(sys, "implementation"): 49 ↛ 56line 49 didn't jump to line 56, because the condition on line 49 was never false
50 impl = sys.implementation.version
51 version = f"{impl.major}.{impl.minor}.{impl.micro}"
52 kind = impl.releaselevel
53 if kind != "final": 53 ↛ 54line 53 didn't jump to line 54, because the condition on line 53 was never true
54 version += kind[0] + str(impl.serial)
55 return sys.implementation.name, version
56 return "", "0.0.0"
59def get_version(dist: str = "devboard") -> str:
60 """Get version of the given distribution.
62 Parameters:
63 dist: A distribution name.
65 Returns:
66 A version number.
67 """
68 try:
69 return metadata.version(dist)
70 except metadata.PackageNotFoundError:
71 return "0.0.0"
74def get_debug_info() -> Environment:
75 """Get debug/environment information.
77 Returns:
78 Environment information.
79 """
80 py_name, py_version = _interpreter_name_version()
81 packages = ["devboard"]
82 variables = ["PYTHONPATH", *[var for var in os.environ if var.startswith("DEVBOARD")]]
83 return Environment(
84 interpreter_name=py_name,
85 interpreter_version=py_version,
86 platform=platform.platform(),
87 variables=[Variable(var, val) for var in variables if (val := os.getenv(var))],
88 packages=[Package(pkg, get_version(pkg)) for pkg in packages],
89 )
92def print_debug_info() -> None:
93 """Print debug/environment information."""
94 info = get_debug_info()
95 print(f"- __System__: {info.platform}")
96 print(f"- __Python__: {info.interpreter_name} {info.interpreter_version}")
97 print("- __Environment variables__:")
98 for var in info.variables:
99 print(f" - `{var.name}`: `{var.value}`")
100 print("- __Installed packages__:")
101 for pkg in info.packages:
102 print(f" - `{pkg.name}` v{pkg.version}")
105if __name__ == "__main__": 105 ↛ 106line 105 didn't jump to line 106, because the condition on line 105 was never true
106 print_debug_info()