Skip to content

feat(statements)!: make pre-IPO stub-quarter statement amounts optional - #386

Merged
benbenbang merged 2 commits into
mainfrom
feat/368-stmt-a-nullable
Sep 30, 2026
Merged

benbenbang merged 2 commits into
mainfrom
feat/368-stmt-a-nullable

Conversation

@benbenbang

Copy link
Copy Markdown
Member

FMP sends null for many balance-sheet and cash-flow amounts on pre-IPO stub quarters, which previously caused those records to be rejected during decoding. This change makes the affected amounts optional so those rows decode cleanly, while keeping the same amounts mandatory outside the stub set.

  • Wrap 38 balance-sheet and 19 cash-flow stub-quarter amounts in optional types across the Rust responses, Python bindings, and Go SDK, decoding null as None/nil and re-encoding as null.
  • Deserialize the Rust fields through a required_option helper and serialize via integral_f64::serialize_option; shadow Go fields through a jsontext.Value member to map JSON null to nil.
  • Update the Python get fields, constructor parameters, and regenerated .pyi stubs to Optional[float].
  • Extend tests across all crates to cover the full stub-null member sets decoding to None, re-encoding to null, rejecting null on non-stub amounts, and rejecting a missing required stub amount key.

BREAKING CHANGE: 57 BalanceSheetStatement and CashFlowStatement amounts are now optional (Option / pointer / Optional); callers must handle the absent case.

Make 57 BalanceSheetStatement and CashFlowStatement amounts optional so
pre-IPO stub quarters that FMP sends as null decode cleanly instead of
being rejected. Amounts that appear only on those stub rows now decode as
None and re-encode as null, while amounts outside that set still reject a
null value.

**Response models (libfmp):**
* Wrap the 38 balance-sheet and 19 cash-flow stub-quarter amounts in
  `Option<StatementAmount>`, deserializing through a `required_option`
  helper and serializing via `integral_f64::serialize_option`.
* Add response tests covering the full stub-null member sets, decoding to
  `None`, re-encoding to null, and rejecting null on non-stub amounts.

**Python bindings (fmp-py):**
* Change the corresponding `#[pyo3(get)]` fields and constructor
  parameters to `Option<f64>` and regenerate the `.pyi` stubs as
  `typing.Optional[builtins.float]`.

**Go SDK:**
* Switch the affected model fields to `*float64`, decode each through a
  `jsontext.Value` shadow member, and treat a JSON null as nil.

**Tests:**
* Update balance and cash-flow assertions to `Some(...)` / pointer form
  and add stub-quarter null decode/re-encode coverage across crates.

BREAKING CHANGE: 57 BalanceSheetStatement and CashFlowStatement amounts
are now optional (Option / pointer / Optional); callers must handle None.
Add a test to the cash flow statement response suite that removes the
`stockBasedCompensation` key from a historical record and asserts that
deserialization fails with an error mentioning the missing field. This
ensures required stub amount keys remain mandatory during parsing.
@benbenbang
benbenbang enabled auto-merge (rebase) September 30, 2026 12:55
@github-actions github-actions Bot added the enhancement New feature or request label Sep 30, 2026
@benbenbang
benbenbang merged commit 854e198 into main Sep 30, 2026
9 checks passed
@benbenbang
benbenbang deleted the feat/368-stmt-a-nullable branch September 30, 2026 13:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant