From b71c66917ce5fc71b19118f20555402d9f8260ab Mon Sep 17 00:00:00 2001 From: AdrianoDev Date: Thu, 30 Apr 2026 19:02:55 +0200 Subject: [PATCH] chore(V2): cleanup quality gate - ruff: contextlib.suppress al posto di try/except/pass (client_registry, test_env_routing) - rimozione services/ legacy (residuo da git rm) - fix integration test fixture: rimosso sys.modules.pop che inquinava module references nei test successivi (test_audit, test_client_init_default_http) 254 test passano. Ruff: clean. Mypy: 68 warning preesistenti dal codice V1 migrato (strict=false). Co-Authored-By: Claude Opus 4.7 (1M context) --- src/cerbero_mcp/__main__.py | 7 ++++++- src/cerbero_mcp/client_registry.py | 5 ++--- src/cerbero_mcp/exchanges/bybit/client.py | 3 ++- src/cerbero_mcp/exchanges/macro/fetchers.py | 9 +++++++-- tests/integration/test_env_routing.py | 17 ++++------------- tests/unit/common/test_errors.py | 2 +- tests/unit/common/test_mcp_bridge.py | 2 +- .../unit/exchanges/alpaca/test_leverage_cap.py | 2 +- tests/unit/exchanges/bybit/test_leverage_cap.py | 2 +- .../unit/exchanges/deribit/test_leverage_cap.py | 2 +- .../exchanges/hyperliquid/test_leverage_cap.py | 2 +- tests/unit/test_auth.py | 2 +- tests/unit/test_exchanges_builder.py | 14 +++++++------- 13 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/cerbero_mcp/__main__.py b/src/cerbero_mcp/__main__.py index e8dd7c0..52797e4 100644 --- a/src/cerbero_mcp/__main__.py +++ b/src/cerbero_mcp/__main__.py @@ -18,7 +18,12 @@ from cerbero_mcp.client_registry import ClientRegistry from cerbero_mcp.common.logging import configure_root_logging from cerbero_mcp.exchanges import build_client from cerbero_mcp.routers import ( - alpaca, bybit, deribit, hyperliquid, macro, sentiment, + alpaca, + bybit, + deribit, + hyperliquid, + macro, + sentiment, ) from cerbero_mcp.server import build_app from cerbero_mcp.settings import Settings diff --git a/src/cerbero_mcp/client_registry.py b/src/cerbero_mcp/client_registry.py index 3a845a8..1a2ecee 100644 --- a/src/cerbero_mcp/client_registry.py +++ b/src/cerbero_mcp/client_registry.py @@ -2,6 +2,7 @@ from __future__ import annotations import asyncio +import contextlib from collections import defaultdict from collections.abc import Awaitable, Callable from typing import Any, Literal @@ -34,8 +35,6 @@ class ClientRegistry: close = getattr(client, "aclose", None) if close is None: continue - try: + with contextlib.suppress(Exception): await close() - except Exception: - pass self._clients.clear() diff --git a/src/cerbero_mcp/exchanges/bybit/client.py b/src/cerbero_mcp/exchanges/bybit/client.py index e60f93d..5439b46 100644 --- a/src/cerbero_mcp/exchanges/bybit/client.py +++ b/src/cerbero_mcp/exchanges/bybit/client.py @@ -3,9 +3,10 @@ from __future__ import annotations import asyncio from typing import Any +from pybit.unified_trading import HTTP + from cerbero_mcp.common import indicators as ind from cerbero_mcp.common import microstructure as micro -from pybit.unified_trading import HTTP def _f(v: Any) -> float | None: diff --git a/src/cerbero_mcp/exchanges/macro/fetchers.py b/src/cerbero_mcp/exchanges/macro/fetchers.py index 554b0eb..fcd3f7d 100644 --- a/src/cerbero_mcp/exchanges/macro/fetchers.py +++ b/src/cerbero_mcp/exchanges/macro/fetchers.py @@ -4,9 +4,14 @@ from datetime import UTC, datetime, timedelta from typing import Any import httpx -from cerbero_mcp.common.http import async_client -from cerbero_mcp.exchanges.macro.cot import classify_extreme, compute_percentile, parse_disagg_row, parse_tff_row +from cerbero_mcp.common.http import async_client +from cerbero_mcp.exchanges.macro.cot import ( + classify_extreme, + compute_percentile, + parse_disagg_row, + parse_tff_row, +) from cerbero_mcp.exchanges.macro.cot_contracts import ( ALL_DISAGG_SYMBOLS, ALL_TFF_SYMBOLS, diff --git a/tests/integration/test_env_routing.py b/tests/integration/test_env_routing.py index 1e5dd13..046ea14 100644 --- a/tests/integration/test_env_routing.py +++ b/tests/integration/test_env_routing.py @@ -9,12 +9,12 @@ solo che il costruttore venga chiamato con i parametri corretti. """ from __future__ import annotations +import contextlib import importlib import pytest from fastapi.testclient import TestClient - # ── Fixtures ──────────────────────────────────────────────────────────────── @pytest.fixture @@ -23,13 +23,6 @@ def app(monkeypatch): for k, v in _minimal_env().items(): monkeypatch.setenv(k, v) - # Re-import fresco per evitare Settings cached con env vuoto - import importlib - import sys - for mod_name in list(sys.modules.keys()): - if "cerbero_mcp" in mod_name: - sys.modules.pop(mod_name, None) - from cerbero_mcp.__main__ import _make_app from cerbero_mcp.settings import Settings return _make_app(Settings()) @@ -58,12 +51,10 @@ def _spy_constructor(monkeypatch, module_path: str, cls_name: str, capture: dict def spy_init(self, *args, **kwargs): capture["args"] = args capture["kwargs"] = kwargs - try: + # Se il costruttore fallisce (network, SDK unavailable) non importa: + # la capture è già avvenuta. + with contextlib.suppress(Exception): real_init(self, *args, **kwargs) - except Exception: - # Se il costruttore fallisce (network, SDK unavailable) non importa: - # la capture è già avvenuta. - pass monkeypatch.setattr(real_cls, "__init__", spy_init) diff --git a/tests/unit/common/test_errors.py b/tests/unit/common/test_errors.py index 0991660..dc5aa8d 100644 --- a/tests/unit/common/test_errors.py +++ b/tests/unit/common/test_errors.py @@ -1,6 +1,6 @@ from __future__ import annotations -from cerbero_mcp.common.errors import error_envelope, HTTP_CODE_MAP +from cerbero_mcp.common.errors import HTTP_CODE_MAP, error_envelope def test_envelope_minimal(): diff --git a/tests/unit/common/test_mcp_bridge.py b/tests/unit/common/test_mcp_bridge.py index faaf05e..a2f23bf 100644 --- a/tests/unit/common/test_mcp_bridge.py +++ b/tests/unit/common/test_mcp_bridge.py @@ -1,8 +1,8 @@ from __future__ import annotations +from cerbero_mcp.common.mcp_bridge import _derive_input_schemas, mount_mcp_endpoint from fastapi import FastAPI from fastapi.testclient import TestClient -from cerbero_mcp.common.mcp_bridge import _derive_input_schemas, mount_mcp_endpoint from pydantic import BaseModel VALID_TOKEN = "t" diff --git a/tests/unit/exchanges/alpaca/test_leverage_cap.py b/tests/unit/exchanges/alpaca/test_leverage_cap.py index c073e20..1027ff7 100644 --- a/tests/unit/exchanges/alpaca/test_leverage_cap.py +++ b/tests/unit/exchanges/alpaca/test_leverage_cap.py @@ -1,8 +1,8 @@ from __future__ import annotations import pytest -from fastapi import HTTPException from cerbero_mcp.exchanges.alpaca.leverage_cap import enforce_leverage, get_max_leverage +from fastapi import HTTPException def test_get_max_leverage_returns_creds_value(): diff --git a/tests/unit/exchanges/bybit/test_leverage_cap.py b/tests/unit/exchanges/bybit/test_leverage_cap.py index 2d47e16..d81d71b 100644 --- a/tests/unit/exchanges/bybit/test_leverage_cap.py +++ b/tests/unit/exchanges/bybit/test_leverage_cap.py @@ -1,8 +1,8 @@ from __future__ import annotations import pytest -from fastapi import HTTPException from cerbero_mcp.exchanges.bybit.leverage_cap import enforce_leverage, get_max_leverage +from fastapi import HTTPException def test_get_max_leverage_returns_creds_value(): diff --git a/tests/unit/exchanges/deribit/test_leverage_cap.py b/tests/unit/exchanges/deribit/test_leverage_cap.py index 7f15b23..1ddb499 100644 --- a/tests/unit/exchanges/deribit/test_leverage_cap.py +++ b/tests/unit/exchanges/deribit/test_leverage_cap.py @@ -1,8 +1,8 @@ from __future__ import annotations import pytest -from fastapi import HTTPException from cerbero_mcp.exchanges.deribit.leverage_cap import enforce_leverage, get_max_leverage +from fastapi import HTTPException def test_get_max_leverage_returns_creds_value(): diff --git a/tests/unit/exchanges/hyperliquid/test_leverage_cap.py b/tests/unit/exchanges/hyperliquid/test_leverage_cap.py index c181892..6859063 100644 --- a/tests/unit/exchanges/hyperliquid/test_leverage_cap.py +++ b/tests/unit/exchanges/hyperliquid/test_leverage_cap.py @@ -1,8 +1,8 @@ from __future__ import annotations import pytest -from fastapi import HTTPException from cerbero_mcp.exchanges.hyperliquid.leverage_cap import enforce_leverage, get_max_leverage +from fastapi import HTTPException def test_get_max_leverage_returns_creds_value(): diff --git a/tests/unit/test_auth.py b/tests/unit/test_auth.py index 74c7f54..f26ed69 100644 --- a/tests/unit/test_auth.py +++ b/tests/unit/test_auth.py @@ -1,4 +1,3 @@ -import pytest from fastapi import FastAPI, Request from fastapi.testclient import TestClient @@ -92,6 +91,7 @@ def test_mainnet_token_sets_env_mainnet(): def test_uses_compare_digest(): """Verifica che _check_token usi secrets.compare_digest (timing-safe).""" import inspect + from cerbero_mcp import auth src = inspect.getsource(auth) diff --git a/tests/unit/test_exchanges_builder.py b/tests/unit/test_exchanges_builder.py index db568cc..9a1d19e 100644 --- a/tests/unit/test_exchanges_builder.py +++ b/tests/unit/test_exchanges_builder.py @@ -10,8 +10,8 @@ async def test_build_client_deribit_returns_correct_url(monkeypatch): for k, v in _minimal_env().items(): monkeypatch.setenv(k, v) - from cerbero_mcp.settings import Settings from cerbero_mcp.exchanges import build_client + from cerbero_mcp.settings import Settings s = Settings() c_test = await build_client(s, "deribit", "testnet") @@ -38,8 +38,8 @@ async def test_build_client_bybit_returns_correct_env(monkeypatch): monkeypatch.setattr(bybit_client, "HTTP", _FakeHTTP) - from cerbero_mcp.settings import Settings from cerbero_mcp.exchanges import build_client + from cerbero_mcp.settings import Settings s = Settings() c_test = await build_client(s, "bybit", "testnet") @@ -57,8 +57,8 @@ async def test_build_client_hyperliquid_returns_correct_env(monkeypatch): for k, v in _minimal_env().items(): monkeypatch.setenv(k, v) - from cerbero_mcp.settings import Settings from cerbero_mcp.exchanges import build_client + from cerbero_mcp.settings import Settings s = Settings() c_test = await build_client(s, "hyperliquid", "testnet") @@ -90,8 +90,8 @@ async def test_build_client_alpaca_returns_correct_env(monkeypatch): monkeypatch.setattr(alpaca_client, "CryptoHistoricalDataClient", _FakeSdk) monkeypatch.setattr(alpaca_client, "OptionHistoricalDataClient", _FakeSdk) - from cerbero_mcp.settings import Settings from cerbero_mcp.exchanges import build_client + from cerbero_mcp.settings import Settings s = Settings() c_test = await build_client(s, "alpaca", "testnet") @@ -109,9 +109,9 @@ async def test_build_client_macro_no_env_distinction(monkeypatch): for k, v in _minimal_env().items(): monkeypatch.setenv(k, v) - from cerbero_mcp.settings import Settings from cerbero_mcp.exchanges import build_client from cerbero_mcp.exchanges.macro.client import MacroClient + from cerbero_mcp.settings import Settings s = Settings() c_test = await build_client(s, "macro", "testnet") @@ -132,9 +132,9 @@ async def test_build_client_sentiment_no_env_distinction(monkeypatch): for k, v in _minimal_env().items(): monkeypatch.setenv(k, v) - from cerbero_mcp.settings import Settings from cerbero_mcp.exchanges import build_client from cerbero_mcp.exchanges.sentiment.client import SentimentClient + from cerbero_mcp.settings import Settings s = Settings() c_test = await build_client(s, "sentiment", "testnet") @@ -155,8 +155,8 @@ async def test_build_client_unknown_exchange_raises(monkeypatch): for k, v in _minimal_env().items(): monkeypatch.setenv(k, v) - from cerbero_mcp.settings import Settings from cerbero_mcp.exchanges import build_client + from cerbero_mcp.settings import Settings s = Settings() with pytest.raises(ValueError):