From 07062055f61d8dcc91138e039bdd8dbc8c281b99 Mon Sep 17 00:00:00 2001 From: matstedt Date: Fri, 23 Jan 2026 17:07:51 +0100 Subject: [PATCH] fix(exchange): drop unused get_ft_has override plumbing --- freqtrade/exchange/check_exchange.py | 18 +------ freqtrade/exchange/exchange_utils.py | 10 +--- tests/exchange/test_exchange_utils.py | 70 +-------------------------- 3 files changed, 3 insertions(+), 95 deletions(-) diff --git a/freqtrade/exchange/check_exchange.py b/freqtrade/exchange/check_exchange.py index 3795a9f4d..583868744 100644 --- a/freqtrade/exchange/check_exchange.py +++ b/freqtrade/exchange/check_exchange.py @@ -1,30 +1,15 @@ import logging -from typing import Any from freqtrade.constants import Config from freqtrade.enums import RunMode from freqtrade.exceptions import OperationalException from freqtrade.exchange import available_exchanges, is_exchange_known_ccxt, validate_exchange from freqtrade.exchange.common import MAP_EXCHANGE_CHILDCLASS, SUPPORTED_EXCHANGES -from freqtrade.resolvers.exchange_resolver import ExchangeResolver logger = logging.getLogger(__name__) -def _get_ft_has_overrides(exchange_name: str) -> dict[str, Any] | None: - subclassed = {e["name"].lower(): e for e in ExchangeResolver.search_all_objects({}, False)} - mapped = MAP_EXCHANGE_CHILDCLASS.get(exchange_name.lower(), exchange_name.lower()).lower() - resolved = subclassed.get(mapped) - if not resolved: - return None - - get_ft_has = getattr(resolved["class"], "get_ft_has", None) - if callable(get_ft_has): - return get_ft_has() or None - return None - - def check_exchange(config: Config, check_for_bad: bool = True) -> bool: """ Check if the exchange name in the config file is supported by Freqtrade @@ -62,8 +47,7 @@ def check_exchange(config: Config, check_for_bad: bool = True) -> bool: f"{', '.join(available_exchanges())}" ) - ft_has_overrides = _get_ft_has_overrides(exchange) - valid, reason, _, _ = validate_exchange(exchange, ft_has_overrides) + valid, reason, _, _ = validate_exchange(exchange) if not valid: if check_for_bad: raise OperationalException( diff --git a/freqtrade/exchange/exchange_utils.py b/freqtrade/exchange/exchange_utils.py index ef4c5387b..1840e0def 100644 --- a/freqtrade/exchange/exchange_utils.py +++ b/freqtrade/exchange/exchange_utils.py @@ -70,7 +70,6 @@ def _exchange_has_helper(ex_has: dict[str, Any], required: dict[str, list[str]]) def validate_exchange( exchange: str, - ft_has_overrides: dict[str, Any] | None = None, ) -> tuple[bool, str, str, ccxt.Exchange | None]: """ returns: can_use, reason, exchange_object @@ -85,8 +84,6 @@ def validate_exchange( return False, "", "", None ex_has = dict(ex_mod.has or {}) - if ft_has_overrides: - ex_has.update(ft_has_overrides) result = True reasons = [] @@ -120,13 +117,8 @@ def _build_exchange_list_entry( mapped_exchange_name = MAP_EXCHANGE_CHILDCLASS.get(exchange_name, exchange_name).lower() resolved = exchangeClasses.get(mapped_exchange_name) - ft_has_overrides = None - if resolved: - get_ft_has = getattr(resolved["class"], "get_ft_has", None) - if callable(get_ft_has): - ft_has_overrides = get_ft_has() or None - valid, comment, comment_fut, ex_mod = validate_exchange(exchange_name, ft_has_overrides) + valid, comment, comment_fut, ex_mod = validate_exchange(exchange_name) is_alias = getattr(ex_mod, "alias", False) result: ValidExchangesType = { diff --git a/tests/exchange/test_exchange_utils.py b/tests/exchange/test_exchange_utils.py index 685e5923d..67cfdd0a5 100644 --- a/tests/exchange/test_exchange_utils.py +++ b/tests/exchange/test_exchange_utils.py @@ -3,7 +3,6 @@ from datetime import UTC, datetime, timedelta from math import isnan, nan from unittest.mock import MagicMock -import ccxt import pytest from ccxt import ( DECIMAL_PLACES, @@ -15,7 +14,6 @@ from ccxt import ( TRUNCATE, ) -import freqtrade.exchange.exchange_utils as exchange_utils_mod from freqtrade.enums import RunMode from freqtrade.exceptions import OperationalException from freqtrade.exchange import ( @@ -30,13 +28,10 @@ from freqtrade.exchange import ( timeframe_to_resample_freq, timeframe_to_seconds, ) -from freqtrade.exchange.check_exchange import _get_ft_has_overrides, check_exchange +from freqtrade.exchange.check_exchange import check_exchange from freqtrade.exchange.exchange_utils import ( - _build_exchange_list_entry, _exchange_has_helper, - validate_exchange, ) -from freqtrade.resolvers.exchange_resolver import ExchangeResolver from tests.conftest import log_has_re @@ -433,66 +428,3 @@ def test_exchange__exchange_has_helper(): } missing = _exchange_has_helper(e_mod.has, required) assert set(missing) == {"fetchOHLCV", "fetchMyTrades", "fetchOrder"} - - -def test_validate_exchange_uses_ft_has_overrides(monkeypatch): - class DummyExchange: - def __init__(self) -> None: - self.has = { - "fetchOrder": False, - "fetchL2OrderBook": False, - "fetchTicker": True, - "cancelOrder": True, - "createOrder": True, - "fetchBalance": True, - "fetchOHLCV": False, - } - - monkeypatch.setattr(ccxt.pro, "dummy", DummyExchange, raising=False) - - valid, _, _, _ = validate_exchange("dummy") - assert not valid - - valid, _, _, _ = validate_exchange("dummy", {"fetchOrder": True, "fetchOHLCV": True}) - assert valid - - -def test_build_exchange_list_entry_uses_ft_has_overrides(monkeypatch): - class DummyClass: - _supported_trading_mode_margin_pairs = [] - - @staticmethod - def get_ft_has(): - return {"fetchOrder": True} - - captured = {} - - class DummyExchange: - name = "Dummy" - alias = False - dex = False - - def fake_validate_exchange(exchange, ft_has_overrides=None): - captured["ft_has_overrides"] = ft_has_overrides - return True, "", "", DummyExchange() - - monkeypatch.setattr(exchange_utils_mod, "validate_exchange", fake_validate_exchange) - - res = _build_exchange_list_entry("dummy", {"dummy": {"class": DummyClass}}) - assert captured["ft_has_overrides"] == {"fetchOrder": True} - assert res["classname"] == "dummy" - - -def test_get_ft_has_overrides_returns_override(monkeypatch): - class DummyClass: - @staticmethod - def get_ft_has(): - return {"fetchOrder": True} - - monkeypatch.setattr( - ExchangeResolver, - "search_all_objects", - lambda *args, **kwargs: [{"name": "dummy", "class": DummyClass}], - ) - - assert _get_ft_has_overrides("dummy") == {"fetchOrder": True}