Repository: freqtrade/freqtrade

Issue:
Gemini exchange error when downloading data
## Step 1: Have you search for this issue before posting it?

yes

## Step 2: Describe your environment

  * Operating system: ubuntu 
  * Python Version: 3.7
  * CCXT version: latest
  * Branch: Develop
  * Last Commit ID: freqtrade develop-9987e64e
  
## Step 3: Describe the problem:

Trying to download data to proceed to backtest, then get an str object has no attribute get

### Steps to reproduce:

  1. Set exchange to gemini
  2. Set base pair to USD
  3. Set BTC/USD, LTC/USD, BCH/USD and ETH/usd pairs
  
### Observed Results:

  * What happened?
Get a str object has no atribute get
  * What did you expect to happen?
Download the data as usual
### Relevant code exceptions or logs:

  ```
2019-12-27 13:07:53,034 - freqtrade.loggers - INFO - Verbosity set to 0
2019-12-27 13:07:53,035 - freqtrade.configuration.configuration - WARNING - `forcebuy` RPC message enabled.
2019-12-27 13:07:53,035 - freqtrade.configuration.configuration - INFO - Using user-data directory: /home/dante/freqtrade/user_data ...
2019-12-27 13:07:53,035 - freqtrade.configuration.configuration - INFO - Using data directory: /home/dante/freqtrade/user_data/data/gemini ...
2019-12-27 13:07:53,035 - freqtrade.configuration.configuration - INFO - timeframes --timeframes: ['1h', '4h', '12h']
2019-12-27 13:07:53,035 - freqtrade.configuration.configuration - INFO - Detected --days: 1200
2019-12-27 13:07:53,035 - freqtrade.configuration.check_exchange - INFO - Checking exchange...
2019-12-27 13:07:53,035 - freqtrade.configuration.check_exchange - WARNING - Exchange "gemini" is known to the the ccxt library, available for the bot, but not officially supported by the Freqtrade development team. It may work flawlessly (please report back) or have serious issues. Use it at your own discretion.
2019-12-27 13:07:53,035 - freqtrade.configuration.configuration - INFO - Using pairlist from configuration.
2019-12-27 13:07:53,035 - freqtrade.configuration.deprecated_settings - WARNING - DEPRECATED: The `experimental.use_sell_signal` setting is deprecated and will be removed in the next versions of Freqtrade. Please use the `ask_strategy.use_sell_signal` setting in your configuration instead.
2019-12-27 13:07:53,035 - freqtrade.configuration.deprecated_settings - WARNING - DEPRECATED: The `experimental.sell_profit_only` setting is deprecated and will be removed in the next versions of Freqtrade. Please use the `ask_strategy.sell_profit_only` setting in your configuration instead.
2019-12-27 13:07:53,035 - freqtrade.configuration.deprecated_settings - WARNING - DEPRECATED: The `experimental.ignore_roi_if_buy_signal` setting is deprecated and will be removed in the next versions of Freqtrade. Please use the `ask_strategy.ignore_roi_if_buy_signal` setting in your configuration instead.
2019-12-27 13:07:53,035 - freqtrade.configuration.deprecated_settings - WARNING - DEPRECATED: Pairlists must be defined explicitly in the future.Defaulting to StaticPairList for now.
2019-12-27 13:07:53,037 - freqtrade.utils - INFO - About to download pairs: ['BTC/USD', 'LTC/USD', 'BCH/USD', 'ETH/USD'], intervals: ['1h', '4h', '12h'] to /home/dante/freqtrade/user_data/data/gemini
2019-12-27 13:07:53,037 - freqtrade.resolvers.exchange_resolver - INFO - No Gemini specific subclass found. Using the generic class instead.
2019-12-27 13:07:53,038 - freqtrade.exchange.exchange - INFO - Instance is running with dry_run enabled
2019-12-27 13:07:53,038 - freqtrade.exchange.exchange - INFO - Applying additional ccxt config: {'enableRateLimit': True}
2019-12-27 13:07:53,039 - freqtrade.exchange.exchange - INFO - Applying additional ccxt config: {'enableRateLimit': True, 'rateLimit': 1000}
2019-12-27 13:07:53,041 - freqtrade.exchange.exchange - INFO - Using Exchange "Gemini"
2019-12-27 13:07:53,928 - freqtrade - ERROR - Fatal exception!
Traceback (most recent call last):
  File "/home/dante/freqtrade/freqtrade/main.py", line 36, in main
    return_code = args['func'](args)
  File "/home/dante/freqtrade/freqtrade/utils.py", line 201, in start_download_data
    exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config)
  File "/home/dante/freqtrade/freqtrade/resolvers/exchange_resolver.py", line 36, in load_exchange
    exchange = Exchange(config, validate=validate)
  File "/home/dante/freqtrade/freqtrade/exchange/exchange.py", line 119, in __init__
    self.validate_pairs(config['exchange']['pair_whitelist'])
  File "/home/dante/freqtrade/freqtrade/exchange/exchange.py", line 281, in validate_pairs
    elif self.markets[pair].get('info', {}).get('IsRestricted', False):
AttributeError: 'str' object has no attribute 'get'

  ```



Discussion:

Resolving patch:
diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py
--- a/freqtrade/exchange/exchange.py
+++ b/freqtrade/exchange/exchange.py
@@ -278,7 +278,15 @@ def validate_pairs(self, pairs: List[str]) -> None:
                 raise OperationalException(
                     f'Pair {pair} is not available on {self.name}. '
                     f'Please remove {pair} from your whitelist.')
-            elif self.markets[pair].get('info', {}).get('IsRestricted', False):
+
+                # From ccxt Documentation:
+                # markets.info: An associative array of non-common market properties,
+                # including fees, rates, limits and other general market information.
+                # The internal info array is different for each particular market,
+                # its contents depend on the exchange.
+                # It can also be a string or similar ... so we need to verify that first.
+            elif (isinstance(self.markets[pair].get('info', None), dict)
+                  and self.markets[pair].get('info', {}).get('IsRestricted', False)):
                 # Warn users about restricted pairs in whitelist.
                 # We cannot determine reliably if Users are affected.
                 logger.warning(f"Pair {pair} is restricted for some users on this exchange."


Test patch:
diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py
--- a/tests/exchange/test_exchange.py
+++ b/tests/exchange/test_exchange.py
@@ -363,8 +363,9 @@ def test_validate_pairs_exception(default_conf, mocker, caplog):
 def test_validate_pairs_restricted(default_conf, mocker, caplog):
     api_mock = MagicMock()
     type(api_mock).markets = PropertyMock(return_value={
-        'ETH/BTC': {}, 'LTC/BTC': {}, 'NEO/BTC': {},
-        'XRP/BTC': {'info': {'IsRestricted': True}}
+        'ETH/BTC': {}, 'LTC/BTC': {},
+        'XRP/BTC': {'info': {'IsRestricted': True}},
+        'NEO/BTC': {'info': 'TestString'},  # info can also be a string ...
     })
     mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
     mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock())