From 28b1ecb109bccd426f9eb739aaa558a0cf104c8d Mon Sep 17 00:00:00 2001 From: Gerald Lonlas Date: Sun, 21 Jan 2018 15:32:49 -0800 Subject: [PATCH] Convert CryptoToFiatConverter into a Singleton Result in a speed up of the unittest from 60s to 4s Because it cost time to load Pymarketcap() every time we create a CryptoToFiatConverter, it worth it to change it into a Singleton. --- freqtrade/fiat_convert.py | 19 +++++++++++++------ freqtrade/tests/rpc/test_rpc_telegram.py | 12 +++--------- freqtrade/tests/test_fiat_convert.py | 6 +++--- freqtrade/tests/test_main.py | 8 ++------ 4 files changed, 21 insertions(+), 24 deletions(-) diff --git a/freqtrade/fiat_convert.py b/freqtrade/fiat_convert.py index 0132e531d..91e04fff9 100644 --- a/freqtrade/fiat_convert.py +++ b/freqtrade/fiat_convert.py @@ -48,7 +48,10 @@ class CryptoFiat(): return self._expiration - time.time() <= 0 -class CryptoToFiatConverter(): +class CryptoToFiatConverter(object): + __instance = None + _coinmarketcap = None + # Constants SUPPORTED_FIAT = [ "AUD", "BRL", "CAD", "CHF", "CLP", "CNY", "CZK", "DKK", @@ -57,12 +60,16 @@ class CryptoToFiatConverter(): "RUB", "SEK", "SGD", "THB", "TRY", "TWD", "ZAR", "USD" ] - def __init__(self) -> None: - try: - self._coinmarketcap = Pymarketcap() - except BaseException: - self._coinmarketcap = None + def __new__(cls): + if CryptoToFiatConverter.__instance is None: + CryptoToFiatConverter.__instance = object.__new__(cls) + try: + CryptoToFiatConverter._coinmarketcap = Pymarketcap() + except BaseException: + CryptoToFiatConverter._coinmarketcap = None + return CryptoToFiatConverter.__instance + def __init__(self) -> None: self._pairs = [] def convert_amount(self, crypto_amount: float, crypto_symbol: str, fiat_symbol: str) -> float: diff --git a/freqtrade/tests/rpc/test_rpc_telegram.py b/freqtrade/tests/rpc/test_rpc_telegram.py index 9c99be342..df2624815 100644 --- a/freqtrade/tests/rpc/test_rpc_telegram.py +++ b/freqtrade/tests/rpc/test_rpc_telegram.py @@ -219,9 +219,7 @@ def test_forcesell_handle(default_conf, update, ticker, ticker_sell_up, mocker): mocker.patch.multiple('freqtrade.main.exchange', validate_pairs=MagicMock(), get_ticker=ticker) - mocker.patch.multiple('freqtrade.fiat_convert.Pymarketcap', - ticker=MagicMock(return_value={'price_usd': 15000.0}), - _cache_symbols=MagicMock(return_value={'BTC': 1})) + mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0) init(default_conf, create_engine('sqlite://')) # Create some test data @@ -256,9 +254,7 @@ def test_forcesell_down_handle(default_conf, update, ticker, ticker_sell_down, m mocker.patch.multiple('freqtrade.main.exchange', validate_pairs=MagicMock(), get_ticker=ticker) - mocker.patch.multiple('freqtrade.fiat_convert.Pymarketcap', - ticker=MagicMock(return_value={'price_usd': 15000.0}), - _cache_symbols=MagicMock(return_value={'BTC': 1})) + mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0) init(default_conf, create_engine('sqlite://')) # Create some test data @@ -317,9 +313,7 @@ def test_forcesell_all_handle(default_conf, update, ticker, mocker): mocker.patch.multiple('freqtrade.main.exchange', validate_pairs=MagicMock(), get_ticker=ticker) - mocker.patch.multiple('freqtrade.fiat_convert.Pymarketcap', - ticker=MagicMock(return_value={'price_usd': 15000.0}), - _cache_symbols=MagicMock(return_value={'BTC': 1})) + mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0) init(default_conf, create_engine('sqlite://')) # Create some test data diff --git a/freqtrade/tests/test_fiat_convert.py b/freqtrade/tests/test_fiat_convert.py index ddc1c8e29..2d112f921 100644 --- a/freqtrade/tests/test_fiat_convert.py +++ b/freqtrade/tests/test_fiat_convert.py @@ -116,9 +116,9 @@ def test_fiat_convert_get_price(mocker): assert fiat_convert._pairs[0]._expiration is not expiration -def test_fiat_convert_without_network(mocker): - pymarketcap = MagicMock(side_effect=ImportError('Oh boy, you have no network!')) - mocker.patch('freqtrade.fiat_convert.Pymarketcap', pymarketcap) +def test_fiat_convert_without_network(): + # Because CryptoToFiatConverter is a Singleton we reset the value of _coinmarketcap + CryptoToFiatConverter._coinmarketcap = None fiat_convert = CryptoToFiatConverter() assert fiat_convert._coinmarketcap is None diff --git a/freqtrade/tests/test_main.py b/freqtrade/tests/test_main.py index a61342480..7ff569e8f 100644 --- a/freqtrade/tests/test_main.py +++ b/freqtrade/tests/test_main.py @@ -525,9 +525,7 @@ def test_execute_sell_up(default_conf, ticker, ticker_sell_up, mocker): mocker.patch.multiple('freqtrade.main.exchange', validate_pairs=MagicMock(), get_ticker=ticker) - mocker.patch.multiple('freqtrade.fiat_convert.Pymarketcap', - ticker=MagicMock(return_value={'price_usd': 15000.0}), - _cache_symbols=MagicMock(return_value={'BTC': 1})) + mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0) init(default_conf, create_engine('sqlite://')) # Create some test data @@ -562,9 +560,7 @@ def test_execute_sell_down(default_conf, ticker, ticker_sell_down, mocker): mocker.patch.multiple('freqtrade.main.exchange', validate_pairs=MagicMock(), get_ticker=ticker) - mocker.patch.multiple('freqtrade.fiat_convert.Pymarketcap', - ticker=MagicMock(return_value={'price_usd': 15000.0}), - _cache_symbols=MagicMock(return_value={'BTC': 1})) + mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0) init(default_conf, create_engine('sqlite://')) # Create some test data