修复了大量存在的问题,增加了假鸭子类型等等机制
This commit is contained in:
@@ -2,11 +2,13 @@
|
||||
TransPyC 彩色日志系统
|
||||
支持终端颜色输出和日志文件转储
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import os
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
from typing import Any, Callable, Optional
|
||||
from lib.constants.config import mode as _ConfigMode
|
||||
|
||||
# ANSI 颜色代码
|
||||
class Colors:
|
||||
@@ -45,7 +47,7 @@ class Colors:
|
||||
GRAY = '\033[90m'
|
||||
|
||||
# 检查是否支持颜色
|
||||
def supports_color():
|
||||
def supports_color() -> bool:
|
||||
if not hasattr(sys.stdout, 'isatty'):
|
||||
return False
|
||||
if not sys.stdout.isatty():
|
||||
@@ -109,28 +111,28 @@ class Logger:
|
||||
self.file_handler.write(f"[{timestamp}] {level} {clean_msg}\n")
|
||||
self.file_handler.flush()
|
||||
|
||||
def set_phase(self, phase: str, total: int = 0):
|
||||
def set_phase(self, phase: str, total: int = 0) -> None:
|
||||
self.current_phase = phase
|
||||
self.total_items = total
|
||||
self.current_item = 0
|
||||
self.progress(phase, 0, total)
|
||||
|
||||
def progress(self, message: str = "", current: int = 0, total: int = 0):
|
||||
def progress(self, message: str = "", current: int = 0, total: int = 0) -> None:
|
||||
if total > 0:
|
||||
self.total_items = total
|
||||
if current > 0:
|
||||
self.current_item = current
|
||||
|
||||
if self.total_items > 0:
|
||||
percent = (self.current_item / self.total_items) * 100
|
||||
bar_length = 30
|
||||
filled = int(bar_length * self.current_item / self.total_items)
|
||||
bar = '█' * filled + '░' * (bar_length - filled)
|
||||
status = f"[{self._colorize(bar, Colors.BLUE)}] {self.current_item}/{self.total_items} ({percent:.1f}%)"
|
||||
percent: float = (self.current_item / self.total_items) * 100
|
||||
bar_length: int = 30
|
||||
filled: int = int(bar_length * self.current_item / self.total_items)
|
||||
bar: str = '█' * filled + '░' * (bar_length - filled)
|
||||
status: str = f"[{self._colorize(bar, Colors.BLUE)}] {self.current_item}/{self.total_items} ({percent:.1f}%)"
|
||||
else:
|
||||
status = ""
|
||||
|
||||
msg = f"{self._colorize('▶', Colors.BRIGHT_CYAN)} {self.current_phase}"
|
||||
msg: str = f"{self._colorize('▶', Colors.BRIGHT_CYAN)} {self.current_phase}"
|
||||
if status:
|
||||
msg += f" {status}"
|
||||
if message:
|
||||
@@ -140,67 +142,67 @@ class Logger:
|
||||
sys.stdout.write('\r' + msg)
|
||||
sys.stdout.flush()
|
||||
|
||||
def debug(self, message: str, category: str = ""):
|
||||
def debug(self, message: str, category: str = "") -> None:
|
||||
if self.level > LogLevel.DEBUG:
|
||||
return
|
||||
|
||||
prefix = self._colorize("DEBUG", Colors.GRAY)
|
||||
prefix: str = self._colorize("DEBUG", Colors.GRAY)
|
||||
if category:
|
||||
prefix += f"[{self._colorize(category, Colors.CYAN)}]"
|
||||
|
||||
msg = f"{self._colorize('├', Colors.GRAY)} {prefix}: {message}"
|
||||
msg: str = f"{self._colorize('├', Colors.GRAY)} {prefix}: {message}"
|
||||
self._write(msg, "DEBUG")
|
||||
|
||||
def info(self, message: str, category: str = ""):
|
||||
prefix = self._colorize("INFO", Colors.GREEN)
|
||||
def info(self, message: str, category: str = "") -> None:
|
||||
prefix: str = self._colorize("INFO", Colors.GREEN)
|
||||
if category:
|
||||
prefix += f"[{self._colorize(category, Colors.CYAN)}]"
|
||||
|
||||
msg = f"{self._colorize('├', Colors.GREEN)} {prefix}: {message}"
|
||||
msg: str = f"{self._colorize('├', Colors.GREEN)} {prefix}: {message}"
|
||||
self._write(msg, "INFO")
|
||||
|
||||
def warning(self, message: str, category: str = ""):
|
||||
prefix = self._colorize("WARN", Colors.BRIGHT_YELLOW)
|
||||
def warning(self, message: str, category: str = "", exc_info: Exception | None = None) -> None:
|
||||
prefix: str = self._colorize("WARN", Colors.BRIGHT_YELLOW)
|
||||
if category:
|
||||
prefix += f"[{self._colorize(category, Colors.CYAN)}]"
|
||||
|
||||
msg = f"{self._colorize('├', Colors.YELLOW)} {prefix}: {message}"
|
||||
|
||||
msg: str = f"{self._colorize('├', Colors.YELLOW)} {prefix}: {message}"
|
||||
self._write(msg, "WARNING")
|
||||
|
||||
def error(self, message: str, category: str = "", exception: Optional[Exception] = None):
|
||||
prefix = self._colorize("ERROR", Colors.BRIGHT_RED)
|
||||
def error(self, message: str, category: str = "", exception: Optional[Exception] = None) -> None:
|
||||
prefix: str = self._colorize("ERROR", Colors.BRIGHT_RED)
|
||||
if category:
|
||||
prefix += f"[{self._colorize(category, Colors.CYAN)}]"
|
||||
|
||||
msg = f"{self._colorize('├', Colors.RED)} {prefix}: {message}"
|
||||
msg: str = f"{self._colorize('├', Colors.RED)} {prefix}: {message}"
|
||||
if exception:
|
||||
msg += f"\n{self._colorize('│', Colors.RED)} Exception: {type(exception).__name__}: {exception}"
|
||||
self._write(msg, "ERROR")
|
||||
|
||||
def critical(self, message: str, category: str = ""):
|
||||
prefix = self._colorize("CRITICAL", Colors.BG_RED + Colors.WHITE + Colors.BOLD)
|
||||
def critical(self, message: str, category: str = "") -> None:
|
||||
prefix: str = self._colorize("CRITICAL", Colors.BG_RED + Colors.WHITE + Colors.BOLD)
|
||||
if category:
|
||||
prefix += f"[{self._colorize(category, Colors.CYAN)}]"
|
||||
|
||||
msg = f"{self._colorize('╠', Colors.RED)} {prefix}: {message}"
|
||||
msg: str = f"{self._colorize('╠', Colors.RED)} {prefix}: {message}"
|
||||
self._write(msg, "CRITICAL")
|
||||
|
||||
def success(self, message: str, category: str = ""):
|
||||
prefix = self._colorize("SUCCESS", Colors.BRIGHT_GREEN)
|
||||
def success(self, message: str, category: str = "") -> None:
|
||||
prefix: str = self._colorize("SUCCESS", Colors.BRIGHT_GREEN)
|
||||
if category:
|
||||
prefix += f"[{self._colorize(category, Colors.CYAN)}]"
|
||||
|
||||
msg = f"{self._colorize('├', Colors.GREEN)} {prefix}: {message}"
|
||||
msg: str = f"{self._colorize('├', Colors.GREEN)} {prefix}: {message}"
|
||||
self._write(msg, "SUCCESS")
|
||||
|
||||
def compile_error(self, message: str, file: str = "", line: int = 0, code: str = ""):
|
||||
def compile_error(self, message: str, file: str = "", line: int = 0, code: str = "") -> None:
|
||||
"""编译错误格式化输出"""
|
||||
header = self._colorize("编译错误", Colors.BG_RED + Colors.WHITE + Colors.BOLD)
|
||||
header: str = self._colorize("编译错误", Colors.BG_RED + Colors.WHITE + Colors.BOLD)
|
||||
|
||||
msg = f"\n{self._colorize('╔', Colors.RED)}{header}{self._colorize('╗', Colors.RED)}\n"
|
||||
msg: str = f"\n{self._colorize('╔', Colors.RED)}{header}{self._colorize('╗', Colors.RED)}\n"
|
||||
|
||||
if file and line > 0:
|
||||
location = f"{self._colorize(file, Colors.CYAN)}:{self._colorize(str(line), Colors.YELLOW)}"
|
||||
location: str = f"{self._colorize(file, Colors.CYAN)}:{self._colorize(str(line), Colors.YELLOW)}"
|
||||
msg += f"{self._colorize('║', Colors.RED)} 位置:{location}\n"
|
||||
|
||||
if code:
|
||||
@@ -211,14 +213,14 @@ class Logger:
|
||||
|
||||
self._write(msg, "ERROR")
|
||||
|
||||
def compile_warning(self, message: str, file: str = "", line: int = 0, code: str = ""):
|
||||
def compile_warning(self, message: str, file: str = "", line: int = 0, code: str = "") -> None:
|
||||
"""编译警告格式化输出"""
|
||||
header = self._colorize("警告", Colors.BG_YELLOW + Colors.BLACK)
|
||||
header: str = self._colorize("警告", Colors.BG_YELLOW + Colors.BLACK)
|
||||
|
||||
msg = f"\n{self._colorize('╔', Colors.YELLOW)}{header}{self._colorize('╗', Colors.YELLOW)}\n"
|
||||
msg: str = f"\n{self._colorize('╔', Colors.YELLOW)}{header}{self._colorize('╗', Colors.YELLOW)}\n"
|
||||
|
||||
if file and line > 0:
|
||||
location = f"{self._colorize(file, Colors.CYAN)}:{self._colorize(str(line), Colors.YELLOW)}"
|
||||
location: str = f"{self._colorize(file, Colors.CYAN)}:{self._colorize(str(line), Colors.YELLOW)}"
|
||||
msg += f"{self._colorize('║', Colors.YELLOW)} 位置:{location}\n"
|
||||
|
||||
if code:
|
||||
@@ -229,21 +231,21 @@ class Logger:
|
||||
|
||||
self._write(msg, "WARNING")
|
||||
|
||||
def summary(self, stats: dict):
|
||||
def summary(self, stats: dict[str, int | str]) -> None:
|
||||
"""输出编译摘要"""
|
||||
header = self._colorize("编译摘要", Colors.BG_BLUE + Colors.WHITE + Colors.BOLD)
|
||||
header: str = self._colorize("编译摘要", Colors.BG_BLUE + Colors.WHITE + Colors.BOLD)
|
||||
|
||||
msg = f"\n{self._colorize('╔', Colors.BLUE)}{header}{self._colorize('╗', Colors.BLUE)}\n"
|
||||
msg: str = f"\n{self._colorize('╔', Colors.BLUE)}{header}{self._colorize('╗', Colors.BLUE)}\n"
|
||||
|
||||
for key, value in stats.items():
|
||||
color = Colors.GREEN if value > 0 else Colors.WHITE
|
||||
color: str = Colors.GREEN if value > 0 else Colors.WHITE
|
||||
msg += f"{self._colorize('║', Colors.BLUE)} {key}: {self._colorize(str(value), color)}\n"
|
||||
|
||||
msg += f"{self._colorize('╚', Colors.BLUE)}{self._colorize('═' * 50, Colors.BLUE)}{self._colorize('╝', Colors.BLUE)}"
|
||||
|
||||
self._write(msg, "SUMMARY")
|
||||
|
||||
def close(self):
|
||||
def close(self) -> None:
|
||||
if self.file_handler:
|
||||
self.file_handler.close()
|
||||
self.info(f"日志已保存到:{self.log_file}")
|
||||
@@ -258,46 +260,46 @@ def get_logger(name: str = "TransPyC", log_file: Optional[str] = None,
|
||||
_global_logger = Logger(name, log_file, level, use_colors)
|
||||
return _global_logger
|
||||
|
||||
def set_logger(logger: Logger):
|
||||
def set_logger(logger: Logger) -> None:
|
||||
global _global_logger
|
||||
_global_logger = logger
|
||||
|
||||
# 便捷函数
|
||||
def debug(msg, category=""):
|
||||
def debug(msg: str, category: str = "") -> None:
|
||||
get_logger().debug(msg, category)
|
||||
|
||||
def info(msg, category=""):
|
||||
def info(msg: str, category: str = "") -> None:
|
||||
get_logger().info(msg, category)
|
||||
|
||||
def warning(msg, category=""):
|
||||
def warning(msg: str, category: str = "") -> None:
|
||||
get_logger().warning(msg, category)
|
||||
|
||||
def error(msg, category="", exception=None):
|
||||
def error(msg: str, category: str = "", exception: Exception | None = None) -> None:
|
||||
get_logger().error(msg, category, exception)
|
||||
|
||||
def critical(msg, category=""):
|
||||
def critical(msg: str, category: str = "") -> None:
|
||||
get_logger().critical(msg, category)
|
||||
|
||||
def success(msg, category=""):
|
||||
def success(msg: str, category: str = "") -> None:
|
||||
get_logger().success(msg, category)
|
||||
|
||||
def compile_error(msg, file="", line=0, code=""):
|
||||
def compile_error(msg: str, file: str = "", line: int = 0, code: str = "") -> None:
|
||||
get_logger().compile_error(msg, file, line, code)
|
||||
|
||||
def compile_warning(msg, file="", line=0, code=""):
|
||||
def compile_warning(msg: str, file: str = "", line: int = 0, code: str = "") -> None:
|
||||
get_logger().compile_warning(msg, file, line, code)
|
||||
|
||||
def set_phase(phase, total=0):
|
||||
def set_phase(phase: str, total: int = 0) -> None:
|
||||
get_logger().set_phase(phase, total)
|
||||
|
||||
def progress(message="", current=0, total=0):
|
||||
def progress(message: str = "", current: int = 0, total: int = 0) -> None:
|
||||
get_logger().progress(message, current, total)
|
||||
|
||||
def summary(stats):
|
||||
def summary(stats: dict[str, int | str]) -> None:
|
||||
get_logger().summary(stats)
|
||||
|
||||
|
||||
def safe_call(func, *args, context: str = "", **kwargs):
|
||||
def safe_call(func: Callable[..., Any], *args: Any, context: str = "", **kwargs: Any) -> Any:
|
||||
"""安全调用函数,在异常时根据模式处理。
|
||||
|
||||
- strict 模式:重新抛出异常
|
||||
@@ -314,7 +316,6 @@ def safe_call(func, *args, context: str = "", **kwargs):
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except Exception as e:
|
||||
from lib.constants.config import mode as _ConfigMode
|
||||
msg = f"{context}: {type(e).__name__}: {e}" if context else f"{type(e).__name__}: {e}"
|
||||
if _ConfigMode == "strict":
|
||||
raise
|
||||
|
||||
Reference in New Issue
Block a user