We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Falure when using single ISIN as a ticker (fix included)
Multiple tickers with ISINs mixed in do work, but a single ISIN fails. Here is the culprit (multi.py):

>     if len(tickers) == 1:
>        ticker = tickers[0]
>        return shared._DFS[shared._ISINS.get(ticker, ticker)]


The last line should be just

> return shared._DFS[ticker]

as at that point in time both _DFS and tickers refer to Yahoo ID instead of ISIN, and lookup by original ISIN in _DFS is failing. 

Testcase:

>import yfinance as yf
>yf.download("SE0000594111", period="7d", repair=True, progress=False, threads=False, timeout=30)

(corresponding Yahoo ID is '0P00000FYR.ST'.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `yfinance/multi.py`
Content:
```
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 #
4 # yfinance - market data downloader
5 # https://github.com/ranaroussi/yfinance
6 #
7 # Copyright 2017-2019 Ran Aroussi
8 #
9 # Licensed under the Apache License, Version 2.0 (the "License");
10 # you may not use this file except in compliance with the License.
11 # You may obtain a copy of the License at
12 #
13 #     http://www.apache.org/licenses/LICENSE-2.0
14 #
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS,
17 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 # See the License for the specific language governing permissions and
19 # limitations under the License.
20 #
21 
22 from __future__ import print_function
23 
24 import logging
25 import traceback
26 import time as _time
27 import multitasking as _multitasking
28 import pandas as _pd
29 
30 from . import Ticker, utils
31 from . import shared
32 
33 @utils.log_indent_decorator
34 def download(tickers, start=None, end=None, actions=False, threads=True, ignore_tz=None,
35              group_by='column', auto_adjust=False, back_adjust=False, repair=False, keepna=False,
36              progress=True, period="max", show_errors=None, interval="1d", prepost=False,
37              proxy=None, rounding=False, timeout=10, session=None):
38     """Download yahoo tickers
39     :Parameters:
40         tickers : str, list
41             List of tickers to download
42         period : str
43             Valid periods: 1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max
44             Either Use period parameter or use start and end
45         interval : str
46             Valid intervals: 1m,2m,5m,15m,30m,60m,90m,1h,1d,5d,1wk,1mo,3mo
47             Intraday data cannot extend last 60 days
48         start: str
49             Download start date string (YYYY-MM-DD) or _datetime, inclusive.
50             Default is 1900-01-01
51             E.g. for start="2020-01-01", the first data point will be on "2020-01-01"
52         end: str
53             Download end date string (YYYY-MM-DD) or _datetime, exclusive.
54             Default is now
55             E.g. for end="2023-01-01", the last data point will be on "2022-12-31"
56         group_by : str
57             Group by 'ticker' or 'column' (default)
58         prepost : bool
59             Include Pre and Post market data in results?
60             Default is False
61         auto_adjust: bool
62             Adjust all OHLC automatically? Default is False
63         repair: bool
64             Detect currency unit 100x mixups and attempt repair
65             Default is False
66         keepna: bool
67             Keep NaN rows returned by Yahoo?
68             Default is False
69         actions: bool
70             Download dividend + stock splits data. Default is False
71         threads: bool / int
72             How many threads to use for mass downloading. Default is True
73         ignore_tz: bool
74             When combining from different timezones, ignore that part of datetime.
75             Default depends on interval. Intraday = False. Day+ = True.
76         proxy: str
77             Optional. Proxy server URL scheme. Default is None
78         rounding: bool
79             Optional. Round values to 2 decimal places?
80         show_errors: bool
81             Optional. Doesn't print errors if False
82             DEPRECATED, will be removed in future version
83         timeout: None or float
84             If not None stops waiting for a response after given number of
85             seconds. (Can also be a fraction of a second e.g. 0.01)
86         session: None or Session
87             Optional. Pass your own session object to be used for all requests
88     """
89     logger = utils.get_yf_logger()
90 
91     if show_errors is not None:
92         if show_errors:
93             utils.print_once(f"yfinance: download(show_errors={show_errors}) argument is deprecated and will be removed in future version. Do this instead: logging.getLogger('yfinance').setLevel(logging.ERROR)")
94             logger.setLevel(logging.ERROR)
95         else:
96             utils.print_once(f"yfinance: download(show_errors={show_errors}) argument is deprecated and will be removed in future version. Do this instead to suppress error messages: logging.getLogger('yfinance').setLevel(logging.CRITICAL)")
97             logger.setLevel(logging.CRITICAL)
98 
99     if logger.isEnabledFor(logging.DEBUG):
100         if threads:
101             # With DEBUG, each thread generates a lot of log messages.
102             # And with multi-threading, these messages will be interleaved, bad!
103             # So disable multi-threading to make log readable.
104             logger.debug('Disabling multithreading because DEBUG logging enabled')
105             threads = False
106         if progress:
107             # Disable progress bar, interferes with display of log messages
108             progress = False
109 
110     if ignore_tz is None:
111         # Set default value depending on interval
112         if interval[1:] in ['m', 'h']:
113             # Intraday
114             ignore_tz = False
115         else:
116             ignore_tz = True
117 
118     # create ticker list
119     tickers = tickers if isinstance(
120         tickers, (list, set, tuple)) else tickers.replace(',', ' ').split()
121 
122     # accept isin as ticker
123     shared._ISINS = {}
124     _tickers_ = []
125     for ticker in tickers:
126         if utils.is_isin(ticker):
127             isin = ticker
128             ticker = utils.get_ticker_by_isin(ticker, proxy, session=session)
129             shared._ISINS[ticker] = isin
130         _tickers_.append(ticker)
131 
132     tickers = _tickers_
133 
134     tickers = list(set([ticker.upper() for ticker in tickers]))
135 
136     if progress:
137         shared._PROGRESS_BAR = utils.ProgressBar(len(tickers), 'completed')
138 
139     # reset shared._DFS
140     shared._DFS = {}
141     shared._ERRORS = {}
142     shared._TRACEBACKS = {}
143 
144     # download using threads
145     if threads:
146         if threads is True:
147             threads = min([len(tickers), _multitasking.cpu_count() * 2])
148         _multitasking.set_max_threads(threads)
149         for i, ticker in enumerate(tickers):
150             _download_one_threaded(ticker, period=period, interval=interval,
151                                    start=start, end=end, prepost=prepost,
152                                    actions=actions, auto_adjust=auto_adjust,
153                                    back_adjust=back_adjust, repair=repair, keepna=keepna,
154                                    progress=(progress and i > 0), proxy=proxy,
155                                    rounding=rounding, timeout=timeout, session=session)
156         while len(shared._DFS) < len(tickers):
157             _time.sleep(0.01)
158     # download synchronously
159     else:
160         for i, ticker in enumerate(tickers):
161             data = _download_one(ticker, period=period, interval=interval,
162                                  start=start, end=end, prepost=prepost,
163                                  actions=actions, auto_adjust=auto_adjust,
164                                  back_adjust=back_adjust, repair=repair, keepna=keepna,
165                                  proxy=proxy,
166                                  rounding=rounding, timeout=timeout, session=session)
167             if progress:
168                 shared._PROGRESS_BAR.animate()
169     
170     if progress:
171         shared._PROGRESS_BAR.completed()
172 
173     if shared._ERRORS:
174         # Send errors to logging module
175         logger = utils.get_yf_logger()
176         logger.error('\n%.f Failed download%s:' % (
177             len(shared._ERRORS), 's' if len(shared._ERRORS) > 1 else ''))
178 
179         # Log each distinct error once, with list of symbols affected
180         errors = {}
181         for ticker in shared._ERRORS:
182             err = shared._ERRORS[ticker]
183             err = err.replace(f'{ticker}', '%ticker%')
184             if not err in errors:
185                 errors[err] = [ticker]
186             else:
187                 errors[err].append(ticker)
188         for err in errors.keys():
189             logger.error(f'{errors[err]}: ' + err)
190 
191         # Log each distinct traceback once, with list of symbols affected
192         tbs = {}
193         for ticker in shared._TRACEBACKS:
194             tb = shared._TRACEBACKS[ticker]
195             tb = tb.replace(f'{ticker}', '%ticker%')
196             if not tb in tbs:
197                 tbs[tb] = [ticker]
198             else:
199                 tbs[tb].append(ticker)
200         for tb in tbs.keys():
201             logger.debug(f'{tbs[tb]}: ' + tb)
202 
203     if ignore_tz:
204         for tkr in shared._DFS.keys():
205             if (shared._DFS[tkr] is not None) and (shared._DFS[tkr].shape[0] > 0):
206                 shared._DFS[tkr].index = shared._DFS[tkr].index.tz_localize(None)
207 
208     if len(tickers) == 1:
209         ticker = tickers[0]
210         return shared._DFS[shared._ISINS.get(ticker, ticker)]
211 
212     try:
213         data = _pd.concat(shared._DFS.values(), axis=1, sort=True,
214                           keys=shared._DFS.keys())
215     except Exception:
216         _realign_dfs()
217         data = _pd.concat(shared._DFS.values(), axis=1, sort=True,
218                           keys=shared._DFS.keys())
219 
220     # switch names back to isins if applicable
221     data.rename(columns=shared._ISINS, inplace=True)
222 
223     if group_by == 'column':
224         data.columns = data.columns.swaplevel(0, 1)
225         data.sort_index(level=0, axis=1, inplace=True)
226 
227     return data
228 
229 
230 def _realign_dfs():
231     idx_len = 0
232     idx = None
233 
234     for df in shared._DFS.values():
235         if len(df) > idx_len:
236             idx_len = len(df)
237             idx = df.index
238 
239     for key in shared._DFS.keys():
240         try:
241             shared._DFS[key] = _pd.DataFrame(
242                 index=idx, data=shared._DFS[key]).drop_duplicates()
243         except Exception:
244             shared._DFS[key] = _pd.concat([
245                 utils.empty_df(idx), shared._DFS[key].dropna()
246             ], axis=0, sort=True)
247 
248         # remove duplicate index
249         shared._DFS[key] = shared._DFS[key].loc[
250             ~shared._DFS[key].index.duplicated(keep='last')]
251 
252 
253 @_multitasking.task
254 def _download_one_threaded(ticker, start=None, end=None,
255                            auto_adjust=False, back_adjust=False, repair=False,
256                            actions=False, progress=True, period="max",
257                            interval="1d", prepost=False, proxy=None,
258                            keepna=False, rounding=False, timeout=10, session=None):
259     data = _download_one(ticker, start, end, auto_adjust, back_adjust, repair,
260                          actions, period, interval, prepost, proxy, rounding,
261                          keepna, timeout, session)
262     if progress:
263         shared._PROGRESS_BAR.animate()
264 
265 
266 def _download_one(ticker, start=None, end=None,
267                   auto_adjust=False, back_adjust=False, repair=False,
268                   actions=False, period="max", interval="1d",
269                   prepost=False, proxy=None, rounding=False,
270                   keepna=False, timeout=10, session=None):
271     data = None
272     try:
273         data = Ticker(ticker, session=session).history(
274                 period=period, interval=interval,
275                 start=start, end=end, prepost=prepost,
276                 actions=actions, auto_adjust=auto_adjust,
277                 back_adjust=back_adjust, repair=repair, proxy=proxy,
278                 rounding=rounding, keepna=keepna, timeout=timeout,
279                 raise_errors=True
280         )
281     except Exception as e:
282         # glob try/except needed as current thead implementation breaks if exception is raised.
283         shared._DFS[ticker.upper()] = utils.empty_df()
284         shared._ERRORS[ticker.upper()] = repr(e)
285         shared._TRACEBACKS[ticker.upper()] = traceback.format_exc()
286     else:
287         shared._DFS[ticker.upper()] = data
288 
289     return data
290
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/yfinance/multi.py b/yfinance/multi.py
--- a/yfinance/multi.py
+++ b/yfinance/multi.py
@@ -207,7 +207,7 @@
 
     if len(tickers) == 1:
         ticker = tickers[0]
-        return shared._DFS[shared._ISINS.get(ticker, ticker)]
+        return shared._DFS[ticker]
 
     try:
         data = _pd.concat(shared._DFS.values(), axis=1, sort=True,

{"golden_diff": "diff --git a/yfinance/multi.py b/yfinance/multi.py\n--- a/yfinance/multi.py\n+++ b/yfinance/multi.py\n@@ -207,7 +207,7 @@\n \n     if len(tickers) == 1:\n         ticker = tickers[0]\n-        return shared._DFS[shared._ISINS.get(ticker, ticker)]\n+        return shared._DFS[ticker]\n \n     try:\n         data = _pd.concat(shared._DFS.values(), axis=1, sort=True,\n", "issue": "Falure when using single ISIN as a ticker (fix included)\nMultiple tickers with ISINs mixed in do work, but a single ISIN fails. Here is the culprit (multi.py):\r\n\r\n>     if len(tickers) == 1:\r\n>        ticker = tickers[0]\r\n>        return shared._DFS[shared._ISINS.get(ticker, ticker)]\r\n\r\n\r\nThe last line should be just\r\n\r\n> return shared._DFS[ticker]\r\n\r\nas at that point in time both _DFS and tickers refer to Yahoo ID instead of ISIN, and lookup by original ISIN in _DFS is failing. \r\n\r\nTestcase:\r\n\r\n>import yfinance as yf\r\n>yf.download(\"SE0000594111\", period=\"7d\", repair=True, progress=False, threads=False, timeout=30)\r\n\r\n(corresponding Yahoo ID is '0P00000FYR.ST'.\n", "before_files": [{"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n#\n# yfinance - market data downloader\n# https://github.com/ranaroussi/yfinance\n#\n# Copyright 2017-2019 Ran Aroussi\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\nfrom __future__ import print_function\n\nimport logging\nimport traceback\nimport time as _time\nimport multitasking as _multitasking\nimport pandas as _pd\n\nfrom . import Ticker, utils\nfrom . import shared\n\n@utils.log_indent_decorator\ndef download(tickers, start=None, end=None, actions=False, threads=True, ignore_tz=None,\n             group_by='column', auto_adjust=False, back_adjust=False, repair=False, keepna=False,\n             progress=True, period=\"max\", show_errors=None, interval=\"1d\", prepost=False,\n             proxy=None, rounding=False, timeout=10, session=None):\n    \"\"\"Download yahoo tickers\n    :Parameters:\n        tickers : str, list\n            List of tickers to download\n        period : str\n            Valid periods: 1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max\n            Either Use period parameter or use start and end\n        interval : str\n            Valid intervals: 1m,2m,5m,15m,30m,60m,90m,1h,1d,5d,1wk,1mo,3mo\n            Intraday data cannot extend last 60 days\n        start: str\n            Download start date string (YYYY-MM-DD) or _datetime, inclusive.\n            Default is 1900-01-01\n            E.g. for start=\"2020-01-01\", the first data point will be on \"2020-01-01\"\n        end: str\n            Download end date string (YYYY-MM-DD) or _datetime, exclusive.\n            Default is now\n            E.g. for end=\"2023-01-01\", the last data point will be on \"2022-12-31\"\n        group_by : str\n            Group by 'ticker' or 'column' (default)\n        prepost : bool\n            Include Pre and Post market data in results?\n            Default is False\n        auto_adjust: bool\n            Adjust all OHLC automatically? Default is False\n        repair: bool\n            Detect currency unit 100x mixups and attempt repair\n            Default is False\n        keepna: bool\n            Keep NaN rows returned by Yahoo?\n            Default is False\n        actions: bool\n            Download dividend + stock splits data. Default is False\n        threads: bool / int\n            How many threads to use for mass downloading. Default is True\n        ignore_tz: bool\n            When combining from different timezones, ignore that part of datetime.\n            Default depends on interval. Intraday = False. Day+ = True.\n        proxy: str\n            Optional. Proxy server URL scheme. Default is None\n        rounding: bool\n            Optional. Round values to 2 decimal places?\n        show_errors: bool\n            Optional. Doesn't print errors if False\n            DEPRECATED, will be removed in future version\n        timeout: None or float\n            If not None stops waiting for a response after given number of\n            seconds. (Can also be a fraction of a second e.g. 0.01)\n        session: None or Session\n            Optional. Pass your own session object to be used for all requests\n    \"\"\"\n    logger = utils.get_yf_logger()\n\n    if show_errors is not None:\n        if show_errors:\n            utils.print_once(f\"yfinance: download(show_errors={show_errors}) argument is deprecated and will be removed in future version. Do this instead: logging.getLogger('yfinance').setLevel(logging.ERROR)\")\n            logger.setLevel(logging.ERROR)\n        else:\n            utils.print_once(f\"yfinance: download(show_errors={show_errors}) argument is deprecated and will be removed in future version. Do this instead to suppress error messages: logging.getLogger('yfinance').setLevel(logging.CRITICAL)\")\n            logger.setLevel(logging.CRITICAL)\n\n    if logger.isEnabledFor(logging.DEBUG):\n        if threads:\n            # With DEBUG, each thread generates a lot of log messages.\n            # And with multi-threading, these messages will be interleaved, bad!\n            # So disable multi-threading to make log readable.\n            logger.debug('Disabling multithreading because DEBUG logging enabled')\n            threads = False\n        if progress:\n            # Disable progress bar, interferes with display of log messages\n            progress = False\n\n    if ignore_tz is None:\n        # Set default value depending on interval\n        if interval[1:] in ['m', 'h']:\n            # Intraday\n            ignore_tz = False\n        else:\n            ignore_tz = True\n\n    # create ticker list\n    tickers = tickers if isinstance(\n        tickers, (list, set, tuple)) else tickers.replace(',', ' ').split()\n\n    # accept isin as ticker\n    shared._ISINS = {}\n    _tickers_ = []\n    for ticker in tickers:\n        if utils.is_isin(ticker):\n            isin = ticker\n            ticker = utils.get_ticker_by_isin(ticker, proxy, session=session)\n            shared._ISINS[ticker] = isin\n        _tickers_.append(ticker)\n\n    tickers = _tickers_\n\n    tickers = list(set([ticker.upper() for ticker in tickers]))\n\n    if progress:\n        shared._PROGRESS_BAR = utils.ProgressBar(len(tickers), 'completed')\n\n    # reset shared._DFS\n    shared._DFS = {}\n    shared._ERRORS = {}\n    shared._TRACEBACKS = {}\n\n    # download using threads\n    if threads:\n        if threads is True:\n            threads = min([len(tickers), _multitasking.cpu_count() * 2])\n        _multitasking.set_max_threads(threads)\n        for i, ticker in enumerate(tickers):\n            _download_one_threaded(ticker, period=period, interval=interval,\n                                   start=start, end=end, prepost=prepost,\n                                   actions=actions, auto_adjust=auto_adjust,\n                                   back_adjust=back_adjust, repair=repair, keepna=keepna,\n                                   progress=(progress and i > 0), proxy=proxy,\n                                   rounding=rounding, timeout=timeout, session=session)\n        while len(shared._DFS) < len(tickers):\n            _time.sleep(0.01)\n    # download synchronously\n    else:\n        for i, ticker in enumerate(tickers):\n            data = _download_one(ticker, period=period, interval=interval,\n                                 start=start, end=end, prepost=prepost,\n                                 actions=actions, auto_adjust=auto_adjust,\n                                 back_adjust=back_adjust, repair=repair, keepna=keepna,\n                                 proxy=proxy,\n                                 rounding=rounding, timeout=timeout, session=session)\n            if progress:\n                shared._PROGRESS_BAR.animate()\n    \n    if progress:\n        shared._PROGRESS_BAR.completed()\n\n    if shared._ERRORS:\n        # Send errors to logging module\n        logger = utils.get_yf_logger()\n        logger.error('\\n%.f Failed download%s:' % (\n            len(shared._ERRORS), 's' if len(shared._ERRORS) > 1 else ''))\n\n        # Log each distinct error once, with list of symbols affected\n        errors = {}\n        for ticker in shared._ERRORS:\n            err = shared._ERRORS[ticker]\n            err = err.replace(f'{ticker}', '%ticker%')\n            if not err in errors:\n                errors[err] = [ticker]\n            else:\n                errors[err].append(ticker)\n        for err in errors.keys():\n            logger.error(f'{errors[err]}: ' + err)\n\n        # Log each distinct traceback once, with list of symbols affected\n        tbs = {}\n        for ticker in shared._TRACEBACKS:\n            tb = shared._TRACEBACKS[ticker]\n            tb = tb.replace(f'{ticker}', '%ticker%')\n            if not tb in tbs:\n                tbs[tb] = [ticker]\n            else:\n                tbs[tb].append(ticker)\n        for tb in tbs.keys():\n            logger.debug(f'{tbs[tb]}: ' + tb)\n\n    if ignore_tz:\n        for tkr in shared._DFS.keys():\n            if (shared._DFS[tkr] is not None) and (shared._DFS[tkr].shape[0] > 0):\n                shared._DFS[tkr].index = shared._DFS[tkr].index.tz_localize(None)\n\n    if len(tickers) == 1:\n        ticker = tickers[0]\n        return shared._DFS[shared._ISINS.get(ticker, ticker)]\n\n    try:\n        data = _pd.concat(shared._DFS.values(), axis=1, sort=True,\n                          keys=shared._DFS.keys())\n    except Exception:\n        _realign_dfs()\n        data = _pd.concat(shared._DFS.values(), axis=1, sort=True,\n                          keys=shared._DFS.keys())\n\n    # switch names back to isins if applicable\n    data.rename(columns=shared._ISINS, inplace=True)\n\n    if group_by == 'column':\n        data.columns = data.columns.swaplevel(0, 1)\n        data.sort_index(level=0, axis=1, inplace=True)\n\n    return data\n\n\ndef _realign_dfs():\n    idx_len = 0\n    idx = None\n\n    for df in shared._DFS.values():\n        if len(df) > idx_len:\n            idx_len = len(df)\n            idx = df.index\n\n    for key in shared._DFS.keys():\n        try:\n            shared._DFS[key] = _pd.DataFrame(\n                index=idx, data=shared._DFS[key]).drop_duplicates()\n        except Exception:\n            shared._DFS[key] = _pd.concat([\n                utils.empty_df(idx), shared._DFS[key].dropna()\n            ], axis=0, sort=True)\n\n        # remove duplicate index\n        shared._DFS[key] = shared._DFS[key].loc[\n            ~shared._DFS[key].index.duplicated(keep='last')]\n\n\n@_multitasking.task\ndef _download_one_threaded(ticker, start=None, end=None,\n                           auto_adjust=False, back_adjust=False, repair=False,\n                           actions=False, progress=True, period=\"max\",\n                           interval=\"1d\", prepost=False, proxy=None,\n                           keepna=False, rounding=False, timeout=10, session=None):\n    data = _download_one(ticker, start, end, auto_adjust, back_adjust, repair,\n                         actions, period, interval, prepost, proxy, rounding,\n                         keepna, timeout, session)\n    if progress:\n        shared._PROGRESS_BAR.animate()\n\n\ndef _download_one(ticker, start=None, end=None,\n                  auto_adjust=False, back_adjust=False, repair=False,\n                  actions=False, period=\"max\", interval=\"1d\",\n                  prepost=False, proxy=None, rounding=False,\n                  keepna=False, timeout=10, session=None):\n    data = None\n    try:\n        data = Ticker(ticker, session=session).history(\n                period=period, interval=interval,\n                start=start, end=end, prepost=prepost,\n                actions=actions, auto_adjust=auto_adjust,\n                back_adjust=back_adjust, repair=repair, proxy=proxy,\n                rounding=rounding, keepna=keepna, timeout=timeout,\n                raise_errors=True\n        )\n    except Exception as e:\n        # glob try/except needed as current thead implementation breaks if exception is raised.\n        shared._DFS[ticker.upper()] = utils.empty_df()\n        shared._ERRORS[ticker.upper()] = repr(e)\n        shared._TRACEBACKS[ticker.upper()] = traceback.format_exc()\n    else:\n        shared._DFS[ticker.upper()] = data\n\n    return data\n", "path": "yfinance/multi.py"}], "after_files": [{"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n#\n# yfinance - market data downloader\n# https://github.com/ranaroussi/yfinance\n#\n# Copyright 2017-2019 Ran Aroussi\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\nfrom __future__ import print_function\n\nimport logging\nimport traceback\nimport time as _time\nimport multitasking as _multitasking\nimport pandas as _pd\n\nfrom . import Ticker, utils\nfrom . import shared\n\n@utils.log_indent_decorator\ndef download(tickers, start=None, end=None, actions=False, threads=True, ignore_tz=None,\n             group_by='column', auto_adjust=False, back_adjust=False, repair=False, keepna=False,\n             progress=True, period=\"max\", show_errors=None, interval=\"1d\", prepost=False,\n             proxy=None, rounding=False, timeout=10, session=None):\n    \"\"\"Download yahoo tickers\n    :Parameters:\n        tickers : str, list\n            List of tickers to download\n        period : str\n            Valid periods: 1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max\n            Either Use period parameter or use start and end\n        interval : str\n            Valid intervals: 1m,2m,5m,15m,30m,60m,90m,1h,1d,5d,1wk,1mo,3mo\n            Intraday data cannot extend last 60 days\n        start: str\n            Download start date string (YYYY-MM-DD) or _datetime, inclusive.\n            Default is 1900-01-01\n            E.g. for start=\"2020-01-01\", the first data point will be on \"2020-01-01\"\n        end: str\n            Download end date string (YYYY-MM-DD) or _datetime, exclusive.\n            Default is now\n            E.g. for end=\"2023-01-01\", the last data point will be on \"2022-12-31\"\n        group_by : str\n            Group by 'ticker' or 'column' (default)\n        prepost : bool\n            Include Pre and Post market data in results?\n            Default is False\n        auto_adjust: bool\n            Adjust all OHLC automatically? Default is False\n        repair: bool\n            Detect currency unit 100x mixups and attempt repair\n            Default is False\n        keepna: bool\n            Keep NaN rows returned by Yahoo?\n            Default is False\n        actions: bool\n            Download dividend + stock splits data. Default is False\n        threads: bool / int\n            How many threads to use for mass downloading. Default is True\n        ignore_tz: bool\n            When combining from different timezones, ignore that part of datetime.\n            Default depends on interval. Intraday = False. Day+ = True.\n        proxy: str\n            Optional. Proxy server URL scheme. Default is None\n        rounding: bool\n            Optional. Round values to 2 decimal places?\n        show_errors: bool\n            Optional. Doesn't print errors if False\n            DEPRECATED, will be removed in future version\n        timeout: None or float\n            If not None stops waiting for a response after given number of\n            seconds. (Can also be a fraction of a second e.g. 0.01)\n        session: None or Session\n            Optional. Pass your own session object to be used for all requests\n    \"\"\"\n    logger = utils.get_yf_logger()\n\n    if show_errors is not None:\n        if show_errors:\n            utils.print_once(f\"yfinance: download(show_errors={show_errors}) argument is deprecated and will be removed in future version. Do this instead: logging.getLogger('yfinance').setLevel(logging.ERROR)\")\n            logger.setLevel(logging.ERROR)\n        else:\n            utils.print_once(f\"yfinance: download(show_errors={show_errors}) argument is deprecated and will be removed in future version. Do this instead to suppress error messages: logging.getLogger('yfinance').setLevel(logging.CRITICAL)\")\n            logger.setLevel(logging.CRITICAL)\n\n    if logger.isEnabledFor(logging.DEBUG):\n        if threads:\n            # With DEBUG, each thread generates a lot of log messages.\n            # And with multi-threading, these messages will be interleaved, bad!\n            # So disable multi-threading to make log readable.\n            logger.debug('Disabling multithreading because DEBUG logging enabled')\n            threads = False\n        if progress:\n            # Disable progress bar, interferes with display of log messages\n            progress = False\n\n    if ignore_tz is None:\n        # Set default value depending on interval\n        if interval[1:] in ['m', 'h']:\n            # Intraday\n            ignore_tz = False\n        else:\n            ignore_tz = True\n\n    # create ticker list\n    tickers = tickers if isinstance(\n        tickers, (list, set, tuple)) else tickers.replace(',', ' ').split()\n\n    # accept isin as ticker\n    shared._ISINS = {}\n    _tickers_ = []\n    for ticker in tickers:\n        if utils.is_isin(ticker):\n            isin = ticker\n            ticker = utils.get_ticker_by_isin(ticker, proxy, session=session)\n            shared._ISINS[ticker] = isin\n        _tickers_.append(ticker)\n\n    tickers = _tickers_\n\n    tickers = list(set([ticker.upper() for ticker in tickers]))\n\n    if progress:\n        shared._PROGRESS_BAR = utils.ProgressBar(len(tickers), 'completed')\n\n    # reset shared._DFS\n    shared._DFS = {}\n    shared._ERRORS = {}\n    shared._TRACEBACKS = {}\n\n    # download using threads\n    if threads:\n        if threads is True:\n            threads = min([len(tickers), _multitasking.cpu_count() * 2])\n        _multitasking.set_max_threads(threads)\n        for i, ticker in enumerate(tickers):\n            _download_one_threaded(ticker, period=period, interval=interval,\n                                   start=start, end=end, prepost=prepost,\n                                   actions=actions, auto_adjust=auto_adjust,\n                                   back_adjust=back_adjust, repair=repair, keepna=keepna,\n                                   progress=(progress and i > 0), proxy=proxy,\n                                   rounding=rounding, timeout=timeout, session=session)\n        while len(shared._DFS) < len(tickers):\n            _time.sleep(0.01)\n    # download synchronously\n    else:\n        for i, ticker in enumerate(tickers):\n            data = _download_one(ticker, period=period, interval=interval,\n                                 start=start, end=end, prepost=prepost,\n                                 actions=actions, auto_adjust=auto_adjust,\n                                 back_adjust=back_adjust, repair=repair, keepna=keepna,\n                                 proxy=proxy,\n                                 rounding=rounding, timeout=timeout, session=session)\n            if progress:\n                shared._PROGRESS_BAR.animate()\n    \n    if progress:\n        shared._PROGRESS_BAR.completed()\n\n    if shared._ERRORS:\n        # Send errors to logging module\n        logger = utils.get_yf_logger()\n        logger.error('\\n%.f Failed download%s:' % (\n            len(shared._ERRORS), 's' if len(shared._ERRORS) > 1 else ''))\n\n        # Log each distinct error once, with list of symbols affected\n        errors = {}\n        for ticker in shared._ERRORS:\n            err = shared._ERRORS[ticker]\n            err = err.replace(f'{ticker}', '%ticker%')\n            if not err in errors:\n                errors[err] = [ticker]\n            else:\n                errors[err].append(ticker)\n        for err in errors.keys():\n            logger.error(f'{errors[err]}: ' + err)\n\n        # Log each distinct traceback once, with list of symbols affected\n        tbs = {}\n        for ticker in shared._TRACEBACKS:\n            tb = shared._TRACEBACKS[ticker]\n            tb = tb.replace(f'{ticker}', '%ticker%')\n            if not tb in tbs:\n                tbs[tb] = [ticker]\n            else:\n                tbs[tb].append(ticker)\n        for tb in tbs.keys():\n            logger.debug(f'{tbs[tb]}: ' + tb)\n\n    if ignore_tz:\n        for tkr in shared._DFS.keys():\n            if (shared._DFS[tkr] is not None) and (shared._DFS[tkr].shape[0] > 0):\n                shared._DFS[tkr].index = shared._DFS[tkr].index.tz_localize(None)\n\n    if len(tickers) == 1:\n        ticker = tickers[0]\n        return shared._DFS[ticker]\n\n    try:\n        data = _pd.concat(shared._DFS.values(), axis=1, sort=True,\n                          keys=shared._DFS.keys())\n    except Exception:\n        _realign_dfs()\n        data = _pd.concat(shared._DFS.values(), axis=1, sort=True,\n                          keys=shared._DFS.keys())\n\n    # switch names back to isins if applicable\n    data.rename(columns=shared._ISINS, inplace=True)\n\n    if group_by == 'column':\n        data.columns = data.columns.swaplevel(0, 1)\n        data.sort_index(level=0, axis=1, inplace=True)\n\n    return data\n\n\ndef _realign_dfs():\n    idx_len = 0\n    idx = None\n\n    for df in shared._DFS.values():\n        if len(df) > idx_len:\n            idx_len = len(df)\n            idx = df.index\n\n    for key in shared._DFS.keys():\n        try:\n            shared._DFS[key] = _pd.DataFrame(\n                index=idx, data=shared._DFS[key]).drop_duplicates()\n        except Exception:\n            shared._DFS[key] = _pd.concat([\n                utils.empty_df(idx), shared._DFS[key].dropna()\n            ], axis=0, sort=True)\n\n        # remove duplicate index\n        shared._DFS[key] = shared._DFS[key].loc[\n            ~shared._DFS[key].index.duplicated(keep='last')]\n\n\n@_multitasking.task\ndef _download_one_threaded(ticker, start=None, end=None,\n                           auto_adjust=False, back_adjust=False, repair=False,\n                           actions=False, progress=True, period=\"max\",\n                           interval=\"1d\", prepost=False, proxy=None,\n                           keepna=False, rounding=False, timeout=10, session=None):\n    data = _download_one(ticker, start, end, auto_adjust, back_adjust, repair,\n                         actions, period, interval, prepost, proxy, rounding,\n                         keepna, timeout, session)\n    if progress:\n        shared._PROGRESS_BAR.animate()\n\n\ndef _download_one(ticker, start=None, end=None,\n                  auto_adjust=False, back_adjust=False, repair=False,\n                  actions=False, period=\"max\", interval=\"1d\",\n                  prepost=False, proxy=None, rounding=False,\n                  keepna=False, timeout=10, session=None):\n    data = None\n    try:\n        data = Ticker(ticker, session=session).history(\n                period=period, interval=interval,\n                start=start, end=end, prepost=prepost,\n                actions=actions, auto_adjust=auto_adjust,\n                back_adjust=back_adjust, repair=repair, proxy=proxy,\n                rounding=rounding, keepna=keepna, timeout=timeout,\n                raise_errors=True\n        )\n    except Exception as e:\n        # glob try/except needed as current thead implementation breaks if exception is raised.\n        shared._DFS[ticker.upper()] = utils.empty_df()\n        shared._ERRORS[ticker.upper()] = repr(e)\n        shared._TRACEBACKS[ticker.upper()] = traceback.format_exc()\n    else:\n        shared._DFS[ticker.upper()] = data\n\n    return data\n", "path": "yfinance/multi.py"}]}