Skip to content

[python] gate TypedDict body overloads behind models-mode typeddict#6

Closed
l0lawrence wants to merge 1 commit into
addtypeddict-basefrom
l0lawrence-cuddly-telegram
Closed

[python] gate TypedDict body overloads behind models-mode typeddict#6
l0lawrence wants to merge 1 commit into
addtypeddict-basefrom
l0lawrence-cuddly-telegram

Conversation

@l0lawrence

Copy link
Copy Markdown
Owner

Why

Stacked on microsoft#10439 (iscai-msft:python/addTypedDict). That PR introduced models-mode: typeddict, but it also turned on part of the TypedDict machinery in the default dpg mode: the preprocessor inserted a TypedDict body overload for every dpg-model body. For mgmt/autorest-sourced libraries the matching TypedDict was never rendered into types.py, so generated operations ended up annotated as:

body: Union[_models.CacheUpdate, _types.CacheUpdate, IO[bytes]]

and importing the module blew up at runtime:

AttributeError: module 'azure.mgmt.netapp.types' has no attribute 'CacheUpdate'

This regressed azure-mgmt-netapp (breaking-change check failure).

What changed

Scope the TypedDict body overload insertion to models-mode: typeddict only, in PreProcessPlugin.add_body_param_type:

  • dpg mode (default): restored the historical behavior of accepting either the generated model or a raw JSON object (any-object). No _types.X reference is emitted, so there is nothing to dangle.
  • typeddict mode: unchanged. Plain model bodies collapse to the single _types.X TypedDict; spread (json-base) bodies still get their TypedDict overload.

Because no TypedDict copies are inserted in dpg mode, is_typed_dict_only stays False, types.py is not generated, and no _types.X references can be produced.

Notes for reviewers

  • The bulk of the file list belongs to the underlying [python] add typeddict models-mode for Python HTTP client emitter microsoft/typespec#10439; the substantive change here is confined to generator/pygen/preprocess/__init__.py, its overload regression tests, and the changelog wording.
  • Verified at the preprocess level:
    • dpg -> body members ['dpg', 'any-object', 'binary'], no typeddict copy in the type list
    • typeddict -> collapses to single _types.X
  • Added test_dpg_mode_emits_no_typeddict_reference and updated the dpg regression guard. All 16 typeddict unit tests pass; the broader codegen unit suite is green.
  • Changelog updated to state that TypedDict generation is scoped to models-mode: typeddict (was "Always generate...").

…mode typeddict

In dpg mode the preprocessor inserted a TypedDict body overload (_types.X) for every dpg-model body, but the matching TypedDict was never rendered into types.py for mgmt/autorest libraries. This produced Union[_models.X, _types.X, IO[bytes]] annotations that failed at import time with AttributeError: module '...types' has no attribute 'X'.

Restore the historical dpg-mode behavior (accept the model or a raw JSON object via any-object) and only insert TypedDict body overloads when models-mode is typeddict. Update the overload regression tests and changelog accordingly.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@l0lawrence l0lawrence changed the base branch from main to addtypeddict-base July 2, 2026 21:53
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

❌ There is undocummented changes. Run chronus add to add a changeset or click here.

The following packages have changes but are not documented.

  • typespec-vs

The following packages have already been documented:

  • @typespec/compiler
  • @typespec/emitter-framework
  • @typespec/html-program-viewer
  • @typespec/http-canonicalization
  • @typespec/http-client-java
  • @typespec/http-client-python
  • @typespec/http-client
  • @typespec/http-server-csharp
  • @typespec/http-server-js
  • @typespec/http-specs
  • @typespec/openapi3
  • @typespec/playground
  • @typespec/spec-api
  • @typespec/spector
  • @typespec/tspd
  • typespec-vscode
Show changes

@typespec/http-client-java - internal ✏️

Ignore modifications to META-INF metadata.json files

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

Add mock API test cases for encode/duration lossy scenarios (int32-seconds and int32-milliseconds) verifying that durations with fractional precision are serialized as integers

@typespec/http-specs - internal ✏️

Add encode/duration lossy Spector scenarios verifying a duration whose value carries more precision than the target integer encoding (fractional seconds and sub-millisecond milliseconds) is serialized as an integer

@typespec/compiler - feature ✏️

Allow @encode(string) on boolean targets, define case-insensitive true/false string semantics, and add shared case-insensitive string matcher support with encode/boolean Spector coverage.,> ,> tsp,> model FeatureFlags {,> @encode(string),> enabled: boolean;,> },>

@typespec/spec-api - feature ✏️

Allow @encode(string) on boolean targets, define case-insensitive true/false string semantics, and add shared case-insensitive string matcher support with encode/boolean Spector coverage.,> ,> tsp,> model FeatureFlags {,> @encode(string),> enabled: boolean;,> },>

@typespec/http-specs - feature ✏️

Allow @encode(string) on boolean targets, define case-insensitive true/false string semantics, and add shared case-insensitive string matcher support with encode/boolean Spector coverage.,> ,> tsp,> model FeatureFlags {,> @encode(string),> enabled: boolean;,> },>

@typespec/html-program-viewer - internal ✏️

Data decorators

@typespec/compiler - feature ✏️

Added auto decorator modifier for declaring decorators that auto-store their arguments as metadata without requiring a JavaScript implementation.,> ,> typespec,> auto dec label(target: Model, value: valueof string);,> ,> @label("my-model"),> model Foo {},> ,> ,> Added compiler API hasAutoDecorator, getAutoDecoratorValue, and getAutoDecoratorTargets for reading auto decorator values by FQN.

@typespec/tspd - feature ✏️

tspd gen-extern-signature now generates typed accessor functions for auto decorators (e.g., isMyFlag, getMyLabel).

@typespec/compiler - fix ✏️

Keep the is/extends keyword on the declaration line when the base is a template reference with multiple arguments. The template argument list now controls the line breaking instead of the keyword being pushed onto its own indented line.

@typespec/http-client-java - internal ✏️

Reformat a test spec affected by the compiler formatter change keeping is/extends inline for multi-argument template references (whitespace only, no semantic change).

@typespec/compiler - fix ✏️

Fix formatter inserting a blank line and over-indenting a union expression used directly as one of multiple template arguments (e.g. PickProperties<Source, "a" | "b">)

@typespec/http-client-java - internal ✏️

Reformat union template arguments in test files to match updated formatter style.

@typespec/http-client-java - fix ✏️

Fix null LRO error response body handling in generated management clients.

@typespec/compiler - internal ✏️

Fix formatter regression where a union used as a named template argument lost its leading | indentation

@typespec/openapi3 - fix ✏️

Fix OpenAPI import to emit @cookie decorators for cookie parameters, including nullable and type-null schema variants.

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

Fix invalid lone @overload generated for body parameters in models-mode: typeddict. When the binary and JSON overloads are omitted, the single remaining body variant is now emitted as a plain parameter instead of a single @overload, which mypy rejects with "Single overload definition, multiple required".

@typespec/http-client-java - internal ✏️

Add e2e tests for parameters/body-root, parameters/query special char, type/model/inheritance/single-discriminator no-subtypes, azure/resourcemanager/common-properties arm-resource-identifiers, and azure/resourcemanager/management-group scenarios

@typespec/http-client-java - dependencies ✏️

Update Node.js dependencies to latest (compiler 1.13.0, TCGC 0.69.0, azure-core 0.69.0) and bump version to 0.9.0

@typespec/http-client-java - fix ✏️

Fix duplicate method in generated samples, when advanced-versioning=true

@typespec/http-client-java - dependencies ✏️

Update Node.js dependencies: @azure-tools/typespec-autorest 0.69.1, @azure-tools/typespec-azure-resource-manager 0.69.1, @azure-tools/typespec-azure-rulesets 0.69.1, @microsoft/api-extractor 7.58.9, @types/node 25.9.3, @vitest/coverage-v8 4.1.9, @vitest/ui 4.1.9, vitest 4.1.9

@typespec/http-specs - fix ✏️

Fix the dollar-sign query scenario route to match the mock API.

@typespec/http-specs - fix ✏️

Fix the swapped mock api uris for the Routes_fixed and Routes_InInterface scenarios so they match the routes defined in the spec.

@typespec/openapi3 - feature ✏️

Add opt-in enum-strategy emitter option to emit TypeSpec enums as annotated enumerations (a oneOf of const subschemas with per-member title/description). Supported for OpenAPI 3.1.0 and above; emitting with OpenAPI 3.0.0 falls back to the default form and reports a warning.,> ,> yaml,> options:,> "@typespec/openapi3":,> enum-strategy: annotated,> ,> ,> For example, the following TypeSpec:,> ,> typespec,> /** Type of pet. */,> enum PetType {,> /** A loyal canine companion. */,> @summary("Dog"),> Dog: "dog",,> ,> /** A self-sufficient feline. */,> @summary("Cat"),> Cat: "cat",,> },> ,> ,> emits:,> ,> yaml,> PetType:,> description: Type of pet.,> oneOf:,> - const: dog,> title: Dog,> description: A loyal canine companion.,> - const: cat,> title: Cat,> description: A self-sufficient feline.,>

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

updating package-lock

@typespec/playground - feature ✏️

Make the raw tspconfig.yaml editor the source of truth so manual edits (comments, output-dir, warn-as-error, ordering and any unknown fields) are preserved instead of being reverted, compile by resolving the written tspconfig.yaml natively, and add language-server completion to the config editor.

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

Add skill for generate-from-typespec, to test generation of local tsp emitter against specs

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

[python] Add a models-mode: typeddict option that generates TypedDict typing hints for input models in the types.py file. Also generate named union aliases in the _unions.py file (renamed from _types.py). TypedDict generation is scoped to models-mode: typeddict; the default dpg mode output is unchanged.

@typespec/spector - fix ✏️

validate-mock-apis now verifies that every route defined in a scenario's main.tsp is served by at least one of the scenario's mock API uris, so a mismatch between the spec route and the mock api uri (which would make a generated client get a 404 from the mock server) is detected by CI.

@typespec/http-server-csharp - fix ✏️

Update the union definition to include unnamed string literals and null

@typespec/compiler - feature ✏️

Dim unused #suppress directives for available compiler and library diagnostics in editor scenarios.,> ,> typespec,> #suppress "deprecated" "old suppression",> model Widget {},>

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

Update js-yaml dependency to ^4.2.0

@typespec/http-client-java - dependencies ✏️

Update js-yaml dependency to ^4.2.0

@typespec/compiler - internal ✏️

Update dependencies

@typespec/emitter-framework - internal ✏️

Update dependencies

@typespec/html-program-viewer - internal ✏️

Update dependencies

@typespec/http-canonicalization - internal ✏️

Update dependencies

@typespec/http-client - internal ✏️

Update dependencies

@typespec/http-server-js - internal ✏️

Update dependencies

@typespec/playground - internal ✏️

Update dependencies

typespec-vscode - internal ✏️

Update dependencies

@l0lawrence l0lawrence closed this Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant