fix(tables): finish GH-352 leftovers — shared column helper and scoreboard - #441
fix(tables): finish GH-352 leftovers — shared column helper and scoreboard#441r-uben wants to merge 1 commit into
Conversation
…board - Collapse _project_candidate_data_columns and _candidate_data_column_indices onto _candidate_data_column_indices as the single source of truth so the projected grid and bind() remap cannot drift apart. - Record model_unbound_nonempty on CoverageRecord and surface it on the whole-page #330 scoreboard summary (region-scoped already had it). PR #430 already landed the column_binding_unverifiable walk gate; left intact. Co-authored-by: Rubén Fernández-Fuertes <r-uben@users.noreply.github.com>
r-uben
left a comment
There was a problem hiding this comment.
MERGE (head 2d3d275, draft)
Both remaining #352 items land. The #430 walk gate is untouched. Does not close #352 — correct.
Helper. _candidate_data_column_indices is the sole numeric-column / widest-row-union implementation; _project_candidate_data_columns projects through that tuple. bind() already remapped via the index helper, so this is the desync hole, not a new bind() rewrite. test_projected_grid_columns_match_index_helper goes red if they drift. typecheck + test (3.11) green.
Scoreboard. CoverageRecord.model_unbound_nonempty is required (no default); _record sets it from result.model_unbound; whole-page summary_text prints model unbound non-empty: N/denominator. Reverting the print reddens test_whole_page_summary_includes_model_unbound_nonempty.
Nits (non-blocking)
test_coverage_record_carries_model_unbound_nonemptyis construct+assert. The load-bearing pin is the summary line + the required field on_record._aggregatefixture has flag andcount>0agreeing, so reverting the sum tomodel_unbound_count > 0stays green. Fine while_recordalways setsbool(result.model_unbound).test_widest_row_union_...never has a narrow-only column, so it does not prove “a narrower row must not pull.” The (1,3) projection fixture is the real pin.- Scoreboard print is pinned from a hand-built
CoverageReport; a live coverage run is nicer, not a closer.
Do not merge unless asked. Do not close #352 from this PR. #326/#322 stay closed.
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks 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 |
Summary
Completes the two remaining items on #352. PR #430 (
223727b) already landed thecolumn_binding_unverifiablewalk gate; this PR leaves that behavior intact.1. Single helper for projected grid + index remap
_candidate_data_column_indicesis now the sole implementation of the numeric-column / widest-row-union logic._project_candidate_data_columnsprojects through that tuple so a future tweak cannot silently desync the remap used inbind().2. Record
model_unbound_nonemptyon the #330 scoreboardCoverageRecordnow carries an explicitmodel_unbound_nonemptyboolean (alongsidemodel_unbound_count)._aggregatesums that flag.summary_textnow printsmodel unbound non-empty: N/denominatorunder Selected whole-page results, matching the feat(tables): candidate-to-native scoping and coverage — the binder cannot fully check any real table (blocks #326) #330 self-bind floor format (6/15in the dry-run log). Region-scoped output already had the field.Tests
New
tests/test_gh352_leftovers.py:_candidate_data_column_indices(including widest-row-union edge case)CoverageRecord.model_unbound_nonempty, aggregate counting, and whole-page summary lineExisting
tests/test_gh352_column_binding_verifiable.pyand binder tests still pass.Verification
Does not close #352 — ready for review/merge first.
Summary by cubic
Completes the remaining GH-352 leftovers: consolidates candidate column projection into a single helper so the projected grid and the
bind()remap can’t drift, and adds amodel_unbound_nonemptyflag to the coverage scoreboard.Changes
_project_candidate_data_columnsnow delegates to_candidate_data_column_indices; the remap inbind()uses the same tuple, preventing silent drift.CoverageRecordgains amodel_unbound_nonemptyboolean; aggregation uses it instead of re‑deriving from count.summary_textnow printsmodel unbound non-empty: N/denominator(region‑scoped already had it).tests/test_gh352_leftovers.pycovering projection consistency, remap stability, and the new scoreboard line.Written for commit 2d3d275. Summary will update on new commits.