fix(context): guard wren context show/validate against null relationship models - #2494
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughRelationship validation and ChangesNull relationship models
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
core/wren/src/wren/context_cli.py (1)
1209-1209: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winApply the same null-safe fallback in
_show_from_osi.Line 1209 still uses
r.get("models", []), which returnsNone(not[]) whenmodelsis present but null — the exact bug this PR fixes in the other two readers. If an OSI-generated manifest ever contains a relationship with null models, this path will raiseTypeErroron" ↔ ".join(None).♻️ Proposed fix for consistency
- models_str = " ↔ ".join(r.get("models", [])) + models_str = " ↔ ".join(r.get("models") or [])🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@core/wren/src/wren/context_cli.py` at line 1209, Update the models extraction in `_show_from_osi` to fall back to an empty list when `r.get("models")` returns null, ensuring the subsequent `" ↔ ".join(...)` remains safe for OSI manifests with null models.core/wren/tests/unit/test_context_cli.py (1)
477-488: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winStrengthen assertions to check exit code, not just TypeError absence.
Both tests only assert that
result.exceptionis not aTypeError. A different failure (e.g., a different exception or a nonzero exit code) would pass silently. Addingassert result.exit_code == 0ensures the commands actually succeed.💚 Proposed fix to strengthen test assertions
def test_validate_tolerates_null_relationship_models(tmp_path): _make_valid_project(tmp_path) _write_null_models_relationship(tmp_path) result = runner.invoke(app, ["context", "validate", "--path", str(tmp_path)]) - assert not isinstance(result.exception, TypeError), result.output + assert result.exit_code == 0, result.output def test_show_tolerates_null_relationship_models(tmp_path): _make_valid_project(tmp_path) _write_null_models_relationship(tmp_path) result = runner.invoke(app, ["context", "show", "--path", str(tmp_path)]) - assert not isinstance(result.exception, TypeError), result.output + assert result.exit_code == 0, result.output🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@core/wren/tests/unit/test_context_cli.py` around lines 477 - 488, Strengthen test_validate_tolerates_null_relationship_models and test_show_tolerates_null_relationship_models by asserting result.exit_code == 0, while retaining the existing TypeError assertion and diagnostic output. Ensure both CLI commands are verified to complete successfully.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@core/wren/src/wren/context_cli.py`:
- Line 1209: Update the models extraction in `_show_from_osi` to fall back to an
empty list when `r.get("models")` returns null, ensuring the subsequent `" ↔
".join(...)` remains safe for OSI manifests with null models.
In `@core/wren/tests/unit/test_context_cli.py`:
- Around line 477-488: Strengthen
test_validate_tolerates_null_relationship_models and
test_show_tolerates_null_relationship_models by asserting result.exit_code == 0,
while retaining the existing TypeError assertion and diagnostic output. Ensure
both CLI commands are verified to complete successfully.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 4e7a0096-95f2-43d4-9426-75a2a481d551
📒 Files selected for processing (3)
core/wren/src/wren/context.pycore/wren/src/wren/context_cli.pycore/wren/tests/unit/test_context_cli.py
The null-models tests only checked that no TypeError escaped, so any other failure mode would have passed silently. Pin the real contract instead: `show` exits 0, and `validate` reports the bad manifest as a semantic error via typer.Exit(1) rather than crashing.
|
@coderabbitai Thanks — took one of the two, and here is why the other one does not apply.
rel_dict: dict = {
"name": name,
"models": [src, dst],
...
}
Test assertions — fixed in d54f408. You were right that
Both tests were re-checked by reverting each guard independently: reverting |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
fd -a osi.py core/wren/src
echo "---"
rg -n "rel_dict" -A15 core/wren/src/wren/osi.py | head -60
echo "---convert_relationship---"
rg -n "_convert_relationship" -A20 core/wren/src/wren/osi.py | head -60
echo "---context_cli show_from_osi---"
rg -n "_show_from_osi" -A30 core/wren/src/wren/context_cli.py | head -60Length of output: 4781
And the refined test assertions in d54f408 are a better fit than my original suggestion — pinning (๑˘•ᴗ•˘)ﻭ |
Summary
wren contextCLI surface against an explicit YAML/JSONnullfor a relationship'smodels:validate_project(context.py) and theshowsummary display (context_cli.py).wren context validateandwren context showno longer abort with an unhandledTypeErrorwhen a project'srelationships.ymlcontains a relationship whosemodels:is left blank (YAML null).Motivation
Both readers do the equivalent of:
dict.get(key, default)only substitutes the default when the key is absent, not when its value isNone.load_relationshipsreadsrelationships.ymland passes each entry straight through, so a relationship written asreaches these readers with
models = None, crashingfor m in None(validate) and" ↔ ".join(None)(show).This is the same null-slip the maintainer already fixed in the memory package in #2424 (
seed_queries._relationship_seed, withtest_relationship_null_models_skipped); this PR closes the same gap on thecontextcommand surface. (A companion PR closes it inwren.memory.schema_indexer.)Fix
Use an
orfallback at both sites:rel.get("models") or []. Behaviour is unchanged for every non-null input; only the crashingnullcase changes —validatetreats it as a relationship with no listed models (consistent with how it already handles an emptymodelslist), andshowprints an empty endpoint list.Verification
CliRunner:test_validate_tolerates_null_relationship_modelstest_show_tolerates_null_relationship_modelsTypeError: 'NoneType' object is not iterable(validate) andTypeError: can only join an iterable(show) — RED.context.pyalone reds the validate test only; revertingcontext_cli.pyalone reds the show test only.uv run --no-sync pytest tests/unit/ --ignore=tests/unit/test_memory.py→ 947 passed, 2 skipped (baseline 945 + the two new tests; 0 regressions).just lintclean.wrenCLI:wren context showprintsrel1 (, MANY_TO_ONE)and exits 0;wren context validateruns to completion — neither raises.Scope
Two reachable sites, both fed by the user-authored
relationships.yml. Theshow --from-osisummary (_show_from_osi,context_cli.py) has the identical expression but is not reachable with a nullmodels:build_manifest_from_osialways constructs relationshipmodelsas[src, dst](and drops relationships it can't build), so no null reaches it — left untouched per "don't guard a case that can't occur." Thedbt.pyrelationship reader builds its relationships internally rather than from an untrusted manifest and is likewise not reached.License
core/**is Apache-2.0 per the repo LICENSE path map — this contribution is within an Apache-2.0 path.Summary by CodeRabbit
Bug Fixes
modelsentries that are present but explicitlynull.modelsisnull.Tests
context validateandcontext showto confirm correct behavior withnullrelationship model lists.