Coverage for src/_griffe/debug.py: 94.94%

61 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-08-15 16:47 +0200

1# This module is here to help users report bugs. 

2# It provides a function to print environment information, 

3# which is called from the public `griffe.debug` module 

4# (when called with `python -m griffe.debug`) 

5# or thanks to the `--debug-info` CLI flag. 

6 

7from __future__ import annotations 

8 

9import os 

10import platform 

11import sys 

12from dataclasses import dataclass 

13from importlib import metadata 

14 

15 

16@dataclass 

17class _Variable: 

18 """Dataclass describing an environment variable.""" 

19 

20 name: str 

21 """Variable name.""" 

22 value: str 

23 """Variable value.""" 

24 

25 

26@dataclass 

27class _Package: 

28 """Dataclass describing a Python package.""" 

29 

30 name: str 

31 """Package name.""" 

32 version: str 

33 """Package version.""" 

34 

35 

36@dataclass 

37class _Environment: 

38 """Dataclass to store environment information.""" 

39 

40 interpreter_name: str 

41 """Python interpreter name.""" 

42 interpreter_version: str 

43 """Python interpreter version.""" 

44 interpreter_path: str 

45 """Path to Python executable.""" 

46 platform: str 

47 """Operating System.""" 

48 packages: list[_Package] 

49 """Installed packages.""" 

50 variables: list[_Variable] 

51 """Environment variables.""" 

52 

53 

54def _interpreter_name_version() -> tuple[str, str]: 

55 if hasattr(sys, "implementation"): 55 ↛ 62line 55 didn't jump to line 62 because the condition on line 55 was always true

56 impl = sys.implementation.version 

57 version = f"{impl.major}.{impl.minor}.{impl.micro}" 

58 kind = impl.releaselevel 

59 if kind != "final": 

60 version += kind[0] + str(impl.serial) 

61 return sys.implementation.name, version 

62 return "", "0.0.0" 

63 

64 

65def _get_version(dist: str = "griffe") -> str: 

66 """Get version of the given distribution. 

67 

68 Parameters: 

69 dist: A distribution name. 

70 

71 Returns: 

72 A version number. 

73 """ 

74 try: 

75 return metadata.version(dist) 

76 except metadata.PackageNotFoundError: 

77 return "0.0.0" 

78 

79 

80def _get_debug_info() -> _Environment: 

81 """Get debug/environment information. 

82 

83 Returns: 

84 Environment information. 

85 """ 

86 py_name, py_version = _interpreter_name_version() 

87 packages = ["griffe"] 

88 variables = ["PYTHONPATH", *[var for var in os.environ if var.startswith("GRIFFE")]] 

89 return _Environment( 

90 interpreter_name=py_name, 

91 interpreter_version=py_version, 

92 interpreter_path=sys.executable, 

93 platform=platform.platform(), 

94 variables=[_Variable(var, val) for var in variables if (val := os.getenv(var))], 

95 packages=[_Package(pkg, _get_version(pkg)) for pkg in packages], 

96 ) 

97 

98 

99def _print_debug_info() -> None: 

100 """Print debug/environment information.""" 

101 info = _get_debug_info() 

102 print(f"- __System__: {info.platform}") 

103 print(f"- __Python__: {info.interpreter_name} {info.interpreter_version} ({info.interpreter_path})") 

104 print("- __Environment variables__:") 

105 for var in info.variables: 

106 print(f" - `{var.name}`: `{var.value}`") 

107 print("- __Installed packages__:") 

108 for pkg in info.packages: 

109 print(f" - `{pkg.name}` v{pkg.version}")