From 0521428f693276b090b9dc3a68f5e4e5a6dadb52 Mon Sep 17 00:00:00 2001 From: Mike Reiche Date: Mon, 9 Oct 2023 09:53:57 +0200 Subject: [PATCH 1/7] Fixed typing bug when series are empty --- yfinance/base.py | 21 ++++++++++++--------- yfinance/ticker.py | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/yfinance/base.py b/yfinance/base.py index 21af2bb51..ecc973aa7 100644 --- a/yfinance/base.py +++ b/yfinance/base.py @@ -45,6 +45,9 @@ from .const import _BASE_URL_, _ROOT_URL_ +_empty_series = pd.Series() + + class TickerBase: def __init__(self, ticker, session=None): self.ticker = ticker.upper() @@ -1910,31 +1913,31 @@ def get_cash_flow(self, proxy=None, as_dict=False, pretty=False, freq="yearly"): def get_cashflow(self, proxy=None, as_dict=False, pretty=False, freq="yearly"): return self.get_cash_flow(proxy, as_dict, pretty, freq) - def get_dividends(self, proxy=None): + def get_dividends(self, proxy=None) -> pd.Series: if self._history is None: self.history(period="max", proxy=proxy) if self._history is not None and "Dividends" in self._history: dividends = self._history["Dividends"] return dividends[dividends != 0] - return [] + return pd.Series() - def get_capital_gains(self, proxy=None): + def get_capital_gains(self, proxy=None) -> pd.Series: if self._history is None: self.history(period="max", proxy=proxy) if self._history is not None and "Capital Gains" in self._history: capital_gains = self._history["Capital Gains"] return capital_gains[capital_gains != 0] - return [] + return _empty_series - def get_splits(self, proxy=None): + def get_splits(self, proxy=None) -> pd.Series: if self._history is None: self.history(period="max", proxy=proxy) if self._history is not None and "Stock Splits" in self._history: splits = self._history["Stock Splits"] return splits[splits != 0] - return [] + return _empty_series - def get_actions(self, proxy=None): + def get_actions(self, proxy=None) -> pd.Series: if self._history is None: self.history(period="max", proxy=proxy) if self._history is not None and "Dividends" in self._history and "Stock Splits" in self._history: @@ -1943,7 +1946,7 @@ def get_actions(self, proxy=None): action_columns.append("Capital Gains") actions = self._history[action_columns] return actions[actions != 0].dropna(how='all').fillna(0) - return [] + return _empty_series def get_shares(self, proxy=None, as_dict=False): self._fundamentals.proxy = proxy @@ -2044,7 +2047,7 @@ def get_isin(self, proxy=None) -> Optional[str]: self._isin = data.split(search_str)[1].split('"')[0].split('|')[0] return self._isin - def get_news(self, proxy=None): + def get_news(self, proxy=None) -> list: if self._news: return self._news diff --git a/yfinance/ticker.py b/yfinance/ticker.py index 241638a5c..8d20a1d27 100644 --- a/yfinance/ticker.py +++ b/yfinance/ticker.py @@ -240,7 +240,7 @@ def options(self) -> tuple: return tuple(self._expirations.keys()) @property - def news(self): + def news(self) -> list: return self.get_news() @property From 9a3d60105ca8b0148a320806a33c07769be8235a Mon Sep 17 00:00:00 2001 From: Mike Reiche Date: Mon, 9 Oct 2023 09:59:25 +0200 Subject: [PATCH 2/7] Minor typing fixes --- yfinance/base.py | 12 ++++++------ yfinance/ticker.py | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/yfinance/base.py b/yfinance/base.py index ecc973aa7..8deaea3b4 100644 --- a/yfinance/base.py +++ b/yfinance/base.py @@ -26,7 +26,7 @@ import logging import time as _time import warnings -from typing import Optional +from typing import Optional, Union, List from urllib.parse import quote as urlencode import dateutil as _dateutil @@ -1883,7 +1883,7 @@ def get_balance_sheet(self, proxy=None, as_dict=False, pretty=False, freq="yearl def get_balancesheet(self, proxy=None, as_dict=False, pretty=False, freq="yearly"): return self.get_balance_sheet(proxy, as_dict, pretty, freq) - def get_cash_flow(self, proxy=None, as_dict=False, pretty=False, freq="yearly"): + def get_cash_flow(self, proxy=None, as_dict=False, pretty=False, freq="yearly") -> Union[pd.DataFrame, dict]: """ :Parameters: as_dict: bool @@ -1919,7 +1919,7 @@ def get_dividends(self, proxy=None) -> pd.Series: if self._history is not None and "Dividends" in self._history: dividends = self._history["Dividends"] return dividends[dividends != 0] - return pd.Series() + return _empty_series def get_capital_gains(self, proxy=None) -> pd.Series: if self._history is None: @@ -1937,7 +1937,7 @@ def get_splits(self, proxy=None) -> pd.Series: return splits[splits != 0] return _empty_series - def get_actions(self, proxy=None) -> pd.Series: + def get_actions(self, proxy=None) -> pd.DataFrame: if self._history is None: self.history(period="max", proxy=proxy) if self._history is not None and "Dividends" in self._history and "Stock Splits" in self._history: @@ -1946,9 +1946,9 @@ def get_actions(self, proxy=None) -> pd.Series: action_columns.append("Capital Gains") actions = self._history[action_columns] return actions[actions != 0].dropna(how='all').fillna(0) - return _empty_series + return pd.DataFrame() - def get_shares(self, proxy=None, as_dict=False): + def get_shares(self, proxy=None, as_dict=False) -> Union[pd.DataFrame, dict]: self._fundamentals.proxy = proxy data = self._fundamentals.shares if as_dict: diff --git a/yfinance/ticker.py b/yfinance/ticker.py index 8d20a1d27..09f55db48 100644 --- a/yfinance/ticker.py +++ b/yfinance/ticker.py @@ -134,7 +134,7 @@ def actions(self) -> _pd.DataFrame: return self.get_actions() @property - def shares(self) -> _pd.DataFrame : + def shares(self) -> _pd.DataFrame: return self.get_shares() @property From ba977a16a26cb97dc77fb4c3346e6d437952948c Mon Sep 17 00:00:00 2001 From: Mike Reiche Date: Tue, 10 Oct 2023 08:25:47 +0200 Subject: [PATCH 3/7] Added tests --- requirements.txt | 4 +++- tests/ticker.py | 22 +++++++++++++++++++--- yfinance/ticker.py | 2 +- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/requirements.txt b/requirements.txt index 427c16ebb..bbe2495ef 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,8 @@ pandas>=1.3.0 numpy>=1.16.5 requests>=2.31 +requests_cache==1.1.0 +requests_ratelimiter==0.4.2 multitasking>=0.0.7 lxml>=4.9.1 appdirs>=1.4.4 @@ -8,4 +10,4 @@ pytz>=2022.5 frozendict>=2.3.4 beautifulsoup4>=4.11.1 html5lib>=1.1 -peewee>=3.16.2 \ No newline at end of file +peewee>=3.16.2 diff --git a/tests/ticker.py b/tests/ticker.py index 681f0387d..8587a7ed6 100644 --- a/tests/ticker.py +++ b/tests/ticker.py @@ -102,8 +102,24 @@ def test_badTicker(self): dat.fast_info[k] for attribute_name, attribute_type in ticker_attributes: - assert_attribute_type(self, dat, attribute_name, attribute_type) - + assert_attribute_type(self, dat, attribute_name, attribute_type) + + with self.assertRaises(YFNotImplementedError): + assert isinstance(dat.earnings, pd.Series) + assert dat.earnings.empty + assert isinstance(dat.dividends, pd.Series) + assert dat.dividends.empty + assert isinstance(dat.splits, pd.Series) + assert dat.splits.empty + assert isinstance(dat.capital_gains, pd.Series) + assert dat.capital_gains.empty + with self.assertRaises(YFNotImplementedError): + assert isinstance(dat.shares, pd.DataFrame) + assert dat.shares.empty + assert isinstance(dat.actions, pd.DataFrame) + assert dat.actions.empty + + def test_goodTicker(self): # that yfinance works when full api is called on same instance of ticker @@ -912,7 +928,7 @@ def test_info(self): def suite(): suite = unittest.TestSuite() suite.addTest(TestTicker('Test ticker')) - suite.addTest(TestTickerEarnings('Test earnings')) + #suite.addTest(TestTickerEarnings('Test earnings')) suite.addTest(TestTickerHolders('Test holders')) suite.addTest(TestTickerHistory('Test Ticker history')) suite.addTest(TestTickerMiscFinancials('Test misc financials')) diff --git a/yfinance/ticker.py b/yfinance/ticker.py index 09f55db48..e6e2fa2b3 100644 --- a/yfinance/ticker.py +++ b/yfinance/ticker.py @@ -122,7 +122,7 @@ def dividends(self) -> _pd.Series: return self.get_dividends() @property - def capital_gains(self): + def capital_gains(self) -> _pd.Series: return self.get_capital_gains() @property From ac8a9172884940275c2381313acd69c3e46f9587 Mon Sep 17 00:00:00 2001 From: Mike Reiche Date: Tue, 9 Jan 2024 08:43:54 +0100 Subject: [PATCH 4/7] Revert adding explicit requirements --- requirements.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index bbe2495ef..b8768416b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,6 @@ pandas>=1.3.0 numpy>=1.16.5 requests>=2.31 -requests_cache==1.1.0 -requests_ratelimiter==0.4.2 multitasking>=0.0.7 lxml>=4.9.1 appdirs>=1.4.4 From 4c34487149ee95b8efb78644d7ee6cac5d760740 Mon Sep 17 00:00:00 2001 From: Mike Reiche Date: Tue, 9 Jan 2024 08:50:00 +0100 Subject: [PATCH 5/7] Revert disabling earnings test --- tests/ticker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ticker.py b/tests/ticker.py index 54ed7b85c..ff0d8e6c4 100644 --- a/tests/ticker.py +++ b/tests/ticker.py @@ -926,7 +926,7 @@ def test_complementary_info(self): def suite(): suite = unittest.TestSuite() suite.addTest(TestTicker('Test ticker')) - #suite.addTest(TestTickerEarnings('Test earnings')) + suite.addTest(TestTickerEarnings('Test earnings')) suite.addTest(TestTickerHolders('Test holders')) suite.addTest(TestTickerHistory('Test Ticker history')) suite.addTest(TestTickerMiscFinancials('Test misc financials')) From 223f5337a8f995c7f4623c425a49ece0ba56e193 Mon Sep 17 00:00:00 2001 From: Mike Reiche Date: Tue, 9 Jan 2024 08:50:31 +0100 Subject: [PATCH 6/7] Remove empty static series --- yfinance/base.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/yfinance/base.py b/yfinance/base.py index af32ddd85..6cb3e751d 100644 --- a/yfinance/base.py +++ b/yfinance/base.py @@ -45,9 +45,6 @@ from .const import _BASE_URL_, _ROOT_URL_ -_empty_series = pd.Series() - - class TickerBase: def __init__(self, ticker, session=None, proxy=None): self.ticker = ticker.upper() @@ -1955,7 +1952,7 @@ def get_dividends(self, proxy=None) -> pd.Series: if self._history is not None and "Dividends" in self._history: dividends = self._history["Dividends"] return dividends[dividends != 0] - return _empty_series + return pd.Series() def get_capital_gains(self, proxy=None) -> pd.Series: if self._history is None: @@ -1963,7 +1960,7 @@ def get_capital_gains(self, proxy=None) -> pd.Series: if self._history is not None and "Capital Gains" in self._history: capital_gains = self._history["Capital Gains"] return capital_gains[capital_gains != 0] - return _empty_series + return pd.Series() def get_splits(self, proxy=None) -> pd.Series: if self._history is None: @@ -1971,7 +1968,7 @@ def get_splits(self, proxy=None) -> pd.Series: if self._history is not None and "Stock Splits" in self._history: splits = self._history["Stock Splits"] return splits[splits != 0] - return _empty_series + return pd.Series() def get_actions(self, proxy=None) -> pd.DataFrame: if self._history is None: From dbc55e55960d685eac0e31365f94fd38b52bac0a Mon Sep 17 00:00:00 2001 From: Mike Reiche Date: Tue, 9 Jan 2024 21:08:46 +0100 Subject: [PATCH 7/7] Remove unused List import --- yfinance/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yfinance/base.py b/yfinance/base.py index 6cb3e751d..c852df245 100644 --- a/yfinance/base.py +++ b/yfinance/base.py @@ -27,7 +27,7 @@ import logging import time as _time import warnings -from typing import Optional, Union, List +from typing import Optional, Union from urllib.parse import quote as urlencode import dateutil as _dateutil