perps: align list-envelope null-handling with prediction (NullableList)#420
Conversation
Follow-up to #418/#419. The perps list-response envelopes (markets/funding) used a non-nullable list — hard-failing on a null array per #404's strict wording — while the prediction envelopes (#419) use NullableList (null -> []). This restores the pre-#418 `or []` null tolerance and makes null-handling identical across both surfaces. `GetMarginMarketsResponse.markets`, `GetMarginMarketCandlesticksResponse.candlesticks`, `GetMarginHistoricalFundingRatesResponse.funding_rates`, and `GetMarginFundingHistoryResponse.funding_history` now use NullableList: a MISSING key still hard-fails (surfacing drift), a NULL array coerces to []. 3.2.0 is unreleased, so this refines the envelopes before release. Removed the now-unused `import builtins` from both model files. Tests updated: null -> [] instead of raising. mypy strict + ruff + 1140 perps/contract tests green.
Code Review — PR #420: perps list-envelope null-handling alignmentOverall verdict: LGTM with minor comments. The change is well-motivated, narrowly scoped, and the updated tests correctly verify the new semantics. Ready to merge modulo the nits below. What this PR doesSwitches four perps list-envelope fields from Code quality / conventions
TestsAll four modified fields now have explicit coverage for both paths:
Two minor observations:
Potential issues / risksNone. The spec-drift protection (missing key → Summary
The async gap is very low risk given shared model deserialization. If you want to keep the async coverage consistent with the sync tests, a quick 🤖 Reviewed with Claude Code |
Optional follow-up to #418 / #419: make perps and prediction list-envelope null-handling identical.
Why
nullarray raises (per resources: validate typed list-response envelopes for REQUIRED-array endpoints (perps + prediction) #404's strict "absent or null → raise" wording).NullableList(anullarray →[]), because the prediction API is documented to return null for empty required arrays.This left the two surfaces inconsistent. This PR aligns perps to
NullableList, which also restores the pre-#418or []null tolerance for these endpoints.Change
GetMarginMarketsResponse.markets,GetMarginMarketCandlesticksResponse.candlesticks,GetMarginHistoricalFundingRatesResponse.funding_rates,GetMarginFundingHistoryResponse.funding_history→NullableList:ValidationError(still surfaces drift — the resources: validate typed list-response envelopes for REQUIRED-array endpoints (perps + prediction) #404 goal);[](Kalshi's empty-as-null convention).3.2.0 is unreleased, so this refines the envelopes before they ship.
Verification
[](sync). Drift harness still passes (the field stays required).mypy --strict+ruffclean; 1140 perps + contract tests pass.🤖 Generated with Claude Code