fix(parsers): reject boolean values in accounting float coercion - #1055
Conversation
`bool` is a subclass of `int`, so `coerce_accounting_float`'s `isinstance(value, (int, float))` branch silently converted `True`/`False` to `1.0`/`0.0`. An accidental boolean flag in a workbook cell was therefore read as a dollar/notional amount instead of being rejected. Add an explicit `isinstance(value, bool)` guard at the top of the function that raises `ValueError`, and cover it with unit tests for both `strip_percent` branches plus a non-regression check that numeric 0/1 still coerce normally. Closes #1048 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Essentials Run ID: 📒 Files selected for processing (2)
Included review availability: 0 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour. 📝 WalkthroughWalkthroughThe XLSX accounting float coercion now rejects boolean inputs before numeric conversion. Tests cover both ChangesAccounting float validation
Priority: ➖ Normal Estimated code review effort: 1 (Trivial) | ~5 minutes Change: Bug fix · Severity of issue fixed: Medium Merge Risk: ⚪ Minimal · up to This change rejects boolean accounting values while preserving valid numeric zero and one handling, with regression coverage in place. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
Workflow state fingerprint for Keepalive Loop Reporter. Do not edit. |
🤖 Keepalive Loop StatusPR #1055 | Agent: Claude | Iteration 1/12 Current State
🔍 Failure Classification| Error type | infrastructure | |
Keepalive Work Log (click to expand)
|
|
Workflow state fingerprint for Agents Gate Followups. Do not edit. |
There was a problem hiding this comment.
🟢 Approval recommended
The fix and regression coverage address the issue with no unresolved comments.
Pull request overview
This pull request prevents Python booleans from being coerced into accounting amounts.
Changes:
- Rejects booleans with
ValueError. - Adds regression tests for booleans and numeric
0/1.
File summaries
| File | Summary |
|---|---|
tests/parsers/test_numeric.py |
Tests boolean rejection and numeric compatibility. |
src/counter_risk/parsers/_xlsx_reader.py |
Adds the boolean validation guard. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Runner dispatch state for claude on PR #1055. Do not edit. |
|
Autofix attempts exhausted for this head. Latest Gate summary: Please investigate manually. |
|
Autofix attempts exhausted for this head. Latest Gate summary: Please investigate manually. |
|
Closer disposition: removing Evidence (head The Cancelled is not failed. Enumerating every run on this exact head shows duplicate dispatches colliding in their concurrency groups:
Within So the retry counter tallied four "attempts" that were self-inflicted concurrency cancellations, exhausted its budget of 3, and asked for a human — two seconds before a fresh Gate ( What automation checked: every workflow run for this SHA and its conclusion; the job-level conclusions inside the cancelled Gate run; the full job log for Action taken: Left for the normal pipeline: if Underlying defect, recorded rather than fixed here (out of this lane's scope): a PR that triggers duplicate same-head dispatches can exhaust its autofix budget purely on concurrency cancellations and self-apply |
|
Pre-merge absent-check audit (mandatory rule), head The prescribed reporter could not be used: Result: no check that normally reports is absent on this head. #1055's check inventory is a structural superset of #1052's. Every job present-and-reporting there is present here, plus The Gate and the full Python CI matrix both reported SUCCESS on this exact unchanged head via Gate run 34700635780: Two names on this head carry a Remaining merge gates, all satisfied on this exact head: non-draft; in-scope agent issue work ( The full diff was read rather than trusted from the body: One note for whoever reads the keepalive summary: its "Tasks 0/5" figure is a counting artifact, not incomplete work. It counts the checkboxes in the generated Sequencing note: this audit was completed and the head re-read as |
Provider Comparison ReportProvider Summary
📋 Full Provider Details (click to expand)openai
anthropic
Agreement
DisagreementNo major disagreements detected. Unique Insights
🔍 LangSmith Traces |
|
Workflow state fingerprint for Agents Verifier. Do not edit. |
Summary
src/counter_risk/parsers/_xlsx_reader.pycoerce_accounting_floatmatched booleans on itsisinstance(value, (int, float))branch, becauseboolis a subclass ofint.coerce_accounting_float(True)returned1.0andcoerce_accounting_float(False)returned0.0, so an accidental boolean flag in a workbook cell was read as a dollar/notional amount instead of being rejected.This adds an explicit
isinstance(value, bool)guard at the top of the function that raisesValueError, and covers it with unit tests.Closes #1048
Tasks
src/counter_risk/parsers/_xlsx_reader.py, add explicit boolean rejection tocoerce_accounting_float— guard added at the top of the function (_xlsx_reader.py:174), raisingValueError("Boolean value is not a valid accounting number: ...")before theint/floatbranch is reached.tests/parsers/test_numeric.py, add unit tests verifyingcoerce_accounting_float(True)andcoerce_accounting_float(False)raiseValueError—test_coerce_accounting_float_rejects_booleans, plustest_coerce_accounting_float_rejects_booleans_under_strip_percent_false(the guard must not depend on thestrip_percentbranch) andtest_coerce_accounting_float_still_accepts_numeric_zero_and_one(non-regression for theint/floatpath the guard sits in front of).Acceptance Criteria
uv run pytest tests/parsers/test_numeric.py -qpasses; boolean values raiseValueErroron coercion — 12 passed in 0.18s (run aspython -m pytest tests/parsers/test_numeric.py -qagainst the repo's Python 3.12 environment withPYTHONPATH=src; module resolution verified to this worktree).Direct inspection confirms
coerce_accounting_float(True)raisesValueError:Deliberate-break gate: removed the boolean check from
coerce_accounting_float, reran the suite, restored, reran.test_coerce_accounting_float_rejects_booleansandtest_coerce_accounting_float_rejects_booleans_under_strip_percent_falsebothFailed: DID NOT RAISE ValueErrorThe gate is therefore non-vacuous: it fails when the behaviour is absent.
Regression / quality checks
pytest tests/parsers -q— 86 passed in 111.14s (whole parsers suite, no regression).black --checkon both changed files — unchanged.ruff checkon both changed files — all checks passed.mypy src/counter_risk/parsers/_xlsx_reader.py— Success: no issues found in 1 source file.Non-Goals
No changes to regex-based accounting string parsing. XLSX
t="b"cells are unaffected:cell_valuealready decodes them to the strings"TRUE"/"FALSE", which continue to take the existing string path. This PR only closes the Python-levelboolhole in front of the numeric branch.🤖 Generated with Claude Code
Closes #1048
Automated Status Summary
Scope
src/counter_risk/parsers/_xlsx_reader.py:171implementscoerce_accounting_float(value). In Python,isinstance(True, (int, float))evaluates toTrue. Becausecoerce_accounting_floatlacks an explicitisinstance(value, bool)check before checkingisinstance(value, (int, float)), boolean values are converted to numeric floats (coerce_accounting_float(True) == 1.0,coerce_accounting_float(False) == 0.0) instead of raisingValueError. This causes accidental boolean flags in Excel workbook cells to be parsed as numerical dollar/notional amounts.Tasks
src/counter_risk/parsers/_xlsx_reader.py, add explicit boolean rejection tocoerce_accounting_float.tests/parsers/test_numeric.py, add unit tests verifyingcoerce_accounting_float(True)andcoerce_accounting_float(False)raiseValueError.Acceptance criteria
uv run pytest tests/parsers/test_numeric.py -qpasses; boolean values raiseValueErroron coercion.coerce_accounting_float(True)raisesValueError.coerce_accounting_floatinsrc/counter_risk/parsers/_xlsx_reader.pyby removing the boolean check; boolean test must fail; restore and rerun.Summary by CodeRabbit
Bug Fixes
Tests