[python] add typeddict models-mode for Python HTTP client emitter#10439
Open
iscai-msft wants to merge 79 commits into
Open
[python] add typeddict models-mode for Python HTTP client emitter#10439iscai-msft wants to merge 79 commits into
models-mode for Python HTTP client emitter#10439iscai-msft wants to merge 79 commits into
Conversation
Add a new 'typeddict' value for the models-mode option that generates Python TypedDict classes instead of DPG model classes. Key features: - TypedDict classes with Required[T]/NotRequired[T] annotations - TypedDict inheritance for non-discriminated models - Discriminated models: Union of leaf TypedDicts, no abstract base class - Input-only: operations accept TypedDict input, return dict output - Wire names used as TypedDict keys - _model_base.py still generated for serialization utilities Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
commit: |
Contributor
|
All changed packages have been documented.
Show changes
|
Collaborator
|
You can try these changes here
|
…ypespec into python/addTypedDict
…hon/addTypedDict
- TypedDictModelType returns 'JSON' for response type annotations - Response.type_annotation/docstring passes is_response=True - Typeddict deserialization uses response.json() directly - Removed NotRequired from TypedDictModelSerializer (total=False handles it) - Updated mock API tests to verify JSON dict responses Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add client/naming typeddict variant to regenerate-common.ts - Create test_client_naming_typeddict.py with 11 tests verifying TypedDict uses wire names (defaultName, wireName) not client names - Tests cover: ClientNameModel, LanguageClientNameModel, ClientNameAndJsonEncodedNameModel, ClientModel, PythonModel Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
TypedDict is already JSON, so the MutableMapping[str, Any] overload is unnecessary. Only keep TypedDict model + IO[bytes] overloads. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Typeddict mode uses response.json() directly, so _deserialize is never called. Skip importing it to avoid W0611 unused-import lint warning. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove unused MutableMapping/Any imports from TypedDictModelType.imports() - Skip _deserialize import in paging_operation.py for typeddict mode Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ypespec into python/addTypedDict
TypedDictModelType returns 'JSON' for response type annotations but never defined the JSON = MutableMapping[str, Any] type alias, causing NameError at runtime. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
34e0cda to
95db199
Compare
Contributor
|
There is new file named |
Contributor
# Conflicts: # packages/http-client-python/generator/pygen/preprocess/__init__.py
- Add crossLanguageDefinitionId-based dedup to dpg model TypedDict creation (prevents duplicate TypedDict classes when multiple operations share the same body model) - Dedup typeddict_models in TypesSerializer: prefer dpg model over typeddict copy when both exist with the same crossLanguageDefinitionId Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
Author
this is defined as a named union, that's why we generate it as one |
…ct copies from _models.py - Only add 'from . import types' to sync __init__.py, not aio (types.py is generated at the sync level, aio doesn't have one) - Filter out base='typeddict' models from _models.py class list (typeddict copies should only appear in types.py, not as model classes) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add 'List' import to ListType.imports() when property/operation named 'list' exists (fixes NameError in special-words types.py) - Use has_non_json_models() for has_models in ModelInitSerializer to avoid generating 'from . import _models' when _models.py doesn't exist - Remove 'from . import types' from __init__.py — each TypedDict type's imports() already handles adding the types import where needed (operations) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
f77576c to
14b7d6c
Compare
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace is_operation_file with serialize_namespace_type to correctly determine when to add the typing.List import. Operation/client files only need it when has_operation_named_list is True, while model/types files need it when has_property_named_list is True. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…e conflicts Remove the 'from typing import List' import entirely from ListType. Types/model files now always use lowercase 'list' since a TypedDict field named 'list' doesn't shadow the builtin. Operation files still use the 'List = list' alias from define_mypy_type when there's an operation named 'list'. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
msyyc
reviewed
Jun 25, 2026
msyyc
left a comment
Contributor
There was a problem hiding this comment.
Will take another review soon.
The response type rendering passes is_operation_file=True but not serialize_namespace_type, so we need to check both to correctly determine operation context. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
msyyc
approved these changes
Jun 25, 2026
For models that are typeddict-only (either via models-mode=typeddict or individual models marked as typedDictOnly), skip the isinstance check against _models.X (which doesn't exist) and skip json.dumps serialization. TypedDict models are plain dicts and should be passed directly to the request as JSON. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add tests passing TypedDicts to regular dpg operations (both sync and async) to verify model + typeddict combined overloads work - Add async test for typeddictonly variant Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


fixes #8800
Add a new 'typeddict' value for the
models-modeoption that generates PythonTypedDictclasses instead of DPG model classes. Key features:_model_base.pystill generated for serialization utilities