fix: render degenerate judge histograms instead of raising (#905) - #919
fix: render degenerate judge histograms instead of raising (#905)#919chethanuk wants to merge 2 commits into
Conversation
…Mo#905) DatasetProfilerResults.to_report() raised on four judge-profile shapes that model_validate() accepts, so a schema-valid analysis result could not be rendered. create_rich_histogram_table called max() on a bare mapping, so an empty categorical histogram raised ValueError one line before the existing max_count <= 0 guard. Its only caller passed a MissingValue straight through to .categories, and create_report_section indexed score_distributions.histograms[score_name] unguarded, so a missing score_distributions or a summary naming a score the histogram map omits raised AttributeError and KeyError. Guard all four at the shared points every caller routes through: max() takes default=0 and empty data renders a placeholder row, the histogram mapping is built empty for a MissingValue with the parameter widened to CategoricalHistogramData | MissingValue, and the per-score lookup falls back to MissingValue.CALCULATION_FAILED. CategoricalHistogramData's list constraints are left alone: adding min_length=1 would make CategoricalDistribution.from_series raise on an empty Series, which _load_stage_analysis catches and turns into None, trading a visible crash for a silently discarded analysis. Covered by parametrized tests driven through the public to_report() entry point both reporters used; they fail on unmodified main with the four exceptions above. Fixes NVIDIA-NeMo#905 Closes NVIDIA-NeMo#903 Signed-off-by: ChethanUK <chethanuk@outlook.com>
Linked Issue CheckIssue #905 has not been triaged yet. A maintainer needs to review You can continue working on the PR in the meantime. The check will |
|
All contributors have signed the DCO ✍️ ✅ |
|
How do I sign it? |
Instructions are here: #919 (comment) |
|
I have read the DCO document and I hereby sign the DCO. |
|
recheck |
nabinchha
left a comment
There was a problem hiding this comment.
Thanks for putting this together, @chethanuk!
Summary
This change makes judge-profile report generation tolerate the empty, missing, and incomplete histogram shapes accepted by the schema. The crash handling matches the PR's stated intent, but the new empty-state row needs one rendering correction before merge.
Findings
Warnings — Worth addressing
packages/data-designer-config/src/data_designer/config/utils/visualization.py:271 — Empty-state markup is rendered literally in saved reports
- What: The placeholder is added as the plain string
"[dim]no data[/dim]", whilegenerate_analysis_report()deliberately renders withmarkup=False. Through the publicDatasetProfilerResults.to_report()path, the saved HTML therefore contains and displays the literal text[dim]no data[/dim]rather than a dimmedno datalabel. - Why: The PR fixes the exceptions, but every repaired empty/missing-histogram case now produces visibly malformed report output on the exact path under test. The current tests miss this because they only check the report size and the value-column cells.
- Suggestion: Pass a styled renderable instead, e.g.
table.add_row(Text("no data", style="dim"), "")(Textis already imported), and extend the saved-report assertion to verify"no data"is present without the Rich control tags.
What Looks Good
- Putting
default=0on the shared histogram maximum handles empty input at the narrowest reusable boundary. - The
MissingValueunion and.get()fallback align report rendering with the shapes the Pydantic models already accept, without tightening the serialized schema. - The parametrized public-path tests cover empty, missing, incomplete, and populated cases, and the full config suite remains green.
Verdict
Needs changes — render the empty-state label with a Text object and lock the saved output down with an assertion so the repaired path does not expose Rich markup tags.
This review was generated by an AI assistant.
Summary
DatasetProfilerResults.to_report()raises on four judge-profile shapes thatmodel_validate()accepts, so a schema-valid analysis result cannot be rendered. All four are one crash family on one render path (create_rich_histogram_tableand its two callers), so they're fixed together.Related Issue
Fixes #905
Closes #903
Changes
create_rich_histogram_table(config/utils/visualization.py):max(data.values())raisedValueErroron an empty mapping, one line before the existingmax_count <= 0guard that already handled "nothing to draw". Changed tomax(data.values(), default=0), and an empty mapping now renders ano dataplaceholder row instead of an empty table.create_judge_score_summary_table(config/analysis/utils/reporting.py): took a histogram by attribute (histogram.categories), so aMissingValue— which the field is typed to allow — raisedAttributeErrora frame earlier than the fix above. Parameter widened toCategoricalHistogramData | MissingValue; aMissingValuenow builds an empty mapping instead.JudgeScoreProfilerResults.create_report_section(config/analysis/column_profilers.py): indexedself.score_distributions.histograms[score_name]unguarded, whilescore_distributionsis itself typed... | MissingValue— raisingAttributeErrorwhen missing andKeyErrorwhen a summary names a score the histogram map omits. Both now fall back toMissingValue.CALCULATION_FAILED, which the guard above renders.CategoricalHistogramData's list constraints. Addingmin_length=1would makeCategoricalDistribution.from_seriesraise on an empty Series, which_load_stage_analysiscatches and turns intoNone— trading a visible crash for a silently discarded analysis.Testing
to_report()entry point both reporters used. On unmodifiedmainwith the tests applied:5 failed, 58 passed—ValueErroratvisualization.py:265,AttributeErroratreporting.py:174,AttributeErrorandKeyErroratcolumn_profilers.py:146, matching both issues verbatim.63 passed.uv run --group dev pytest packages/data-designer-config/tests→652 passed(main: 644; the +8 is exactly the new cases).uv run --group dev pytest packages/data-designer-engine/tests→2257 passed.make check-all-fixclean, tree unmodified.Checklist