Skip to content

Commit bbf7062

Browse files
kovtcharov-amdOvtcharov
andauthored
fix(deps): make python-multipart a base dependency for gaia-mcp (#1380)
The v0.20.0 post-publish smoke test caught a real packaging bug: on a clean `pip install amd-gaia`, the `gaia-mcp` command crashes immediately with `ModuleNotFoundError: No module named 'python_multipart'`. `gaia.mcp.mcp_bridge` imports `python_multipart` at module load, and `gaia-mcp` is a **base** console_script — but `python-multipart` was declared only in the `api`/`ui` extras (not even in `[mcp]`). So every base install (and `pip install amd-gaia[mcp]`) shipped a broken `gaia-mcp`. Fix: move `python-multipart>=0.0.9` into base `install_requires`. After this, `pip install amd-gaia` → `gaia-mcp --help` works, and the post-publish smoke test passes. Also adds a packaging regression test: if a base console_script's module imports a third-party package at top level, that dist must be a base dependency (not extras-only) — encoding the invariant this bug violated. > Note: v0.20.0 is already published to PyPI immutably with the bug; this fix ships in **0.20.1**. ## Test plan - [x] `pytest tests/unit/test_packaging.py` — passes; new `TestBaseDependencies` guard included - [ ] Post-publish smoke test on the 0.20.1 tag reaches `gaia-mcp --help` without `ModuleNotFoundError` Co-authored-by: Ovtcharov <kovtchar@amd.com>
1 parent 5e6f031 commit bbf7062

2 files changed

Lines changed: 46 additions & 0 deletions

File tree

setup.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@
109109
"beautifulsoup4",
110110
"watchdog>=2.1.0",
111111
"pillow>=9.0.0",
112+
# Required by the `gaia-mcp` bridge (base console_script), which parses
113+
# multipart uploads via python_multipart at import time. Base — not an
114+
# extra — so a plain `pip install amd-gaia` ships a working gaia-mcp.
115+
"python-multipart>=0.0.9",
112116
],
113117
extras_require={
114118
"image": [

tests/unit/test_packaging.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,21 @@ def _parse_setup_entry_points():
5757
return result
5858

5959

60+
def _parse_setup_install_requires():
61+
"""Extract the base install_requires package names (lowercased) from setup.py."""
62+
content = SETUP_PY.read_text()
63+
match = re.search(r"install_requires\s*=\s*\[(.*?)\]", content, re.DOTALL)
64+
assert match, "Could not find install_requires=[] in setup.py"
65+
raw = match.group(1)
66+
names = set()
67+
for spec in re.findall(r'"([^"]+)"', raw):
68+
# Strip version specifiers / markers; keep just the distribution name.
69+
name = re.split(r"[<>=!~; ]", spec, maxsplit=1)[0].strip().lower()
70+
if name:
71+
names.add(name)
72+
return names
73+
74+
6075
def _find_filesystem_packages():
6176
"""Find all directories under src/gaia/ that contain __init__.py."""
6277
packages = set()
@@ -189,3 +204,30 @@ def test_entry_point_parent_packages_declared(self):
189204
assert (
190205
not failures
191206
), f"Entry point parent packages missing from setup.py:\n" + "\n".join(failures)
207+
208+
209+
class TestBaseDependencies:
210+
"""Base console_scripts must work on a plain `pip install amd-gaia`."""
211+
212+
def test_gaia_mcp_module_imports_are_base_deps(self):
213+
"""`gaia-mcp` is a base console_script whose module imports
214+
``python_multipart`` at load time. The dist must be in base
215+
install_requires (not only extras), or a plain `pip install amd-gaia`
216+
ships a broken gaia-mcp. Regression for the v0.20.0 post-publish smoke
217+
failure (ModuleNotFoundError: python_multipart)."""
218+
bridge = (SRC_DIR / "gaia" / "mcp" / "mcp_bridge.py").read_text(
219+
encoding="utf-8"
220+
)
221+
base = _parse_setup_install_requires()
222+
# Only enforce while the import is top-level; a future lazy import would
223+
# legitimately move the dep into an extra.
224+
top_level_multipart = re.search(
225+
r"^(from|import) python_multipart", bridge, re.MULTILINE
226+
)
227+
if top_level_multipart:
228+
assert "python-multipart" in base, (
229+
"gaia.mcp.mcp_bridge imports python_multipart at module top level "
230+
"and gaia-mcp is a base console_script, but 'python-multipart' is "
231+
"not in setup.py install_requires (only extras). A plain "
232+
"`pip install amd-gaia` would ship a broken gaia-mcp entry point."
233+
)

0 commit comments

Comments
 (0)