Skip to content

Commit 5039c7b

Browse files
committed
get_news(): cap pagination at max_pages to prevent runaway requests
1 parent a266a5b commit 5039c7b

2 files changed

Lines changed: 17 additions & 1 deletion

File tree

‎tests/test_ticker.py‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,19 @@ def test_news_pagination_stops_on_stalled_cursor(self):
628628
self.assertEqual([a["id"] for a in news], ["a"])
629629
self.assertEqual(post.call_count, 2, "must break when endCursor does not advance")
630630

631+
def test_news_pagination_stops_on_max_pages(self):
632+
# Even if Yahoo returns new cursors with hasNextPage=True on every page of AssetErrors,
633+
# the loop must terminate at max_pages rather than running indefinitely.
634+
infinite_pages = (
635+
self._response([{"__typename": "AssetError"}], end_cursor=f"c{i}", has_next=True)
636+
for i in range(1, 100)
637+
)
638+
with patch("yfinance.data.YfData.post", side_effect=infinite_pages) as post:
639+
news = yf.Ticker("MSFT").get_news(count=5)
640+
641+
self.assertEqual(news, [])
642+
self.assertEqual(post.call_count, 5, "capped at max_pages (5 for count=5)")
643+
631644
def test_news_empty_result_is_cached(self):
632645
payload = {"data": {"lightyearList": None},
633646
"errors": [{"message": "Error", "extensions": {"code": "NOT_FOUND"}}]}

‎yfinance/base.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,10 @@ def get_news(self, count=10, tab="news") -> list:
674674

675675
news = []
676676
after = None
677-
while len(news) < count:
677+
max_pages = max(5, (count + 9) // 10 * 2)
678+
pages_fetched = 0
679+
while len(news) < count and pages_fetched < max_pages:
680+
pages_fetched += 1
678681
body = {
679682
"operationName": "FinanceTickerListNews",
680683
"query": _NEWS_GRAPHQL_QUERY_,

0 commit comments

Comments
 (0)