[Fix] Replace subprocess startup-import diff with static source scan - #26934
Conversation
|
Michael Riad Zaky seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
Greptile SummaryThis PR replaces a subprocess-based
Confidence Score: 3/5Safe to merge for CI speed, but intentionally weakens the test's runtime guarantee — the class docstring and the actual assertion are now mismatched. P1 finding: the replacement test no longer verifies the property its class claims to assert (no lazy modules in sys.modules at startup), missing transitive and partial-path import leaks. tests/test_litellm/proxy/test_proxy_server.py — the test_heavy_modules_absent_at_startup method and its class docstring need to be updated to match the new (weaker) semantics, or the approach should be extended to also cover the gap patterns.
|
| Filename | Overview |
|---|---|
| tests/test_litellm/proxy/test_proxy_server.py | Replaces subprocess sys.modules diffing with a static regex scan of proxy_server.py; the new approach misses transitive imports and the partial-path import form, so the test no longer verifies what its class docstring claims. |
Reviews (1): Last reviewed commit: "test: replace subprocess startup-import ..." | Re-trigger Greptile
| def test_heavy_modules_absent_at_startup(self): | ||
| # Force a fresh `proxy_server` import in a subprocess so other tests | ||
| # in this run (which may have triggered lazy loads via the TestClient) | ||
| # don't pollute the result. | ||
| import subprocess | ||
|
|
||
| check = ( | ||
| "import sys; " | ||
| "from litellm.proxy.proxy_server import app; " # noqa: F401 | ||
| "heavy = [" | ||
| "'litellm.proxy._experimental.mcp_server.rest_endpoints'," | ||
| "'litellm.proxy._experimental.mcp_server.server'," | ||
| "'litellm.proxy.management_endpoints.config_override_endpoints'," | ||
| "'litellm.proxy.guardrails.guardrail_endpoints'," | ||
| "'litellm.proxy.openai_evals_endpoints.endpoints'," | ||
| "]; " | ||
| "still_present = [m for m in heavy if m in sys.modules]; " | ||
| "print('PRESENT_AT_STARTUP:', still_present)" | ||
| ) | ||
| result = subprocess.run( | ||
| [sys.executable, "-c", check], | ||
| capture_output=True, | ||
| text=True, | ||
| timeout=120, | ||
| # Static scan of proxy_server.py source — catches any top-level | ||
| # `from <lazy_module> import` that would defeat lazy loading. | ||
| # Importing proxy_server in a subprocess and diffing sys.modules | ||
| # would also work, but takes 60-120 s and flakes on slow CI runners. | ||
| import re | ||
| from pathlib import Path | ||
|
|
||
| from litellm.proxy._lazy_features import LAZY_FEATURES | ||
|
|
||
| proxy_server_src = ( | ||
| Path(__file__).resolve().parents[3] / "litellm/proxy/proxy_server.py" | ||
| ).read_text() | ||
|
|
||
| leaks = [] | ||
| for feat in LAZY_FEATURES: | ||
| # Anchor at column 0 — indented imports inside function bodies | ||
| # are fine (deferred until the function runs). | ||
| pattern = ( | ||
| rf"^(from\s+{re.escape(feat.module_path)}\s+import|" | ||
| rf"import\s+{re.escape(feat.module_path)})" | ||
| ) | ||
| if re.search(pattern, proxy_server_src, re.MULTILINE): | ||
| leaks.append(feat.module_path) | ||
|
|
||
| assert not leaks, ( | ||
| "proxy_server.py top-level imports a lazy feature module — these " | ||
| f"should be loaded via LazyFeatureMiddleware: {leaks}" | ||
| ) |
There was a problem hiding this comment.
Static scan doesn't catch transitive imports — test no longer verifies its own docstring
The class docstring states the test ensures "gated feature modules must NOT be present in sys.modules immediately after proxy_server imports," but the new implementation only checks for direct import X / from X import statements at column 0 in proxy_server.py. It misses two real failure modes:
- Transitive imports: if any module that
proxy_server.pyimports at the top level itself imports a lazy feature, the heavy module will appear insys.modulesat startup, but this scan won't detect it. - Partial-path form:
from litellm.proxy.guardrails import guardrail_endpointscauses the same startup load as the matched patterns but is undetected because the regex only anchors on the fullmodule_pathin thefromclause.
Rule Used: What: Flag any modifications to existing tests and... (source)
There was a problem hiding this comment.
This is intentional.
There was a problem hiding this comment.
Got it — the trade-off is intentional. A fast, partial check that catches direct top-level imports is a reasonable pragmatic choice over a correct-but-slow subprocess check that flakes on CI.
Tip: You can give me more context with .greptile/rules.md so I get this right next time.
e810d87
into
litellm_internal_staging
[Fix] Replace subprocess startup-import diff with static source scan
Relevant issues
Fixes lazy loading test that times out by statically checking imports instead.
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
tests/test_litellm/directory, Adding at least 1 test is a hard requirement - see detailsmake test-unit@greptileaiand received a Confidence Score of at least 4/5 before requesting a maintainer reviewScreenshots / Proof of Fix
Test is 13 seconds locally instead of timing out past two minutes.
Type
🐛 Bug Fix
✅ Test
Changes
test_proxy_server