Adds 6 tests covering Page[T] DataFrame conversion when T has nested
Pydantic sub-models and list[Decimal] fields. Pins the current
model_dump(mode="python") contract so a future flip to mode="json", or
a pandas/polars upgrade that changes nested-cell inference, fails CI
instead of silently breaking downstream Decimal arithmetic.
Pinned behavior:
- pandas: nested model -> object column holding raw dict (Decimals
preserved inside); list[Decimal] -> object column holding list of
Decimal.
- polars: nested model -> Struct column; list[Decimal] -> List(Decimal)
column.
- Top-level Decimal stays Decimal in both backends even when nested
columns share the frame.
Closes #101
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Wave 2 #101: pins the behavior of
Page.to_dataframe()/Page.to_polars()for nested-Pydantic-model fields, so a future pandas/polars upgrade can't silently change how nested structures land in cells.6 new tests in `tests/test_page_dataframe.py` (12 total in this file now).
Observed behavior (now pinned)
pandas
to_dataframe():objectcolumn; each cell is the rawdictfrommodel_dump(mode="python")(NOT expanded toinner.*columns, NOT stringified)list[Decimal]→objectcolumn holding Pythonlist[Decimal]Decimalvalues stayDecimal(mode="python" contract held)polars
to_polars():Structcolumn (auto-inferred from dict shape); cell round-trips todictwith original typeslist[Decimal]→List(Decimal(precision=38, scale=N))columnDecimaldtypeNo bug in
Page. R-08 perf observation (intermediate dict allocations) noted in the issue body but out of scope for this PR.Closes #101
Test plan
uv run pytest tests/test_page_dataframe.py -q— 12 passed (was 6)uv run ruff check .cleanuv run mypy kalshi/clean