fix(http-client-python): don't corrupt TypedDict literal values matching builtin names - #11268
Merged
Yuchao Yan (msyyc) merged 1 commit intoJul 16, 2026
Merged
Conversation
…ing builtin names The builtin-shadowing workaround in types_serializer.py used a naive word-boundary regex that also matched identifiers inside string literals (e.g. the `type` in `Literal[\\ ype\\]`), rewriting literal values and quoted forward references into `builtins.X` and emitting spurious `import builtins` statements. Detection and application are now string-literal-aware and detect shadowing against the actually-emitted (TYPES_FILE) annotation, so genuine sibling-builtin shadowing is still qualified while literal values and quoted forward references are left untouched. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
commit: |
Contributor
|
All changed packages have been documented.
Show changes
|
|
You can try these changes here
|
Libba Lawrence (l0lawrence)
marked this pull request as ready for review
July 15, 2026 20:49
Yuchao Yan (msyyc)
approved these changes
Jul 16, 2026
Yuchao Yan (msyyc)
deleted the
l0lawrence-fix-builtins-literal-corruption
branch
July 16, 2026 03:46
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.
Problem
In the Python HTTP client emitter, a TypedDict literal value that coincides with a Python builtin type name got corrupted into
builtins.Xin the generatedtypes.py:The TypeSpec source (
type: "type";) is correct; the corruption is introduced purely by the emitter.Root cause
packages/http-client-python/generator/pygen/codegen/serializers/types_serializer.pyhas a TypedDict-only builtin-shadowing workaround: when a field's wire name is a Python builtin type name (e.g.bytes,int,type) and a sibling field is annotated with that bare builtin, pyright errorsreportInvalidTypeForm(the earlier field shadows the type). To avoid that, the serializer qualifies the builtin asbuiltins.X.Both the detection (
get_shadowed_builtins) and the application (_qualify_shadowed_builtins) used a naive\bname\bregex that also matched inside string literals likeLiteral["type"], so:builtins.X, andimport builtinsstatements were emitted.A second, related issue: detection ran against the default annotation while emission uses the
TYPES_FILEannotation. UnderTYPES_FILEsome types change (bytes/datetime→str,decimal→float), so detection could both miss real shadowing and flag false ones.Fix
_qualify_shadowed_builtinsand the detection helper are now string-literal-aware: the annotation is split on single/double-quoted spans and the\bname\bsubstitution only runs on code segments. A(?<!\.)lookbehind also skips already-dotted names (nobuiltins.builtins).get_shadowed_builtinsnow detects shadowing against the actually-emitted (TYPES_FILE) annotation, so genuine sibling-builtin shadowing is still qualified while literal values / quoted forward references are left untouched, and no spuriousimport builtinsis emitted.Surgical change; no unrelated refactoring.
Behavior preserved
The legitimate case is still qualified (verified with pyright):
Tests
tests/unit/test_typeddict.py(36 pass), covering: (a) a Literal value coinciding with a builtin name is not rewritten; (b) a quoted forward reference is left untouched; (c) genuine sibling-builtin shadowing is qualified tobuiltins.X; (d) already-dotted names are not double-qualified; (e) no spuriousimport builtinsfor the false-positive; and (f) types that change underTYPES_FILEdon't cause spurious imports.Regeneration
Regenerated the full test corpus (azure + unbranded) with and without the change. Zero diff — the fix is behavior-preserving:
typetest-union, a field namedintwithbuiltins.intsiblings) is retained unchanged.Validation
pytest tests/unit/test_typeddict.py→ 36 passed