diff --git a/src/pyflowx/cli/emlmanager.py b/src/pyflowx/cli/emlmanager.py index 0c60cdf..f5d52d4 100644 --- a/src/pyflowx/cli/emlmanager.py +++ b/src/pyflowx/cli/emlmanager.py @@ -240,7 +240,7 @@ def _parse_email_date(date_str: str) -> str: try: dt = parsedate_to_datetime(date_str) return dt.isoformat() - except Exception: + except (ValueError, TypeError, OverflowError): return date_str @@ -277,11 +277,11 @@ def _extract_email_body_part(part: Any) -> str: decoded_text = payload.decode(charset, errors="replace") except (UnicodeDecodeError, LookupError) as decode_error: # 如果指定编码失败,尝试常见编码 - logger.warning(f"字符编码 {charset} 解码失败: {decode_error}") + logger.warning("字符编码 %s 解码失败: %s", charset, decode_error) for fallback_charset in ["utf-8", "gbk", "gb2312", "latin-1"]: try: decoded_text = payload.decode(fallback_charset, errors="replace") - logger.info(f"成功使用备用编码 {fallback_charset} 解码") + logger.info("成功使用备用编码 %s 解码", fallback_charset) break except (UnicodeDecodeError, LookupError): continue @@ -293,15 +293,15 @@ def _extract_email_body_part(part: Any) -> str: # 限制长度并返回 result = decoded_text[:MAX_BODY_LENGTH] if len(decoded_text) > MAX_BODY_LENGTH: - logger.debug(f"正文内容过长,截取前{MAX_BODY_LENGTH}字符") + logger.debug("正文内容过长,截取前%d字符", MAX_BODY_LENGTH) return result except AttributeError as attr_error: - logger.error(f"邮件部分对象属性错误: {attr_error}") + logger.error("邮件部分对象属性错误: %s", attr_error) return "" except Exception as unexpected_error: - logger.error(f"提取邮件正文时发生未知错误: {unexpected_error}") + logger.error("提取邮件正文时发生未知错误: %s", unexpected_error) return "" diff --git a/src/pyflowx/conditions.py b/src/pyflowx/conditions.py index e87b706..3715c33 100644 --- a/src/pyflowx/conditions.py +++ b/src/pyflowx/conditions.py @@ -11,6 +11,7 @@ from __future__ import annotations +import logging import os import shutil import subprocess @@ -20,6 +21,8 @@ from typing import Any, Callable from .task import Condition, Context +logger = logging.getLogger(__name__) + __all__ = ["BuiltinConditions", "Condition", "Constants"] @@ -153,7 +156,7 @@ class BuiltinConditions: return False try: return content in p.read_text(encoding="utf-8") - except Exception: + except (OSError, UnicodeDecodeError): return False return _static(_check, f"FILE_CONTENT_EXISTS({path!r},{content!r})") @@ -186,7 +189,8 @@ class BuiltinConditions: return False try: return predicate(ctx[dep_name]) - except Exception: + except Exception as exc: + logger.warning("DEP_MATCHES predicate %r raised: %r", dep_name, exc) return False _cond.__name__ = f"DEP_MATCHES({dep_name!r},{getattr(predicate, '__name__', 'pred')})" diff --git a/src/pyflowx/executors.py b/src/pyflowx/executors.py index 29781c8..083b5e6 100644 --- a/src/pyflowx/executors.py +++ b/src/pyflowx/executors.py @@ -56,7 +56,7 @@ from .report import RunReport from .storage import StateBackend, resolve_backend from .task import TaskEvent, TaskHooks, TaskResult, TaskSpec, TaskStatus -logger = logging.getLogger("pyflowx") +logger = logging.getLogger(__name__) # 观察者回调类型。 EventCallback = Callable[[TaskEvent], None] diff --git a/src/pyflowx/runner.py b/src/pyflowx/runner.py index 3953dd8..67268ea 100644 --- a/src/pyflowx/runner.py +++ b/src/pyflowx/runner.py @@ -15,6 +15,7 @@ import argparse import enum import sys from dataclasses import dataclass, field, replace +from pathlib import Path from typing import Any, Sequence, get_args from .compose import GraphComposer @@ -138,9 +139,7 @@ class CliRunner: # ------------------------------------------------------------------ # def _prog_name(self) -> str: """从 sys.argv[0] 推导程序名.""" - import os - - return os.path.basename(sys.argv[0]) if sys.argv else "pyflowx" + return Path(sys.argv[0]).name if sys.argv else "pyflowx" def create_parser(self) -> argparse.ArgumentParser: """创建参数解析器. diff --git a/src/pyflowx/task.py b/src/pyflowx/task.py index f4de1c5..6705c9b 100644 --- a/src/pyflowx/task.py +++ b/src/pyflowx/task.py @@ -69,7 +69,7 @@ TaskCmd = Union[ Strategy = Union[str, "StrategyKind"] StrategyKind = Any # 占位,避免循环;executors 模块用 Literal 约束 -logger = logging.getLogger("pyflowx") +logger = logging.getLogger(__name__) # 条件判断函数类型:接收依赖上下文(可能为空映射),返回是否应执行。 Condition = Callable[[Context], bool]