Skip to content

feat(http-client-python): support P1 inline discriminated unions - #12285

Draft
Libba Lawrence (l0lawrence) wants to merge 1 commit into
microsoft:mainfrom
l0lawrence:python-inline-discriminated-unions
Draft

Libba Lawrence (l0lawrence) wants to merge 1 commit into
microsoft:mainfrom
l0lawrence:python-inline-discriminated-unions

Conversation

@l0lawrence

Copy link
Copy Markdown
Member

Summary

Implement the Python P1 inline discriminated-union shape described in Azure/typespec-azure#5703 (section 2). This is a scoped Python implementation, not a resolution of the complete cross-language issue.

  • Support @discriminated(#{ envelope: "none" }) on unions with an explicit model constraint and nominal model variants declaring matching required literal discriminator properties.
  • Preserve named Python union aliases and declared model inheritance. Generate Annotated[Union[...], _DiscriminatedUnion(...)] metadata for union-local deserialization rather than replacing the union with its base model or modifying shared model registrations.
  • Honor custom discriminator names and JSON wire names; reuse existing literal-field serialization for inline tags.
  • Handle operation request/response boundaries, model properties, optional/container uses, recursion, and cross-namespace aliases. Missing or unknown tags raise DeserializationError rather than selecting the first variant.
  • Preserve ordinary untagged unions, direct model behavior, and existing @discriminator hierarchies. Add regression coverage, README documentation, and a feature changelog.

Compatibility and scope

Installed TCGC 0.73.0 exposes discriminatedOptions but not SdkUnionType.baseType. Read the compiler's explicit Union.baseType constraint and match SDK model ancestry against it; do not infer a common ancestor. The sample requires the compiler's experimental union-extends feature.

Initial support targets the default DPG model mode and explicit-base nominal variants. P2 object envelopes, default variants, structural variants, unions without an explicit model constraint, and variants without matching literal tags are unsupported and receive an explicit diagnostic. Existing skipped envelope/Spector scenarios remain untouched.

Validation

  • Emitter TypeScript build and Python wheel build passed using installed dependencies (tsc and python -m build --wheel --no-isolation), avoiding dependency bootstrapping/downloads.
  • Emitter suite: 40 passed (vitest run --config emitter/vitest.config.ts --testTimeout 20000).
  • Focused Python suites: 103 passed, 1 deselected, including 26 new cases covering Azure/unbranded runtimes and generated fixtures.
  • Actual emitted/generated Azure and unbranded SDK smoke checks passed for synchronous and asynchronous requests/responses using mocked pipeline responses, including exact inline JSON, variant selection, containers, direct models, and unknown tags.
  • Emitter Oxlint, changed generator-source Pylint, package formatting, repository pnpm format, and git diff --check passed.

Baseline caveats

  • Deselected test_models_mode_typeddict_does_not_write_empty_models_folder: its existing model-package scaffolding failure was reproduced with baseline CombinedType from HEAD before implementation was committed.
  • Direct Pylint of the generated runtime reports pre-existing template findings; rendering and linting the baseline template reproduced the same findings and 9.92/10 score. No new runtime lint findings were observed.
  • No full monorepo build/test or live Spector-server run was performed; generated-client smoke checks mocked pipeline responses.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@microsoft-github-policy-service microsoft-github-policy-service Bot added the emitter:client:python Issue for the Python client emitter: @typespec/http-client-python label Oct 15, 2026
@pkg-pr-new

pkg-pr-new Bot commented Oct 15, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/http-client-python@12285

commit: 02672c4

@github-actions

Copy link
Copy Markdown
Contributor

Python emitter diff

Baseline gh:57c3a2200daf08f0c558b2ff11fdfd2f5aa353d3 vs this PR.

⚠️ emitter-diff failed (exit 1) — tool/build error, not a diff. See the run.

Informational check (eng/emitter-diff); does not block the PR.

@github-actions

Copy link
Copy Markdown
Contributor

All changed packages have been documented.

  • ✅ @typespec/http-client-python
Show changes

@typespec/http-client-python - feature ✏️

Support inline discriminated unions with an explicit model constraint and nominal,> model variants. Keep the named Python union alias and declared model inheritance,,> and deserialize responses and nested properties using the configured inline,> discriminator. Missing or unknown tags raise DeserializationError. Object,> envelopes and default variants are not supported.,> ,> tsp,> model PetBase { kind: string; name: string; },> model Cat extends PetBase { kind: "cat"; meows: boolean; },> model Dog extends PetBase { kind: "dog"; barks: boolean; },> @discriminated(#{ envelope: "none" }),> union Pet extends PetBase { cat: Cat, dog: Dog },>

@azure-sdk-automation

Copy link
Copy Markdown

You can try these changes here

🛝 Playground 🌐 Website 🛝 VSCode Extension

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:python Issue for the Python client emitter: @typespec/http-client-python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant