Add test for __code__ loading
This commit is contained in:
		| @@ -51,7 +51,8 @@ class IResolver: | |||||||
|         :param object_name: Class name of the object |         :param object_name: Class name of the object | ||||||
|         :param enum_failed: If True, will return None for modules which fail. |         :param enum_failed: If True, will return None for modules which fail. | ||||||
|             Otherwise, failing modules are skipped. |             Otherwise, failing modules are skipped. | ||||||
|         :return: generator containing matching objects |         :return: generator containing tuple of matching objects | ||||||
|  |              Tuple format: [Object, source] | ||||||
|         """ |         """ | ||||||
|  |  | ||||||
|         # Generate spec based on absolute path |         # Generate spec based on absolute path | ||||||
| @@ -67,7 +68,8 @@ class IResolver: | |||||||
|                 return iter([None]) |                 return iter([None]) | ||||||
|  |  | ||||||
|         valid_objects_gen = ( |         valid_objects_gen = ( | ||||||
|             (obj, inspect.getsource(module)) for name, obj in inspect.getmembers( |             (obj, inspect.getsource(module)) for | ||||||
|  |             name, obj in inspect.getmembers( | ||||||
|                 module, inspect.isclass) if ((object_name is None or object_name == name) |                 module, inspect.isclass) if ((object_name is None or object_name == name) | ||||||
|                                              and issubclass(obj, cls.object_type) |                                              and issubclass(obj, cls.object_type) | ||||||
|                                              and obj is not cls.object_type) |                                              and obj is not cls.object_type) | ||||||
| @@ -75,7 +77,7 @@ class IResolver: | |||||||
|         return valid_objects_gen |         return valid_objects_gen | ||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def _search_object(cls, directory: Path, object_name: str |     def _search_object(cls, directory: Path, object_name: str, add_source: bool = False | ||||||
|                        ) -> Union[Tuple[Any, Path], Tuple[None, None]]: |                        ) -> Union[Tuple[Any, Path], Tuple[None, None]]: | ||||||
|         """ |         """ | ||||||
|         Search for the objectname in the given directory |         Search for the objectname in the given directory | ||||||
| @@ -94,12 +96,14 @@ class IResolver: | |||||||
|             obj = next(cls._get_valid_object(module_path, object_name), None) |             obj = next(cls._get_valid_object(module_path, object_name), None) | ||||||
|  |  | ||||||
|             if obj: |             if obj: | ||||||
|                 obj[0].__code__ = obj[1] |                 obj[0].__file__ = str(entry) | ||||||
|  |                 if add_source: | ||||||
|  |                     obj[0].__code__ = obj[1] | ||||||
|                 return (obj[0], module_path) |                 return (obj[0], module_path) | ||||||
|         return (None, None) |         return (None, None) | ||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def _load_object(cls, paths: List[Path], object_name: str, |     def _load_object(cls, paths: List[Path], object_name: str, add_source: bool = False, | ||||||
|                      kwargs: dict = {}) -> Optional[Any]: |                      kwargs: dict = {}) -> Optional[Any]: | ||||||
|         """ |         """ | ||||||
|         Try to load object from path list. |         Try to load object from path list. | ||||||
| @@ -108,7 +112,8 @@ class IResolver: | |||||||
|         for _path in paths: |         for _path in paths: | ||||||
|             try: |             try: | ||||||
|                 (module, module_path) = cls._search_object(directory=_path, |                 (module, module_path) = cls._search_object(directory=_path, | ||||||
|                                                            object_name=object_name) |                                                            object_name=object_name, | ||||||
|  |                                                            add_source=add_source) | ||||||
|                 if module: |                 if module: | ||||||
|                     logger.info( |                     logger.info( | ||||||
|                         f"Using resolved {cls.object_type.__name__.lower()[1:]} {object_name} " |                         f"Using resolved {cls.object_type.__name__.lower()[1:]} {object_name} " | ||||||
|   | |||||||
| @@ -174,7 +174,9 @@ class StrategyResolver(IResolver): | |||||||
|  |  | ||||||
|         strategy = StrategyResolver._load_object(paths=abs_paths, |         strategy = StrategyResolver._load_object(paths=abs_paths, | ||||||
|                                                  object_name=strategy_name, |                                                  object_name=strategy_name, | ||||||
|                                                  kwargs={'config': config}) |                                                  add_source=True, | ||||||
|  |                                                  kwargs={'config': config}, | ||||||
|  |                                                  ) | ||||||
|         if strategy: |         if strategy: | ||||||
|             strategy._populate_fun_len = len(getfullargspec(strategy.populate_indicators).args) |             strategy._populate_fun_len = len(getfullargspec(strategy.populate_indicators).args) | ||||||
|             strategy._buy_fun_len = len(getfullargspec(strategy.populate_buy_trend).args) |             strategy._buy_fun_len = len(getfullargspec(strategy.populate_buy_trend).args) | ||||||
|   | |||||||
| @@ -921,7 +921,6 @@ def test_api_pair_history(botclient, ohlcv_history): | |||||||
|     assert rc.json['data_stop_ts'] == 1515715200000 |     assert rc.json['data_stop_ts'] == 1515715200000 | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def test_api_plot_config(botclient): | def test_api_plot_config(botclient): | ||||||
|     ftbot, client = botclient |     ftbot, client = botclient | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,13 +18,15 @@ def test_search_strategy(): | |||||||
|  |  | ||||||
|     s, _ = StrategyResolver._search_object( |     s, _ = StrategyResolver._search_object( | ||||||
|         directory=default_location, |         directory=default_location, | ||||||
|         object_name='DefaultStrategy' |         object_name='DefaultStrategy', | ||||||
|  |         add_source=True, | ||||||
|     ) |     ) | ||||||
|     assert issubclass(s, IStrategy) |     assert issubclass(s, IStrategy) | ||||||
|  |  | ||||||
|     s, _ = StrategyResolver._search_object( |     s, _ = StrategyResolver._search_object( | ||||||
|         directory=default_location, |         directory=default_location, | ||||||
|         object_name='NotFoundStrategy' |         object_name='NotFoundStrategy', | ||||||
|  |         add_source=True, | ||||||
|     ) |     ) | ||||||
|     assert s is None |     assert s is None | ||||||
|  |  | ||||||
| @@ -53,6 +55,9 @@ def test_load_strategy(default_conf, result): | |||||||
|                          'strategy_path': str(Path(__file__).parents[2] / 'freqtrade/templates') |                          'strategy_path': str(Path(__file__).parents[2] / 'freqtrade/templates') | ||||||
|                          }) |                          }) | ||||||
|     strategy = StrategyResolver.load_strategy(default_conf) |     strategy = StrategyResolver.load_strategy(default_conf) | ||||||
|  |     assert isinstance(strategy.__code__, str) | ||||||
|  |     assert 'class SampleStrategy' in strategy.__code__ | ||||||
|  |     assert isinstance(strategy.__file__, str) | ||||||
|     assert 'rsi' in strategy.advise_indicators(result, {'pair': 'ETH/BTC'}) |     assert 'rsi' in strategy.advise_indicators(result, {'pair': 'ETH/BTC'}) | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user