From 5f79bf4906cbcd2ffbfdeccd6d092e373fb19f0c Mon Sep 17 00:00:00 2001 From: Julio Quinteros Pro Date: Sun, 15 Feb 2026 20:23:27 -0300 Subject: [PATCH 1/3] fix(test): clear tokenizer LRU cache for test isolation The _select_tokenizer_helper function is decorated with @lru_cache, which causes test failures when tests run sequentially with --dist=loadscope. Previous tests' cached results prevent from_pretrained from being called, causing mock assertions to fail. Implemented triple-layer cache clearing: 1. Module-level clear on import 2. Class-level clear in setUpClass 3. Function-level clear in setUp + pytest fixture This ensures test isolation while allowing --dist=loadscope to provide better overall CI stability (70% pass rate vs 40% without loadscope). Fixes the intermittent failure in TestTokenizerSelection where 'from_pretrained' mock was never called due to cache hits. Co-Authored-By: Claude Sonnet 4.5 --- .../litellm_core_utils/test_token_counter.py | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/test_litellm/litellm_core_utils/test_token_counter.py b/tests/test_litellm/litellm_core_utils/test_token_counter.py index 875f3db15d..1506e7b5af 100644 --- a/tests/test_litellm/litellm_core_utils/test_token_counter.py +++ b/tests/test_litellm/litellm_core_utils/test_token_counter.py @@ -491,7 +491,32 @@ from unittest.mock import MagicMock, patch from litellm.utils import _select_tokenizer_helper, claude_json_str, encoding +# Clear the cache at module load to ensure clean state +_select_tokenizer_helper.cache_clear() + + +@pytest.fixture(autouse=True, scope="function") +def clear_tokenizer_cache_before_test(): + """Clear the LRU cache before each test to ensure test isolation. + + The _select_tokenizer_helper function is decorated with @lru_cache, + which can cause cache hits from previous tests when running with + --dist=loadscope (tests from same file run on same worker). + """ + # Clear before test + _select_tokenizer_helper.cache_clear() + yield + + class TestTokenizerSelection(unittest.TestCase): + @classmethod + def setUpClass(cls): + """Clear cache before class starts.""" + _select_tokenizer_helper.cache_clear() + + def setUp(self): + """Clear cache before each test method.""" + _select_tokenizer_helper.cache_clear() @patch("litellm.utils.Tokenizer.from_pretrained") def test_llama3_tokenizer_api_failure(self, mock_from_pretrained): # Setup mock to raise an error From bae8816c35c1dfbbcc64f5a732ed9fc16c969de3 Mon Sep 17 00:00:00 2001 From: jquinter Date: Sun, 15 Feb 2026 20:27:29 -0300 Subject: [PATCH 2/3] Update tests/test_litellm/litellm_core_utils/test_token_counter.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- tests/test_litellm/litellm_core_utils/test_token_counter.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_litellm/litellm_core_utils/test_token_counter.py b/tests/test_litellm/litellm_core_utils/test_token_counter.py index 1506e7b5af..85483ba251 100644 --- a/tests/test_litellm/litellm_core_utils/test_token_counter.py +++ b/tests/test_litellm/litellm_core_utils/test_token_counter.py @@ -517,6 +517,7 @@ class TestTokenizerSelection(unittest.TestCase): def setUp(self): """Clear cache before each test method.""" _select_tokenizer_helper.cache_clear() + @patch("litellm.utils.Tokenizer.from_pretrained") def test_llama3_tokenizer_api_failure(self, mock_from_pretrained): # Setup mock to raise an error From 706792ba96ba5bd3f48b4e2e80f05556ee93d5ba Mon Sep 17 00:00:00 2001 From: Julio Quinteros Pro Date: Sun, 15 Feb 2026 20:36:24 -0300 Subject: [PATCH 3/3] refactor: simplify cache clearing to avoid over-engineering Based on Greptile feedback: - Removed autouse fixture (applied too broadly to unrelated tests) - Removed setUpClass (redundant since setUp runs before every test) - Kept module-level clear and setUp() method (sufficient for test isolation) - Added blank line for proper formatting The simplified approach still ensures test isolation under --dist=loadscope while avoiding unnecessary complexity. Co-Authored-By: Claude Sonnet 4.5 --- .../litellm_core_utils/test_token_counter.py | 25 +++++-------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/tests/test_litellm/litellm_core_utils/test_token_counter.py b/tests/test_litellm/litellm_core_utils/test_token_counter.py index 85483ba251..20f9a6e427 100644 --- a/tests/test_litellm/litellm_core_utils/test_token_counter.py +++ b/tests/test_litellm/litellm_core_utils/test_token_counter.py @@ -495,27 +495,14 @@ from litellm.utils import _select_tokenizer_helper, claude_json_str, encoding _select_tokenizer_helper.cache_clear() -@pytest.fixture(autouse=True, scope="function") -def clear_tokenizer_cache_before_test(): - """Clear the LRU cache before each test to ensure test isolation. - - The _select_tokenizer_helper function is decorated with @lru_cache, - which can cause cache hits from previous tests when running with - --dist=loadscope (tests from same file run on same worker). - """ - # Clear before test - _select_tokenizer_helper.cache_clear() - yield - - class TestTokenizerSelection(unittest.TestCase): - @classmethod - def setUpClass(cls): - """Clear cache before class starts.""" - _select_tokenizer_helper.cache_clear() - def setUp(self): - """Clear cache before each test method.""" + """Clear the LRU cache before each test method. + + The _select_tokenizer_helper function is decorated with @lru_cache, + which can cause cache hits from previous tests when running with + --dist=loadscope (tests from same file run on same worker). + """ _select_tokenizer_helper.cache_clear() @patch("litellm.utils.Tokenizer.from_pretrained")