When an operation is deterministic and expensive (often due to external IO like yfinance), avoid doing the same work twice. Use bounded memoization for repeated lookups and explicitly short-circuit cases where two inputs resolve to the same underlying entity. Also ensure caches don’t leak between tests.
Practical rules:
maxsize.autouse fixture).Example pattern:
from functools import lru_cache
import yfinance as yf
@lru_cache(maxsize=128)
def company_name(ticker: str) -> str:
return yf.Ticker(ticker).info.get("longName") or ""
def fetch_returns(ticker: str, benchmark: str, trade_date, end_str):
stock = yf.Ticker(ticker).history(start=trade_date, end=end_str)
# Avoid redundant external call when both refer to the same entity
if benchmark == ticker:
bench = stock
else:
bench = yf.Ticker(benchmark).history(start=trade_date, end=end_str)
# ...compute metrics using stock and bench...
return stock, bench
Enter the URL of a public GitHub repository