3.2 KiB
REVIEW-lex — Adversary Verdicts
Legend
- PASS @ — gate accepted, evidence below
- FAIL — repro steps below, Builder must fix
D1 — numbers
PASS @2026-06-15T00:36Z
Cold run evidence:
python -c "...tokenize('42')..." → NUMBER(42, int), EOF — PASS
python -c "...tokenize('3.14')..." → NUMBER(3.14, float), EOF — PASS
python -c "...tokenize('.5')..." → NUMBER(0.5), EOF — PASS
python -c "...tokenize('10.')..." → NUMBER(10.0), EOF — PASS
Type assertions: isinstance(42, int) ✓, isinstance(3.14, float) ✓
D2 — operators & parens
PASS @2026-06-15T00:36Z
Cold run evidence:
tokenize('1+2*3') kinds → ['NUMBER','PLUS','NUMBER','STAR','NUMBER','EOF'] ✓
tokenize('3.5*(1-2)') → [('NUMBER', 3.5), ('STAR', '*'), ('LPAREN', '('), ('NUMBER', 1), ('MINUS', '-'), ('NUMBER', 2), ('RPAREN', ')'), ('EOF', None)] ✓
All 6 operators (PLUS MINUS STAR SLASH LPAREN RPAREN) individually tested ✓
SLASH explicitly tested in test_lexer.py ✓
D3 — whitespace & errors
PASS @2026-06-15T00:36Z
Cold run evidence:
tokenize(' 12 + 3 ') kinds → ['NUMBER','PLUS','NUMBER','EOF'] ✓
tokenize('1 @ 2') → raises calc.lexer.LexError: unexpected character '@' at position 2
'@' in message ✓, '2' (position) in message ✓
Plan's verbatim command exits code 1 with correct traceback ✓
Break-it probes run (see Adversary findings for non-blocking issues):
$raises LexError ✓x(letter) raises LexError ✓\nraises LexError (treated as invalid char, reasonable) ✓
D4 — tests green
PASS @2026-06-15T00:36Z
Cold run:
$ python -m unittest -q
----------------------------------------------------------------------
Ran 24 tests in 0.001s
OK
Exit code 0. 24/24 pass.
DoD-mandated test inputs confirmed present:
" 12 + 3 "— covered by test_spaces_between_tokens + test_padded_addition ✓"3.5*(1-2)"— covered by test_complex_expression + test_complex_with_values ✓"1 @ 2"raises LexError — covered by test_invalid_char_raises + test_lex_error_position ✓
Non-blocking finding: unhandled ValueError for malformed number literals
Severity: informational — does not fail any DoD gate
tokenize('1.2.3'), tokenize('.'), tokenize('..') all raise Python's built-in
ValueError ("could not convert string to float: ...") instead of LexError.
The lexer greedily consumes digit/dot sequences then passes the raw string to
float() without catching failure.
The DoD's D3 specifies "invalid character (e.g. @, $, a letter)" — not malformed
number literals — so this does not block PASS. However, downstream parser/evaluator
phases will see unexpected ValueError exceptions from edge-case inputs. The Builder
should consider wrapping the float(raw) call in a try/except that re-raises as
LexError.
This finding is noted only; the Builder may address it in a follow-up or the next phase. No VETO issued.
Summary
| Gate | Verdict |
|---|---|
| D1 — numbers | PASS |
| D2 — operators & parens | PASS |
| D3 — whitespace & errors | PASS |
| D4 — tests green | PASS |
All gates PASS. Builder may write "## DONE" to STATUS-lex.md.