diff --git a/packages/middleware/points_gate.py b/packages/middleware/points_gate.py index 14f324534..54f8b7187 100644 --- a/packages/middleware/points_gate.py +++ b/packages/middleware/points_gate.py @@ -69,7 +69,7 @@ def points_gate( @functools.wraps(func) def sync_wrapper(*args: Any, **kwargs: Any) -> Any: if not _points_gate_enabled(): - return func(*args, **kwargs) + return func(*args, **_filter_kwargs(func, kwargs)) return _execute_with_gate( func, args, kwargs, scene_key, per_unit, unit_field, quantity_field, is_async=False ) @@ -81,6 +81,20 @@ def points_gate( return decorator + +def _filter_kwargs(func: Callable, kwargs: dict) -> dict: + """过滤掉目标函数签名不接受的 kwargs(避免 TypeError)。""" + import inspect + try: + sig = inspect.signature(func) + params = sig.parameters + has_var_keyword = any(p.kind == inspect.Parameter.VAR_KEYWORD for p in params.values()) + if has_var_keyword: + return kwargs + return {k: v for k, v in kwargs.items() if k in params} + except (ValueError, TypeError): + return kwargs + def _extract_kwargs(func: Callable, args: tuple, kwargs: dict) -> dict: """将位置参数映射到函数签名中的参数名,便于统一按 kwargs 提取。""" sig = inspect.signature(func) @@ -134,8 +148,8 @@ def _execute_with_gate( kwargs["_points_deducted"] = 0 kwargs["_is_free_quota"] = True if is_async: - return _run_async(func, args, kwargs) - return func(*args, **kwargs) + return _run_async(func, args, _filter_kwargs(func, kwargs)) + return func(*args, **_filter_kwargs(func, kwargs)) # ── 计算积分消耗 ── if per_unit is not None: @@ -163,8 +177,8 @@ def _execute_with_gate( if total_points == 0: kwargs["_points_deducted"] = 0 if is_async: - return _run_async(func, args, kwargs) - return func(*args, **kwargs) + return _run_async(func, args, _filter_kwargs(func, kwargs)) + return func(*args, **_filter_kwargs(func, kwargs)) # ── 扣减积分 ── from packages.domain.points_service import PointsService @@ -190,8 +204,8 @@ def _execute_with_gate( # ── 执行业务函数,失败则退还积分 ── try: if is_async: - return _run_async(func, args, kwargs) - return func(*args, **kwargs) + return _run_async(func, args, _filter_kwargs(func, kwargs)) + return func(*args, **_filter_kwargs(func, kwargs)) except Exception: svc.refund_points(user.id, total_points, scene_key, db, ref_id=str(job_id)) raise @@ -199,4 +213,4 @@ def _execute_with_gate( def _run_async(func: Callable, args: tuple, kwargs: dict): """在 async wrapper 中 await 原始 async 函数。""" - return func(*args, **kwargs) + return func(*args, **_filter_kwargs(func, kwargs))