fix(points): @points_gate decorator filter internal kwargs to avoid TypeError on routes without **kwargs
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 2s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 3s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m58s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 29s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 1m32s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 4m28s
AI Code Review / AI Code Review (pull_request) Successful in 6m46s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 9m6s
CI/CD Pipeline / Validate - Style (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Security (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Has been cancelled
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Build Production API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been cancelled
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Has been cancelled
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been cancelled
CI/CD Pipeline / Build Staging API Image (pull_request) Failing after 17h52m20s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Failing after 17h51m38s
CI/CD Pipeline / Build Staging Web Image (pull_request) Failing after 17h51m38s
CI/CD Pipeline / PR Build Web Image (pull_request) Failing after 17h53m10s
CI/CD Pipeline / Check push changed paths (pull_request) Failing after 17h55m40s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 17h53m39s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 17h53m40s
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 2s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 3s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m58s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 29s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 1m32s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 4m28s
AI Code Review / AI Code Review (pull_request) Successful in 6m46s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 9m6s
CI/CD Pipeline / Validate - Style (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Security (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Has been cancelled
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Build Production API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been cancelled
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Has been cancelled
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been cancelled
CI/CD Pipeline / Build Staging API Image (pull_request) Failing after 17h52m20s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Failing after 17h51m38s
CI/CD Pipeline / Build Staging Web Image (pull_request) Failing after 17h51m38s
CI/CD Pipeline / PR Build Web Image (pull_request) Failing after 17h53m10s
CI/CD Pipeline / Check push changed paths (pull_request) Failing after 17h55m40s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 17h53m39s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 17h53m40s
This commit is contained in:
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user