From 8efb70287113cb5a2ef3903163f785347f84690e Mon Sep 17 00:00:00 2001 From: Yijia-Xiao Date: Wed, 23 Sep 2026 23:57:13 +0000 Subject: [PATCH] style: normalise blank lines between definitions - two between top-level definitions, one between methods, none doubled inside a body --- cli/prompts.py | 1 + tests/test_api_key_env.py | 1 - tests/test_checkpoint_lifecycle.py | 2 -- tests/test_checkpoint_resume.py | 1 - tests/test_llm_max_retries.py | 1 + tests/test_llm_max_tokens.py | 1 + tests/test_news_lookahead.py | 2 -- tests/test_ohlcv_latest_bar.py | 1 + tests/test_reddit_fallback.py | 1 - tests/test_social_lookahead.py | 2 -- tradingagents/dataflows/router.py | 3 +++ tradingagents/dataflows/vendors/alpha_vantage/common.py | 4 +++- tradingagents/dataflows/vendors/alpha_vantage/news.py | 1 + tradingagents/dataflows/vendors/reddit.py | 1 + tradingagents/dataflows/vendors/yahoo/market.py | 2 +- 15 files changed, 13 insertions(+), 11 deletions(-) diff --git a/cli/prompts.py b/cli/prompts.py index 3eacb3cad..1aae00f8e 100644 --- a/cli/prompts.py +++ b/cli/prompts.py @@ -309,6 +309,7 @@ def select_deep_thinking_agent(provider, default=None) -> str: """Select deep thinking llm engine using an interactive selection.""" return _select_model(provider, "deep", default) + def _llm_provider_table() -> list[tuple[str, str, str | None]]: """(display_name, provider_key, base_url) for every supported provider. diff --git a/tests/test_api_key_env.py b/tests/test_api_key_env.py index 725d7649b..bdec18441 100644 --- a/tests/test_api_key_env.py +++ b/tests/test_api_key_env.py @@ -182,7 +182,6 @@ def test_existing_key_file_is_tightened_before_writing(monkeypatch, prompts, tmp assert "OTHER=1" in env.read_text() - @pytest.mark.skipif(os.name == "nt", reason="POSIX file modes") def test_read_only_key_file_is_still_updated(monkeypatch, prompts, tmp_path): env = tmp_path / ".env" diff --git a/tests/test_checkpoint_lifecycle.py b/tests/test_checkpoint_lifecycle.py index 4933b5b67..5bc8ff694 100644 --- a/tests/test_checkpoint_lifecycle.py +++ b/tests/test_checkpoint_lifecycle.py @@ -58,8 +58,6 @@ def _bare_graph(tmpdir, *, enabled=True): return g - - @pytest.mark.unit def test_disabled_is_a_noop(): with tempfile.TemporaryDirectory() as tmp: diff --git a/tests/test_checkpoint_resume.py b/tests/test_checkpoint_resume.py index bc0037671..6d134f6bb 100644 --- a/tests/test_checkpoint_resume.py +++ b/tests/test_checkpoint_resume.py @@ -103,7 +103,6 @@ class TestCheckpointResume(unittest.TestCase): self.assertEqual(result["count"], 11) - def test_different_date_starts_fresh(self): """A different date must NOT resume from an existing checkpoint.""" global _should_crash diff --git a/tests/test_llm_max_retries.py b/tests/test_llm_max_retries.py index a32416127..bac0c8bd1 100644 --- a/tests/test_llm_max_retries.py +++ b/tests/test_llm_max_retries.py @@ -15,6 +15,7 @@ from tradingagents.llm_clients.factory import _coerce_max_retries, build_llm_kwa # --- coercion / validation ------------------------------------------------- + @pytest.mark.unit @pytest.mark.parametrize("value,expected", [(0, 0), (2, 2), (10, 10), ("6", 6)]) def test_coerce_accepts_non_negative_ints_and_numeric_strings(value, expected): diff --git a/tests/test_llm_max_tokens.py b/tests/test_llm_max_tokens.py index 85e8760bb..2715e179e 100644 --- a/tests/test_llm_max_tokens.py +++ b/tests/test_llm_max_tokens.py @@ -17,6 +17,7 @@ from tradingagents.llm_clients.factory import _coerce_max_tokens, build_llm_kwar # --- coercion / validation ------------------------------------------------- + @pytest.mark.unit @pytest.mark.parametrize("value,expected", [(1, 1), (8192, 8192), ("4096", 4096)]) def test_coerce_accepts_positive_ints_and_numeric_strings(value, expected): diff --git a/tests/test_news_lookahead.py b/tests/test_news_lookahead.py index 09717d5e6..5c5c1c420 100644 --- a/tests/test_news_lookahead.py +++ b/tests/test_news_lookahead.py @@ -106,7 +106,6 @@ def test_global_news_empty_after_filter_is_informative(monkeypatch): assert "unavailable" in out and "not an absence" in out - def _ticker_with(articles, monkeypatch): class FakeTicker: def __init__(self, *a, **k): @@ -162,7 +161,6 @@ def test_coverage_gap_boundaries(dates, expect_gap): assert "unavailable for 2026-05-01..2026-05-08" in out and "not an absence" in out - @pytest.mark.unit def test_ticker_news_empty_feed_for_a_past_window_is_unavailable(monkeypatch): _ticker_with([], monkeypatch) diff --git a/tests/test_ohlcv_latest_bar.py b/tests/test_ohlcv_latest_bar.py index b326d3ef2..1fb82d866 100644 --- a/tests/test_ohlcv_latest_bar.py +++ b/tests/test_ohlcv_latest_bar.py @@ -30,6 +30,7 @@ def _stamp(path, ts): # --- date normalization ----------------------------------------------------- + @pytest.mark.unit def test_normalize_dates_strips_tz_and_normalizes_to_midnight(): aware = pd.Series(pd.to_datetime( diff --git a/tests/test_reddit_fallback.py b/tests/test_reddit_fallback.py index 79096b996..77d50c1b8 100644 --- a/tests/test_reddit_fallback.py +++ b/tests/test_reddit_fallback.py @@ -251,7 +251,6 @@ def test_posts_from_an_unrequested_or_unnamed_subreddit_are_not_dropped(): assert "NO LABEL" in out - @pytest.mark.unit def test_each_subreddit_keeps_its_own_quota(): busy = [{"title": f"A{i}", "created_utc": None, "selftext": "", "subreddit": "a"} for i in range(9)] diff --git a/tests/test_social_lookahead.py b/tests/test_social_lookahead.py index 92427f680..ca58e1a37 100644 --- a/tests/test_social_lookahead.py +++ b/tests/test_social_lookahead.py @@ -172,7 +172,6 @@ def test_reddit_live_empty_feed_is_a_real_absence(monkeypatch): assert "unavailable" not in out - @pytest.mark.unit def test_stocktwits_empty_stream_for_a_past_window_is_unavailable(monkeypatch): monkeypatch.setattr(stocktwits, "urlopen", lambda *a, **k: _JsonResp({"messages": []})) @@ -180,7 +179,6 @@ def test_stocktwits_empty_stream_for_a_past_window_is_unavailable(monkeypatch): assert "unavailable" in out and "not an absence" in out - @pytest.mark.unit def test_reddit_window_straddling_the_lookback_is_unavailable(monkeypatch): # Ten days ago through five days ago: the week-long search never reaches the diff --git a/tradingagents/dataflows/router.py b/tradingagents/dataflows/router.py index 8f6d277af..33d7df866 100644 --- a/tradingagents/dataflows/router.py +++ b/tradingagents/dataflows/router.py @@ -156,6 +156,7 @@ VENDOR_METHODS = { }, } + def get_category_for_method(method: str) -> str: """Get the category that contains the specified method.""" for category, info in TOOLS_CATEGORIES.items(): @@ -163,6 +164,7 @@ def get_category_for_method(method: str) -> str: return category raise ValueError(f"Method '{method}' not found in any category") + def get_vendor(category: str, method: str = None) -> str: """Get the configured vendor for a data category or specific tool method. Tool-level configuration takes precedence over category-level. @@ -178,6 +180,7 @@ def get_vendor(category: str, method: str = None) -> str: # Fall back to category-level configuration return config.get("data_vendors", {}).get(category, "default") + def route_to_vendor(method: str, *args, **kwargs): """Route method calls to appropriate vendor implementation with fallback support.""" category = get_category_for_method(method) diff --git a/tradingagents/dataflows/vendors/alpha_vantage/common.py b/tradingagents/dataflows/vendors/alpha_vantage/common.py index 640cf7a24..39ffb1d81 100644 --- a/tradingagents/dataflows/vendors/alpha_vantage/common.py +++ b/tradingagents/dataflows/vendors/alpha_vantage/common.py @@ -34,6 +34,7 @@ def get_api_key() -> str: ) return api_key + def format_datetime_for_api(date_input, end_of_day: bool = False) -> str: """Convert various date formats to the YYYYMMDDTHHMM Alpha Vantage expects. @@ -60,10 +61,12 @@ def format_datetime_for_api(date_input, end_of_day: bool = False) -> str: else: raise ValueError(f"Date must be string or datetime object, got {type(date_input)}") + class AlphaVantageRateLimitError(VendorRateLimitError): """Raised when the Alpha Vantage API rate limit is exceeded.""" pass + def _make_api_request(function_name: str, params: dict) -> dict | str: """Helper function to make API requests and handle responses. @@ -119,7 +122,6 @@ def _make_api_request(function_name: str, params: dict) -> dict | str: return response_text - def _filter_csv_by_date_range(csv_data: str, start_date: str, end_date: str) -> str: """ Filter CSV data to include only rows within the specified date range. diff --git a/tradingagents/dataflows/vendors/alpha_vantage/news.py b/tradingagents/dataflows/vendors/alpha_vantage/news.py index 76c16b89f..299264da7 100644 --- a/tradingagents/dataflows/vendors/alpha_vantage/news.py +++ b/tradingagents/dataflows/vendors/alpha_vantage/news.py @@ -32,6 +32,7 @@ def get_news(ticker, start_date, end_date) -> dict[str, str] | str: return _make_api_request("NEWS_SENTIMENT", params) + def get_global_news(curr_date, look_back_days: int | None = None, limit: int | None = None) -> dict[str, str] | str: """Returns global market news & sentiment data without ticker-specific filtering. diff --git a/tradingagents/dataflows/vendors/reddit.py b/tradingagents/dataflows/vendors/reddit.py index bfb0e6fef..db8397bfe 100644 --- a/tradingagents/dataflows/vendors/reddit.py +++ b/tradingagents/dataflows/vendors/reddit.py @@ -64,6 +64,7 @@ def _coverage_dates(posts) -> list: dates.append(datetime.now(timezone.utc) - _SEARCH_LOOKBACK) return dates + _RSS = "https://www.reddit.com/r/{sub}/search.rss?{qs}" # A descriptive, identified User-Agent (per Reddit's API etiquette). Reddit # blocks generic/anonymous tokens like bare "Mozilla/5.0" or "curl/…" but diff --git a/tradingagents/dataflows/vendors/yahoo/market.py b/tradingagents/dataflows/vendors/yahoo/market.py index 900b1dbbe..5e4d5a9c2 100644 --- a/tradingagents/dataflows/vendors/yahoo/market.py +++ b/tradingagents/dataflows/vendors/yahoo/market.py @@ -69,6 +69,7 @@ def get_YFin_data_online( return header + csv_string + def get_stock_stats_indicators_window( symbol: Annotated[str, "ticker symbol of the company"], indicator: Annotated[str, "technical indicator to get the analysis and report of"], @@ -269,7 +270,6 @@ def get_stockstats_indicator( return str(indicator_value) - def get_closes(symbol: str, start_date: str, end_date: str) -> pd.Series: """Daily closes from ``start_date`` up to, not including, ``end_date``.""" canonical = normalize_symbol(symbol)