Add discriminated union serialization tests - #1860
Conversation
Tests discriminated union type shapes for both request-side (TypedDict params with Literal discriminator) and response-side (StripeObject deserialization), covering standalone and inline variants. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
There was a problem hiding this comment.
Pull request overview
Adds a new test module intended to validate “discriminated union” payload shapes, covering both request-style dict params (TypedDict + Literal discriminator) and response-style StripeObject construct/to_dict round-trips.
Changes:
- Introduces standalone and inline discriminator “union” examples via
TypedDictvariants. - Adds runtime tests for discriminator field presence/access on dict params and
StripeObjectinstances. - Adds round-trip checks ensuring discriminator fields survive
construct_from(...).to_dict().
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| params: RgbColorParams = {"model": "rgb", "r": 200, "g": 100, "b": 50} | ||
| # Simulating what the SDK does when encoding params for an API request. | ||
| serialized = dict(params) |
There was a problem hiding this comment.
Fixed — updated the comment to clarify that this tests runtime dict semantics (discriminator and variant fields survive a shallow copy), not the full SDK encoding pipeline.
| """ | ||
| Tests for discriminated union type shapes. | ||
|
|
||
| Covers both sides of the API boundary: | ||
| - Request side: TypedDict params with Literal discriminator fields | ||
| - Response side: StripeObject deserialization from JSON with a discriminator | ||
|
|
||
| Two structural patterns are tested: | ||
| - Standalone union: the discriminated union is its own type (e.g. ColorParams) | ||
| - Inline union: the discriminator lives at the parent object level (e.g. shape.type) | ||
| """ |
There was a problem hiding this comment.
Good catch — updated the module docstring to explicitly state these tests exercise runtime semantics only, not static type narrowing.
There was a problem hiding this comment.
yeah this was basically going to be my comment. We have some other types test in the repo already!
The module docstring now explicitly states these tests exercise runtime semantics (dict construction, field access, round-trip), not static type narrowing. The dict() comment explains what it's actually testing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
…ar/discriminated-unions
xavdid
left a comment
There was a problem hiding this comment.
commented - but this isn't really testing types yet
Inline union tests now use the flattened TypedDict pattern (discriminator and per-variant payload fields on the parent) rather than the incorrect per-variant TypedDicts-with-type-field pattern that was there before. Request-side tests now exercise `_api_encode` so they verify real SDK encoding behavior (bracket notation, nested dicts) rather than just dict construction and key lookup. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
Why?
Validates that the discriminated union serialization design works correctly in stripe-python before codegen produces these patterns. Exercises both request-side (params encoding via
_api_encode) and response-side (StripeObject.construct_fromdeserialization).What?
tests/test_discriminated_unions.pywith 29 tests covering:Literal["value"]discriminator field, encoded via_api_encodeverifying correct bracket-notation output (color[model]=rgb,color[r]=255)PaymentParamsTypedDict with discriminator + per-variant nullable payload fields (matchingflattenDiscriminatedUnionFieldsoutput), encoded via_api_encodeverifying top-level discriminator + nested payload keysStripeObject.construct_fromwith flat JSON, verifying discriminator and payload field access via attribute and bracket notationStripeObject.construct_fromwith nested JSON ({"type": "card", "card": {"number": "4242"}}), verifying recursive StripeObject deserialization of variant payloads_api_encodefor request direction,construct_from+to_dictfor response direction