Coverage for src/ezplog/types/enums/log_level.py: 100.00%

58 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-10-16 19:04 +0000

1# /////////////////////////////////////////////////////////////// 

2# EZPL - LogLevel enumeration 

3# Project: ezpl 

4# /////////////////////////////////////////////////////////////// 

5 

6""" 

7LogLevel enumeration for Ezpl logging framework. 

8 

9This module defines the logging levels with their associated colors and properties. 

10""" 

11 

12from __future__ import annotations 

13 

14# /////////////////////////////////////////////////////////////// 

15# IMPORTS 

16# /////////////////////////////////////////////////////////////// 

17# Standard library imports 

18from enum import Enum 

19from typing import Any, cast 

20 

21# Local imports 

22from ...core.exceptions import ValidationError 

23 

24# /////////////////////////////////////////////////////////////// 

25# CLASSES 

26# /////////////////////////////////////////////////////////////// 

27 

28 

29class LogLevel(Enum): 

30 """ 

31 LogLevel is an enumeration representing different logging levels with associated names, 

32 numeric levels, and colorimetric configurations. 

33 

34 **Attributes:** 

35 * `label`: Human-readable name of the log level 

36 * `no`: Numeric level for comparison 

37 * `fg`: Foreground color code 

38 * `bg`: Background color code 

39 

40 **Levels:** 

41 * `TRACE`: Fine-grained tracing messages (lowest priority) 

42 * `DEBUG`: Debugging messages (verbose debugging) 

43 * `INFO`: Informational messages 

44 * `SUCCESS`: Success messages 

45 * `WARNING`: Warning messages 

46 * `ERROR`: Error messages 

47 * `CRITICAL`: Critical messages (highest priority) 

48 """ 

49 

50 # Numeric levels match loguru standard levels (stable constants, no runtime lookup) 

51 TRACE = ("TRACE", 5, "e", "K") # cyan / black 

52 DEBUG = ("DEBUG", 10, "e", "K") # cyan / black 

53 INFO = ("INFO", 20, "w", "K") # white / black 

54 SUCCESS = ("SUCCESS", 25, "w", "G") # white / green 

55 WARNING = ("WARNING", 30, "y", "K") # yellow / black 

56 ERROR = ("ERROR", 40, "r", "K") # red / black 

57 CRITICAL = ("CRITICAL", 50, "w", "M") # white / magenta 

58 

59 # /////////////////////////////////////////////////////////////// 

60 # INIT 

61 # /////////////////////////////////////////////////////////////// 

62 

63 label: str 

64 no: int 

65 fg: str 

66 bg: str 

67 

68 def __init__(self, label: str, no: int, fg: str, bg: str) -> None: 

69 """ 

70 Initialize a LogLevel instance. 

71 

72 Args: 

73 label: Human-readable name of the log level 

74 no: Numeric level for comparison 

75 fg: Foreground color code 

76 bg: Background color code 

77 """ 

78 self.label = label 

79 self.no = no 

80 self.fg = fg 

81 self.bg = bg 

82 

83 # /////////////////////////////////////////////////////////////// 

84 # CLASS METHODS 

85 # /////////////////////////////////////////////////////////////// 

86 

87 @classmethod 

88 def get_attribute(cls, level: str, attribute: str) -> Any: 

89 """ 

90 Returns the specified attribute (label, no, fg, bg) for a given logging level. 

91 

92 Args: 

93 level: The logging level name 

94 attribute: The attribute to retrieve ('label', 'no', 'fg', 'bg') 

95 

96 Returns: 

97 The requested attribute value 

98 

99 Raises: 

100 ValueError: If the level or attribute is not found 

101 """ 

102 try: 

103 lvl = cls[level.upper()] 

104 return getattr(lvl, attribute) 

105 except KeyError as e: 

106 raise ValidationError(f"Unknown level '{level}'", "level", level) from e 

107 except AttributeError as e: 

108 raise ValidationError( 

109 f"Invalid attribute '{attribute}'", "attribute", attribute 

110 ) from e 

111 

112 @classmethod 

113 def get_label(cls, level: str) -> str: 

114 """ 

115 Get the label for a given log level. 

116 

117 Args: 

118 level: The logging level name 

119 

120 Returns: 

121 The label for the log level 

122 """ 

123 return cast(str, cls.get_attribute(level, "label")) 

124 

125 @classmethod 

126 def get_no(cls, level: str) -> int: 

127 """ 

128 Get the numeric level for a given log level. 

129 

130 Args: 

131 level: The logging level name 

132 

133 Returns: 

134 The numeric level 

135 """ 

136 return cast(int, cls.get_attribute(level, "no")) 

137 

138 @classmethod 

139 def get_fgcolor(cls, level: str) -> str: 

140 """ 

141 Get the foreground color for a given log level. 

142 

143 Args: 

144 level: The logging level name 

145 

146 Returns: 

147 The foreground color code 

148 """ 

149 return cast(str, cls.get_attribute(level, "fg")) 

150 

151 @classmethod 

152 def get_bgcolor(cls, level: str) -> str: 

153 """ 

154 Get the background color for a given log level. 

155 

156 Args: 

157 level: The logging level name 

158 

159 Returns: 

160 The background color code 

161 """ 

162 return cast(str, cls.get_attribute(level, "bg")) 

163 

164 @classmethod 

165 def is_valid_level(cls, level: str) -> bool: 

166 """ 

167 Check if a given level is valid. 

168 

169 Args: 

170 level: The logging level name to check 

171 

172 Returns: 

173 True if the level is valid, False otherwise 

174 """ 

175 try: 

176 cls[level.upper()] 

177 return True 

178 except KeyError: 

179 return False 

180 

181 @classmethod 

182 def get_all_levels(cls) -> list[str]: 

183 """ 

184 Get all available log levels. 

185 

186 Returns: 

187 List of all available log level names 

188 """ 

189 return [level.name for level in cls] 

190 

191 # /////////////////////////////////////////////////////////////// 

192 # REPRESENTATION METHODS 

193 # /////////////////////////////////////////////////////////////// 

194 

195 def __str__(self) -> str: 

196 """String representation of the log level.""" 

197 return f"LogLevel.{self.name}({self.label})" 

198 

199 def __repr__(self) -> str: 

200 """Detailed string representation of the log level.""" 

201 return f"LogLevel.{self.name}(label='{self.label}', no={self.no}, fg='{self.fg}', bg='{self.bg}')" 

202 

203 def get_rich_style(self) -> str: 

204 """ 

205 Get the Rich style string for this log level. 

206 

207 Returns: 

208 Rich style string (e.g., "bold red", "cyan", etc.) 

209 """ 

210 styles = { 

211 "DEBUG": "cyan", 

212 "INFO": "blue", 

213 "SUCCESS": "bold green", 

214 "WARNING": "bold yellow", 

215 "ERROR": "bold red", 

216 "CRITICAL": "bold magenta on red", 

217 } 

218 return styles.get(self.name, "") 

219 

220 

221# /////////////////////////////////////////////////////////////// 

222# PUBLIC API 

223# /////////////////////////////////////////////////////////////// 

224 

225__all__ = [ 

226 "LogLevel", 

227]