Commit ce593cd
authored
* refactor(workflows): let the evaluator report its own leaves (#4274)
_unresolvable_term answered one question -- does every operand in this
condition resolve to something? -- by walking the expression itself:
filters, then or/and/not, then comparisons, then list literals, down to
the leaves. That walk was a second implementation of the parsing in
_evaluate_simple_expression, kept in step with it by hand.
Two helpers existed only to restate rules the evaluator already had.
_looks_numeric mirrored the float()-only-when-a-dot-is-present rule
because a bare float() accepts 1e3 and the evaluator does not.
_is_literal mirrored the matching-close-is-the-final-character string
test because startswith/endswith accepts 'a' 'b' and the evaluator does
not. Both docstrings said "mirror the evaluator exactly", which is the
tell: when the two drift nothing breaks loudly, the gate just answers
wrongly, and the wrong answer is a paste-ready correction that inverts a
condition.
Seven of the nine findings in #4230 were the same defect wearing
different clothes -- the gate disagreeing with the evaluator about where
the operands are. Each round fixed one shape. Nothing stopped a tenth.
_evaluate_simple_expression has exactly one place where a substring stops
being grammar and becomes a name to resolve: its final line,
_resolve_dot_path. Literals return before it; operands, filter arguments
and list elements all arrive there by construction. Record the leaf
there, behind a ContextVar that is None outside a probe, and the gate
applies namespace rules to that list instead of re-deriving it. It now
contains no grammar at all.
Two properties this rests on, both asserted rather than assumed:
* or/and are not short-circuited -- both sides are evaluated and only
then combined -- so a leaf is recorded whatever the other side is
worth. If that ever changes the gate would go quietly blind, so
there is a test for it.
* A probe run can raise on its own placeholder values. The leaves seen
before that point are real, so they are kept rather than discarded;
discarding them would lose `bogus` in `inputs.tags | join(bogus)`,
which an earlier round of #4230 had to add by hand.
expressions.py is 109 lines lighter and 84 heavier. All 336 existing
tests pass unchanged, including the 20 cases of
test_operands_must_be_literals_or_known_paths that took eight rounds to
get right. test_literal_test_mirrors_the_evaluator tested the mirror, so
it becomes test_literal_handling_comes_from_the_evaluator and asserts the
same knowledge about 1e3 and 'a' 'b' through the gate instead.
Four mutations, each killed by the tests that should kill it -- removing
the leaf report alone turns 38 red. ruff 0.15.0 clean.
* refactor(workflows): let _resolve_dot_path define the indexed segment
The gate no longer restates the operator grammar, but it still restated
the shape of a path segment: _PATH_SEGMENT and an inline fullmatch both
described the index form that _resolve_dot_path matches with its own
regex. Three copies of one rule, kept in step by hand -- the same drift
this refactor set out to remove, one layer down.
Name the form once as _INDEXED_SEGMENT beside _resolve_dot_path and have
the gate ask it. Behaviour is unchanged: the regex is copied verbatim.
What changes is that widening indexing now reaches the gate for free.
* test(workflows): pin that the gate reads the evaluator's definitions
Two regression tests for the property this refactor is for, both of which
a second copy of the grammar in the gate would break while every existing
test stayed green:
- widening _INDEXED_SEGMENT alone reaches the gate (the negative-index
shape from #4416)
- when the evaluator stops treating something as a leaf, the gate stops
checking it, with no gate edit (the grouped-operand shape from #4417)
Both were checked by reintroducing the drift: giving the gate its own
segment regex again fails the first with the real message rather than an
import error.
* fix(workflows): keep collecting leaves after a probe error
The refactor stopped the leaf walk at the first exception a probe value
raised, so every leaf further along the chain was lost. That is the one
thing the collection exists to report, and it was a step backwards from
the hand-written walk this PR replaces:
inputs.blob | from_json | contains(bogus)
origin/main reports 'bogus'
this PR before the fix MISSED
this PR after the fix reports 'bogus'
from_json receives the probe placeholder mapping and raises; the walk ended
there and contains(bogus) was never reached.
Carry on past a failing filter while the sink is armed. _apply_filter
evaluates a filter argument before it can raise on the value, so the failing
segment's own leaves are already recorded; a fresh placeholder goes into the
next filter, matching what the probe namespace hands out.
Scoped to the probe: the sink is armed only by _collect_leaves, and
_evaluator_rejects runs its own probe without it, so a mis-wired filter is
still rejected and a real evaluation still raises rather than quietly
returning the unfiltered value.
1 parent 7cb2c7d commit ce593cd
2 files changed
Lines changed: 264 additions & 116 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
| |||
134 | 135 | | |
135 | 136 | | |
136 | 137 | | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
137 | 147 | | |
138 | 148 | | |
139 | 149 | | |
| |||
143 | 153 | | |
144 | 154 | | |
145 | 155 | | |
146 | | - | |
| 156 | + | |
147 | 157 | | |
148 | 158 | | |
149 | 159 | | |
| |||
479 | 489 | | |
480 | 490 | | |
481 | 491 | | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
482 | 497 | | |
483 | 498 | | |
484 | 499 | | |
| |||
545 | 560 | | |
546 | 561 | | |
547 | 562 | | |
| 563 | + | |
548 | 564 | | |
549 | | - | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
550 | 584 | | |
551 | 585 | | |
552 | 586 | | |
| |||
627 | 661 | | |
628 | 662 | | |
629 | 663 | | |
630 | | - | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
631 | 670 | | |
632 | 671 | | |
633 | 672 | | |
| |||
1047 | 1086 | | |
1048 | 1087 | | |
1049 | 1088 | | |
1050 | | - | |
1051 | | - | |
| 1089 | + | |
| 1090 | + | |
| 1091 | + | |
1052 | 1092 | | |
1053 | 1093 | | |
1054 | 1094 | | |
| |||
1097 | 1137 | | |
1098 | 1138 | | |
1099 | 1139 | | |
1100 | | - | |
1101 | | - | |
1102 | | - | |
1103 | | - | |
1104 | | - | |
1105 | | - | |
1106 | | - | |
1107 | | - | |
1108 | | - | |
1109 | | - | |
1110 | | - | |
1111 | | - | |
1112 | | - | |
1113 | | - | |
1114 | | - | |
1115 | | - | |
1116 | | - | |
| 1140 | + | |
| 1141 | + | |
1117 | 1142 | | |
1118 | | - | |
1119 | | - | |
| 1143 | + | |
| 1144 | + | |
| 1145 | + | |
| 1146 | + | |
| 1147 | + | |
1120 | 1148 | | |
1121 | | - | |
1122 | | - | |
1123 | | - | |
| 1149 | + | |
| 1150 | + | |
| 1151 | + | |
| 1152 | + | |
| 1153 | + | |
1124 | 1154 | | |
1125 | | - | |
1126 | | - | |
1127 | | - | |
1128 | | - | |
| 1155 | + | |
| 1156 | + | |
| 1157 | + | |
| 1158 | + | |
| 1159 | + | |
| 1160 | + | |
| 1161 | + | |
| 1162 | + | |
| 1163 | + | |
| 1164 | + | |
| 1165 | + | |
1129 | 1166 | | |
1130 | | - | |
1131 | | - | |
1132 | 1167 | | |
1133 | | - | |
1134 | | - | |
1135 | | - | |
| 1168 | + | |
| 1169 | + | |
1136 | 1170 | | |
1137 | | - | |
1138 | | - | |
1139 | | - | |
1140 | | - | |
1141 | | - | |
| 1171 | + | |
| 1172 | + | |
1142 | 1173 | | |
1143 | | - | |
1144 | | - | |
1145 | | - | |
1146 | | - | |
1147 | | - | |
1148 | | - | |
1149 | | - | |
1150 | | - | |
1151 | | - | |
1152 | | - | |
1153 | | - | |
1154 | | - | |
1155 | | - | |
1156 | | - | |
1157 | | - | |
1158 | | - | |
1159 | | - | |
1160 | | - | |
1161 | | - | |
1162 | | - | |
1163 | | - | |
1164 | | - | |
1165 | | - | |
1166 | | - | |
1167 | | - | |
1168 | | - | |
1169 | | - | |
1170 | | - | |
1171 | | - | |
1172 | | - | |
1173 | | - | |
1174 | | - | |
1175 | | - | |
1176 | | - | |
1177 | | - | |
1178 | | - | |
1179 | | - | |
1180 | | - | |
1181 | | - | |
1182 | | - | |
1183 | | - | |
1184 | | - | |
1185 | | - | |
1186 | | - | |
1187 | | - | |
1188 | | - | |
1189 | | - | |
1190 | | - | |
1191 | | - | |
1192 | | - | |
1193 | | - | |
1194 | | - | |
1195 | | - | |
1196 | | - | |
1197 | | - | |
1198 | | - | |
1199 | | - | |
1200 | | - | |
1201 | | - | |
1202 | | - | |
1203 | | - | |
1204 | | - | |
1205 | | - | |
1206 | | - | |
1207 | | - | |
1208 | | - | |
| 1174 | + | |
| 1175 | + | |
| 1176 | + | |
1209 | 1177 | | |
1210 | 1178 | | |
1211 | 1179 | | |
1212 | 1180 | | |
1213 | 1181 | | |
1214 | 1182 | | |
1215 | 1183 | | |
1216 | | - | |
| 1184 | + | |
1217 | 1185 | | |
1218 | 1186 | | |
1219 | 1187 | | |
| |||
1222 | 1190 | | |
1223 | 1191 | | |
1224 | 1192 | | |
1225 | | - | |
| 1193 | + | |
1226 | 1194 | | |
1227 | 1195 | | |
1228 | 1196 | | |
1229 | 1197 | | |
| 1198 | + | |
| 1199 | + | |
| 1200 | + | |
| 1201 | + | |
| 1202 | + | |
| 1203 | + | |
| 1204 | + | |
| 1205 | + | |
| 1206 | + | |
| 1207 | + | |
| 1208 | + | |
| 1209 | + | |
| 1210 | + | |
| 1211 | + | |
| 1212 | + | |
| 1213 | + | |
| 1214 | + | |
| 1215 | + | |
| 1216 | + | |
| 1217 | + | |
| 1218 | + | |
| 1219 | + | |
| 1220 | + | |
| 1221 | + | |
| 1222 | + | |
| 1223 | + | |
| 1224 | + | |
1230 | 1225 | | |
1231 | 1226 | | |
1232 | 1227 | | |
| |||
0 commit comments