-
Notifications
You must be signed in to change notification settings - Fork 61
Description
Bug Description
When a TypeSpec model containing a Record<string> property is wrapped with MergePatchUpdate<T>, the Python emitter generates an empty, unusable class RecordMergePatchUpdate instead of emitting Dict[str, str].
TypeSpec Source
The ContentUnderstandingDefaults model has a Record<string> property:
model ContentUnderstandingDefaults {
modelDeployments: Record<string>;
}This model is used in an operation via MergePatchUpdate<T>:
updateDefaults is Foundations.Operation<
MergePatchUpdate<ContentUnderstandingDefaults>,
ContentUnderstandingDefaults,
ServiceTraits
>;Generated Code (Broken)
The emitter generates an empty class with no properties, constructor, or dict-like behavior:
class RecordMergePatchUpdate(_Model):
"""RecordMergePatchUpdate."""This type is then used in the generated update_defaults operation signature:
def update_defaults(
self,
model_deployments: Optional[RecordMergePatchUpdate] = None,
...
)User Impact
Users cannot pass a dictionary to model_deployments. The empty class has no way to set key-value pairs, making the update_defaults API effectively broken without a workaround.
Contrast: Same Record<string> Works Correctly Elsewhere
The same Record<string> type on ContentUnderstandingDefaults (the response model, not the merge-patch input) generates correctly as dict[str, str]:
class ContentUnderstandingDefaults(_Model):
model_deployments: dict[str, str] = rest_field(name="modelDeployments", ...)Other Record<string> properties (e.g., tags on ContentAnalyzer) also generate correctly as dict[str, str]. The issue is specifically triggered when MergePatchUpdate<T> wraps a model containing Record<string>.
Our Workaround
We patched it in _patch.py by aliasing the empty class to Dict[str, str] and monkey-patching it onto the models module at runtime:
_patch.py#L50-L52(alias definition)_patch.py#L205-L206(runtime patch)
# _patch.py
RecordMergePatchUpdate = Dict[str, str]
def patch_sdk():
from . import _models
_models.RecordMergePatchUpdate = RecordMergePatchUpdateExpected Behavior
The emitter should either:
- Generate
RecordMergePatchUpdateas a type alias forDict[str, str], or - Inline the
Record<string>property on the merge-patch model asdict[str, str](same as it does for the non-patch model)