Merge pull request #1772 from freqtrade/fix/staticmethod_import

Gracefully handle pickle-errors when @staticmethod is used
This commit is contained in:
Misagh 2019-04-17 17:24:56 +02:00 committed by GitHub
commit f5ef8f5bc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 6 deletions

View File

@ -157,12 +157,15 @@ class StrategyResolver(IResolver):
getfullargspec(strategy.populate_indicators).args)
strategy._buy_fun_len = len(getfullargspec(strategy.populate_buy_trend).args)
strategy._sell_fun_len = len(getfullargspec(strategy.populate_sell_trend).args)
return import_strategy(strategy, config=config)
try:
return import_strategy(strategy, config=config)
except TypeError as e:
logger.warning(
f"Impossible to load strategy '{strategy}' from {_path}. Error: {e}")
except FileNotFoundError:
logger.warning('Path "%s" does not exist', _path.relative_to(Path.cwd()))
raise ImportError(
"Impossible to load Strategy '{}'. This class does not exist"
" or contains Python code errors".format(strategy_name)
f"Impossible to load Strategy '{strategy_name}'. This class does not exist"
" or contains Python code errors"
)

View File

@ -1,17 +1,19 @@
# pragma pylint: disable=missing-docstring, protected-access, C0103
import logging
import warnings
from base64 import urlsafe_b64encode
from os import path
from pathlib import Path
import warnings
from unittest.mock import Mock
import pytest
from pandas import DataFrame
from freqtrade.resolvers import StrategyResolver
from freqtrade.strategy import import_strategy
from freqtrade.strategy.default_strategy import DefaultStrategy
from freqtrade.strategy.interface import IStrategy
from freqtrade.resolvers import StrategyResolver
from freqtrade.tests.conftest import log_has_re
def test_import_strategy(caplog):
@ -94,6 +96,16 @@ def test_load_not_found_strategy():
strategy._load_strategy(strategy_name='NotFoundStrategy', config={})
def test_load_staticmethod_importerror(mocker, caplog):
mocker.patch("freqtrade.resolvers.strategy_resolver.import_strategy", Mock(
side_effect=TypeError("can't pickle staticmethod objects")))
with pytest.raises(ImportError,
match=r"Impossible to load Strategy 'DefaultStrategy'."
r" This class does not exist or contains Python code errors"):
StrategyResolver()
assert log_has_re(r".*Error: can't pickle staticmethod objects", caplog.record_tuples)
def test_strategy(result):
config = {'strategy': 'DefaultStrategy'}