[python] add typeddict models-mode for Python HTTP client emitter#10439
[python] add typeddict models-mode for Python HTTP client emitter#10439iscai-msft wants to merge 81 commits into
models-mode for Python HTTP client emitter#10439Conversation
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: |
|
All changed packages have been documented.
Show changes
|
|
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
# 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>
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
left a comment
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>
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>
| RegenerateContext, | ||
| RegenerateFlags, | ||
| runParallel, | ||
| } from "./regenerate-common.js"; |
There was a problem hiding this comment.
regenerate-common is very important since it makes sync easy for typespec-python repo about the regeneration and test cases.
Actually you just need add a few lines of new configuration in regenerate-common.ts instead of so many changes while most are duplicated in regenerate.ts.
| const SKIP_SPECS: string[] = [ | ||
| "type/file", | ||
| "service/multiple-services", | ||
| "azure/client-generator-core/response-as-bool", | ||
| ]; |
There was a problem hiding this comment.
cases of line 56-line57 are already supported in https://github.com/microsoft/typespec/pull/10944/changes#diff-6d3a02078e3812a5ae4eb5b94e9f07952450932adb30a87dea6664ef8a270323.
| SKIP_PACKAGES = { | ||
| ("azure", "service-multiple-services"), | ||
| ("azure", "azure-client-generator-core-client-initialization"), | ||
| ("azure", "azure-client-generator-core-response-as-bool"), |
There was a problem hiding this comment.
no need to add it since this folder has README.md: https://github.com/Azure/azure-sdk-for-python/blob/typespec-python-generated-tests/eng/tools/azure-sdk-tools/emitter/generated/azure/azure-client-generator-core-response-as-bool/README.md.
After my comments about regenerate.ts resolved, you could remove this line.
…rate-common.ts Keep regenerate-common.ts as the synced, shared module instead of duplicating its helpers inline in regenerate.ts. Add the typeddict-specific emitter options and baseline changes there, and remove the now-supported response-as-bool skip entries. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
In models-mode: typeddict the binary/JSON overloads are omitted, leaving a single body variant that was still wrapped in a lone @overload (mypy: Single overload definition, multiple required). Collapse the one-member combined type back to a plain body type so no overload is emitted. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
running into a mypy error because of: https://github.com/Azure/azure-sdk-for-python/pull/47346/changes#r3483777805 |
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