fix: relax python-dotenv pin from ==1.0.1 to >=1.0.1 - #25231
Conversation
The exact pin makes litellm uninstallable alongside any library that requires python-dotenv>=1.1.0 (e.g. fastmcp[tasks]==3.2.0). Exact pins in published package metadata propagate to every consumer's resolver. Reproducible builds should use lockfiles, not exact pins in pyproject.toml. Fixes BerriAI#25210 Co-Authored-By: Claude <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR relaxes the
Confidence Score: 5/5Safe to merge — this is a pure dependency metadata change with no behavioral impact The only finding is a P2 style suggestion to add a major-version upper bound. The change itself is correct, well-motivated by a real and reproducible incompatibility, and consistent with library packaging best practices. No 2.x python-dotenv release exists today. All remaining concerns are speculative future-proofing. No files require special attention
|
| Filename | Overview |
|---|---|
| pyproject.toml | Relaxes python-dotenv pin from ==1.0.1 to >=1.0.1; consistent with library packaging best practices but lacks an upper bound unlike all surrounding exact pins |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Consumer installs litellm + fastmcp] --> B{Dependency resolver}
B -->|Before PR: litellm==1.83.3 requires python-dotenv==1.0.1| C[❌ Conflict with fastmcp requiring python-dotenv>=1.1.0]
B -->|After PR: litellm>=1.83.4 requires python-dotenv>=1.0.1| E[✅ Resolver picks compatible version]
E --> F[python-dotenv 1.1.0 installed successfully]
Reviews (1): Last reviewed commit: "fix: relax python-dotenv pin from ==1.0...." | Re-trigger Greptile
| httpx = "0.28.1" | ||
| openai = "2.30.0" | ||
| python-dotenv = "1.0.1" | ||
| python-dotenv = ">=1.0.1" |
There was a problem hiding this comment.
No upper bound on the relaxed pin
All other core (non-optional) dependencies in this file are exact-pinned (e.g. httpx = "0.28.1", openai = "2.30.0"), and the comment at line 21 explicitly states these were derived from a known-good PyPI resolution. Relaxing python-dotenv to >=1.0.1 with no upper bound means a future python-dotenv 2.x with breaking changes could silently be pulled in by consumers.
As of now there is no 2.x release, but adding a major-version cap is inexpensive insurance and aligns with the project's cautious pinning intent:
| python-dotenv = ">=1.0.1" | |
| python-dotenv = ">=1.0.1,<2.0.0" |
NBI's pyproject was un-installable on a fresh Python 3.14 because `litellm>=1.83.7` (the floor that picks up CVE-2026-42203 / CVE-2026-42208 / CVE-2026-42271 fixes) hard-pins `python-dotenv==1.0.1`, and every `fastmcp>=2.11.2` release requires `python-dotenv>=1.1.0`. Mutually unsatisfiable; pip reports `ResolutionImpossible`. Upstream litellm has closed a CVE-fix bump (BerriAI/litellm#26435) and stalled on a pin-relaxation PR (BerriAI/litellm#25231) for ~7 weeks with no signal of movement. This commit drops the `fastmcp` dep entirely and routes `mcp_manager.py` through a thin local shim (`notebook_intelligence/mcp_client.py`) implemented against the official `mcp` Python SDK. The SDK lists `python-dotenv` only as an optional `cli` extra, so it can coexist with litellm's hard `==1.0.1` and the resolver succeeds. `mcp` was already in NBI's dep tree (transitively via `claude-agent-sdk`); promoted to a direct `>=1.27.0` pin so the version is anchored. The shim exposes the small fastmcp surface NBI used (`Client`, `StdioTransport`, `StreamableHttpTransport`) with constructor signatures and method shapes identical to fastmcp's. Return values are the underlying mcp Pydantic models — the same shapes fastmcp returned, since fastmcp itself is a thin layer over the SDK. mcp_manager.py's two imports change; nothing else in the consumer moves. Tests (`tests/test_mcp_client_shim.py`, 5 cases): - Constructor field-name parity for both transports. - Methods-before-context-entry surface as RuntimeError. - Unsupported transport types surface as TypeError. - End-to-end against a real stdio MCP server: ping, list_tools, call_tool, list_prompts, get_prompt. Asserts the exact attribute paths mcp_manager.py reads (tool.name / tool.inputSchema / prompt.arguments[i].required / get_prompt_result.messages[i]. content.text). A future SDK refactor that returns an envelope where a list was expected (or vice versa) flunks the test rather than silently breaking the consumer. - Context cleanup on initialize failure: the stdio subprocess unwinds cleanly when the server exits before the handshake. Verification: fresh `python -m venv && pip install -e .` on Python 3.14 succeeds (previously failed with ResolutionImpossible). Full pytest suite: 1012 passed. TS gates clean. The shim's end-to-end test runs the real stdio handshake in <1s. Temporary in spirit: once BerriAI/litellm#25231 lands and the fastmcp clients NBI used become installable alongside it again, this shim can revert to a direct `fastmcp` import and the local file can be deleted. Both the new module's docstring and the pyproject comment point at that upstream PR.
|
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. |
Summary
Relaxes the
python-dotenvdependency pin inpyproject.tomlfrom exact==1.0.1to lower-bounded>=1.0.1.Motivation
The exact pin introduced in v1.83.1 makes litellm uninstallable alongside any package requiring
python-dotenv>=1.1.0(e.g.fastmcp[tasks]==3.2.0):Exact pins in published package metadata propagate to every consumer's resolver. Reproducible builds should use lockfiles (poetry.lock), not exact pins in pyproject.toml.
Changes
pyproject.toml: Changedpython-dotenv = "1.0.1"topython-dotenv = ">=1.0.1"Testing
No behavioral change — this only affects dependency resolution. Existing tests are unaffected.
Disclaimer
AI agents (Claude Code) assisted with this contribution.
Fixes #25210