From 33f0b138d6bc1bb45bde0e124836b76078064a61 Mon Sep 17 00:00:00 2001 From: Liang Wu <18244712+wuliang229@users.noreply.github.com> Date: Thu, 6 Aug 2026 01:00:45 +0000 Subject: [PATCH] fix(deps): exclude nltk 3.10.1, which breaks venvs living inside the working directory (v1) Ports 1a0c3bd49f512dc3b01e3e83185a6315ae3e954b from main to v1. Applied by hand rather than cherry-picked, because the extras lists have diverged between the branches; the same three extras reach nltk on v1. nltk 3.10.1 added an import-time security hook (nltk/inisec.py) that breaks any ADK code path reaching nltk, in two independent ways: 1. It installs a meta-path finder that raises ImportError for any module whose file resolves under the current working directory while an nltk frame is on the stack. The standard layout puts the virtualenv inside the project (.venv/), so every site-packages module nltk imports looks like a CWD hijack and a plain `import nltk` dies on `import regex`. 2. It calls os.environ.setdefault("PYTHONSAFEPATH", "1"), which leaks into every subprocess started afterwards. PYTHONSAFEPATH stops CPython from prepending the script/CWD entry to sys.path, and that prepend is what causes the eagerly created `google` namespace package (from google-cloud-aiplatform's legacy *-nspkg.pth) to recompute its __path__ and pick up src/google. Without it, `import google.adk` fails with ModuleNotFoundError in child interpreters. Note this happens even when the nltk import itself fails, because the hook installs before the failure, so catching the ImportError does not undo it. Three extras reach nltk, and all three are constrained here: * eval -> rouge-score -> nltk. * extensions -> llama-index-{embeddings-google-genai,readers-file} -> llama-index-core -> nltk. * test -> both of the above. nltk removed the hook in 3.10.2, released after the original commit landed on main, so a fresh resolve already picks up a good version. 3.10.1 is not yanked, though, so it stays reachable via stale lockfiles, lowest-version resolution and pinned or mirrored indexes. The `!=` form excludes only the bad release and keeps v1 in parity with main. --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 809332d953..951f86a64f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -109,6 +109,7 @@ optional-dependencies.eval = [ "gepa>=0.1", "google-cloud-aiplatform[evaluation]>=1.148", "jinja2>=3.1.4,<4", # For eval template rendering + "nltk!=3.10.1", # Transitive via rouge-score; 3.10.1's import hook breaks any venv living inside the working directory (reverted upstream in nltk/nltk#3732). "pandas>=2.2.3", "rouge-score>=0.1.2", "tabulate>=0.9", @@ -128,6 +129,7 @@ optional-dependencies.extensions = [ "llama-index-embeddings-google-genai>=0.3", # For files retrieval using LlamaIndex. "llama-index-readers-file>=0.4", # For retrieval using LlamaIndex. "lxml>=5.3", # For load_web_page tool. + "nltk!=3.10.1", # Transitive via llama-index-core; 3.10.1's import hook breaks any venv living inside the working directory (reverted upstream in nltk/nltk#3732). "pypika>=0.50", # For crewai->chromadb dependency "toolbox-adk>=1,<2", # For tools.toolbox_toolset.ToolboxToolset ] @@ -145,6 +147,7 @@ optional-dependencies.test = [ "langgraph>=0.2.60,<0.4.8", # For LangGraphAgent "litellm>=1.83.7,<=1.83.14", # For LiteLLM tests. Lower bound: 5 CVE patches (2026-04). Upper bound pinned to current latest; bump deliberately. See #5488. "llama-index-readers-file>=0.4", # For retrieval tests + "nltk!=3.10.1", # Transitive via rouge-score and llama-index-core; 3.10.1's import hook breaks any venv living inside the working directory (reverted upstream in nltk/nltk#3732). "openai>=1.100.2", # For LiteLLM "opentelemetry-instrumentation-google-genai>=0.3b0,<1", "pypika>=0.50", # For crewai->chromadb dependency