Skip to content

fix(http-client-python): avoid _enums import for constant enum values in typeddict mode#11212

Merged
msyyc merged 2 commits into
microsoft:mainfrom
l0lawrence:l0lawrence-typeddict-enum-import
Jul 9, 2026
Merged

fix(http-client-python): avoid _enums import for constant enum values in typeddict mode#11212
msyyc merged 2 commits into
microsoft:mainfrom
l0lawrence:l0lawrence-typeddict-enum-import

Conversation

@l0lawrence

@l0lawrence l0lawrence commented Jul 8, 2026

Copy link
Copy Markdown
Member

Problem

In models-mode: typeddict, enums are emitted as Literal aliases in types.py (e.g. Color = Literal["red", "blue"]) and _enums.py is never generated. However, a single constant enum value (EnumValue) still used the dpg-style annotation Literal[Color.RED] and imported Color from ..models._enums — a module that does not exist in typeddict mode, and an attribute (Color.RED) that a Literal alias does not have.

Fix

EnumValue, in typeddict mode only:

  • type_annotation returns the raw literal value — Literal["red"] — instead of Literal[Color.RED].
  • imports skips the _enums import (only typing.Literal is needed).

dpg / msrest behavior is unchanged. ConstantType is unaffected (it already uses primitive value types).

# models-mode: typeddict — before (broken)
from ..models._enums import Color   # _enums.py never generated
x: Literal[Color.RED]               # Color is a Literal alias, has no .RED

# after
from typing import Literal
x: Literal["red"]

This scenario is what I have a question on:

# models-mode: typeddict — before (broken)
from ..models._enums import Foo  # _enums.py never generated
Foo = Literal["bar"]
x: Literal[Foo.BAR]              

# after
from typing import Literal
Foo = Literal["bar"]   # enums are extensible so at any time Foo could become Foo = Literal["bar", "bar2"]????
x: Literal["bar"]

versus where it is the whole enum type

# models-mode: typeddict — before (broken)
from ..models._enums import Foo  # _enums.py never generated
Foo = Literal["bar"]
x: Foo        

# after
from typing import Literal
Foo = Literal["bar"]  
x: Foo

… in typeddict mode

In models-mode: typeddict, enums are emitted as Literal aliases in types.py
and _enums.py is never generated. A single constant enum value previously
annotated as Literal[Color.RED] and imported Color from the nonexistent
..models._enums module. It now annotates with its literal value (e.g.
Literal["red"]) and skips the _enums import.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@microsoft-github-policy-service microsoft-github-policy-service Bot added the emitter:client:python Issue for the Python client emitter: @typespec/http-client-python label Jul 8, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jul 8, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/http-client-python@11212

commit: 662e27e

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

All changed packages have been documented.

  • @typespec/http-client-python
Show changes

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

Fix constant enum values referencing the nonexistent _enums module in models-mode: typeddict. In typeddict mode enums are emitted as Literal aliases in types.py and _enums.py is never generated, so a single constant enum value now annotates with its literal value (e.g. Literal["red"]) and no longer imports from _enums.

@azure-sdk-automation

azure-sdk-automation Bot commented Jul 8, 2026

Copy link
Copy Markdown

You can try these changes here

🛝 Playground 🌐 Website 🛝 VSCode Extension

@l0lawrence

Copy link
Copy Markdown
Member Author

fixes #11210

@l0lawrence

Copy link
Copy Markdown
Member Author

@msyyc msyyc added this pull request to the merge queue Jul 9, 2026
Merged via the queue into microsoft:main with commit 57c3174 Jul 9, 2026
41 of 43 checks passed
tadelesh pushed a commit that referenced this pull request Jul 9, 2026
… in typeddict mode (#11212)

## Problem

In `models-mode: typeddict`, enums are emitted as `Literal` aliases in
`types.py` (e.g. `Color = Literal["red", "blue"]`) and `_enums.py` is
**never generated**. However, a single constant enum value (`EnumValue`)
still used the dpg-style annotation `Literal[Color.RED]` and imported
`Color` from `..models._enums` — a module that does not exist in
typeddict mode, and an attribute (`Color.RED`) that a `Literal` alias
does not have.

## Fix

`EnumValue`, in typeddict mode only:

- `type_annotation` returns the raw literal value — `Literal["red"]` —
instead of `Literal[Color.RED]`.
- `imports` skips the `_enums` import (only `typing.Literal` is needed).

dpg / msrest behavior is unchanged. `ConstantType` is unaffected (it
already uses primitive value types).

```python
# models-mode: typeddict — before (broken)
from ..models._enums import Color   # _enums.py never generated
x: Literal[Color.RED]               # Color is a Literal alias, has no .RED

# after
from typing import Literal
x: Literal["red"]
```


This scenario is what I have a question on:


```python
# models-mode: typeddict — before (broken)
from ..models._enums import Foo  # _enums.py never generated
Foo = Literal["bar"]
x: Literal[Foo.BAR]              

# after
from typing import Literal
Foo = Literal["bar"]   # enums are extensible so at any time Foo could become Foo = Literal["bar", "bar2"]????
x: Literal["bar"]
```

versus where it is the whole enum type

```python
# models-mode: typeddict — before (broken)
from ..models._enums import Foo  # _enums.py never generated
Foo = Literal["bar"]
x: Foo        

# after
from typing import Literal
Foo = Literal["bar"]  
x: Foo
```

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:python Issue for the Python client emitter: @typespec/http-client-python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants