Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
0834a2c
feat: add typeddict models-mode for Python HTTP client emitter
Apr 21, 2026
27c8bfb
Enhance Python HTTP client emitter with TypedDict support
iscai-msft Apr 21, 2026
c1487f8
add discriminator
Apr 21, 2026
02e6f35
Merge branch 'python/addTypedDict' of https://github.com/iscai-msft/t…
Apr 21, 2026
2647828
Merge branch 'main' of https://github.com/microsoft/typespec into pyt…
Apr 21, 2026
3a125b8
feat: return JSON for typeddict responses, drop NotRequired
Apr 23, 2026
e0569db
feat: add wire name mock API tests for typeddict naming spec
Apr 23, 2026
3e5c0ef
fix: remove redundant JSON overload for typeddict mode
Apr 23, 2026
f76c88d
fix: remove unused _deserialize import in typeddict mode
Apr 23, 2026
2401b66
fix: remove all unused imports in typeddict generated code
Apr 23, 2026
57bf76a
Merge branch 'main' into python/addTypedDict
iscai-msft Apr 24, 2026
47b5024
format and lint
Apr 27, 2026
87ea0a1
Merge branch 'python/addTypedDict' of https://github.com/iscai-msft/t…
Apr 27, 2026
95db199
fix: define JSON type alias in TypedDictModelType imports
Apr 28, 2026
37806df
switch to always generating typeddicts as typing hints
May 5, 2026
18786e3
switch to always generating typeddicts as typing hints
May 5, 2026
8d323ac
Merge branch 'python/addTypedDict' of https://github.com/iscai-msft/t…
May 5, 2026
db10eeb
move discriminated union to types.py
May 6, 2026
841b2ee
Merge branch 'main' of https://github.com/microsoft/typespec into pyt…
May 6, 2026
a206181
format
May 6, 2026
9572470
add for output as well
May 6, 2026
cdcedf5
add e2e tests
May 6, 2026
1d1d7c6
update unions serializer to get around pyright issue
May 6, 2026
f5e1f7d
fix: resolve pylint and pyright errors in generated types.py
May 7, 2026
f5f9300
Merge branch 'main' of https://github.com/microsoft/typespec into pyt…
May 11, 2026
f3be83c
fix pylint and pyright in generated code
May 11, 2026
6a34daf
Merge branch 'main' of https://github.com/microsoft/typespec into pyt…
May 11, 2026
bf7ef34
fix: move discriminated union aliases from _unions.py to types.py
May 11, 2026
e6b1b52
fix: topologically sort discriminated union aliases in types.py
May 11, 2026
df17af5
fix: skip model imports in types.py regardless of namespace
May 11, 2026
cedece0
fix: skip imports for discriminated base models in types.py
May 11, 2026
4497199
fix: sort TypedDict properties to avoid builtin name shadowing
May 11, 2026
7c8bf77
fix: handle reserved words in TypedDict field names comprehensively
May 11, 2026
136e247
fix: generate types.py per namespace instead of only at top level
May 11, 2026
b14f874
fix: correct cross-namespace imports in per-namespace types.py
May 12, 2026
c67d633
feat: combine regenerate scripts and add typeddict variant packages
May 12, 2026
1dd8314
feat: add client-naming-typeddict variant package
May 12, 2026
48d2aed
refactor: remove unnecessary is_response pops from TypedDictModelType
May 12, 2026
a130bfc
fix: use TypedDict dicts instead of model classes in naming test
May 12, 2026
6a15774
fix: skip self-import in types.py and unused _deserialize for typed-d…
May 13, 2026
3789713
fix: skip _models prefix for internal models in types.py annotations
May 13, 2026
762d694
merge: resolve upstream/main conflict, inline regenerate-common.ts ch…
May 20, 2026
bd83e9f
Merge branch 'main' of https://github.com/microsoft/typespec into pyt…
May 26, 2026
6c0ee44
switch to models-mode=typeddict to represent td only, generate union …
May 26, 2026
6d75f07
don't conflate optional and nullable
May 26, 2026
27113ce
format and lint
May 26, 2026
1de57f4
fix: address PR review comments for TypedDict support
May 27, 2026
a88d471
lint
May 27, 2026
d9341d0
Merge branch 'main' into python/addTypedDict
iscai-msft Jun 1, 2026
ca95971
fix: address review comments on TypedDict PR
Jun 1, 2026
177a46c
fix: remove typeddict-specific guard from no-sdk-clients check
Jun 1, 2026
a1101da
feat: replace JSON overloads with TypedDict overloads in operations
Jun 2, 2026
a99065d
Merge remote-tracking branch 'upstream/main' into python/addTypedDict
Jun 2, 2026
3cea12c
fix: restore regenerate-common.ts
Jun 2, 2026
94f613b
Merge branch 'main' into python/addTypedDict
msyyc Jun 4, 2026
edb252d
fix: alias types imports to avoid conflicts in multi-namespace packages
Jun 4, 2026
4c0a3ac
Merge branch 'python/addTypedDict' of https://github.com/iscai-msft/t…
Jun 4, 2026
7f2ffd5
feat: use wire/serialization types for TypedDict properties
Jun 5, 2026
a5e1a39
Merge branch 'main' into python/addTypedDict
msyyc Jun 9, 2026
eb4123e
only generate types.py file if needed
Jun 10, 2026
75d097c
Merge branch 'python/addTypedDict' of https://github.com/iscai-msft/t…
Jun 10, 2026
33a5e4c
fix some commit issues
Jun 16, 2026
f9f0f2f
fix calling polymorphic subtypes on combined type
Jun 22, 2026
5226e44
Merge remote-tracking branch 'upstream/main' into python/addTypedDict
Jun 22, 2026
73710dc
fix splatted body params method
Jun 22, 2026
48f1180
attempt to have correct typeddicts show for splatted models
Jun 23, 2026
c2152a9
fix: dedup TypedDict copies in types.py for spread bodies and dpg models
Jun 23, 2026
1eaac1e
fix: prevent aio __init__.py from importing types and exclude typeddi…
Jun 24, 2026
1ff2c23
cspell
Jun 24, 2026
14b7d6c
fix: resolve CI failures in type checking, lint, and mock API tests
Jun 24, 2026
0a966b3
refactor: extract typeddict helpers to fix too-many-statements lint
Jun 24, 2026
32a4836
fix: use serialize_namespace_type for List import in ListType
Jun 24, 2026
251a85f
fix: use builtin list directly, only use List alias for operation nam…
Jun 24, 2026
e36cd75
fix: also check is_operation_file for List alias in type_annotation
Jun 25, 2026
b3380b9
format
Jun 25, 2026
0c545d5
fix: skip isinstance check and serialization for typeddict-only models
Jun 25, 2026
5e77c53
test: add TypedDict mock API tests for model usage
Jun 25, 2026
2b1291d
fix: skip response-as-bool in README test (in SKIP_SPECS)
Jun 25, 2026
ceed358
Merge branch 'main' into python/addTypedDict
iscai-msft Jun 25, 2026
d5a51f3
refactor(http-client-python): move typeddict regen config into regene…
l0lawrence Jun 26, 2026
0feff61
fix(http-client-python): avoid lone @overload in typeddict models-mode
l0lawrence Jun 26, 2026
5777d0a
fix(http-client-python): address review comments on regenerate-common.ts
l0lawrence Jun 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: fix
packages:
- "@typespec/http-client-python"
---

Fix invalid lone `@overload` generated for body parameters in `models-mode: typeddict`. When the binary and JSON overloads are omitted, the single remaining body variant is now emitted as a plain parameter instead of a single `@overload`, which mypy rejects with "Single overload definition, multiple required".
8 changes: 8 additions & 0 deletions .chronus/changes/python-addTypedDict-2026-3-21-17-47-3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: feature
packages:
- "@typespec/http-client-python"
---

[python] Always generate `TypedDict` typing hints for input models in the `types.py` file, and named union aliases in the `_unions.py` file
1 change: 1 addition & 0 deletions cspell.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ words:
- canonicalizer
- Cblack
- Cbrown
- clid
- clsx
- cobertura
- codehaus
Expand Down
2 changes: 2 additions & 0 deletions packages/http-client-python/emitter/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ function emitProperty(
// Python convert all the type of file part to FileType so clear these models' usage so that they won't be generated
addDisableGenerationMap(context, property.type);
}
const isNullable = !isMultipartFileInput && sourceType.kind === "nullable";
Comment thread
iscai-msft marked this conversation as resolved.
return {
clientName: getClientName(property),
isExactName: property.isExactName,
Expand All @@ -242,6 +243,7 @@ function emitProperty(
: property.serializationOptions?.json?.name) ?? property.name,
type: getType(context, sourceType),
optional: property.optional,
nullable: isNullable,
Comment thread
msyyc marked this conversation as resolved.
description: property.summary ? property.summary : property.doc,
addedOn: getAddedOn(context, property),
apiVersions: property.apiVersions,
Expand Down
55 changes: 40 additions & 15 deletions packages/http-client-python/eng/scripts/ci/regenerate-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,15 @@ export const AZURE_EMITTER_OPTIONS: Record<
"package-name": "client-structure-twooperationgroup",
namespace: "client.structure.twooperationgroup",
},
"client/naming": {
namespace: "client.naming.main",
},
"client/naming": [
{
namespace: "client.naming.main",
},
{
"package-name": "client-naming-typeddict",
namespace: "client.naming.typeddict",
},
],
"client/overload": {
namespace: "client.overload",
},
Expand Down Expand Up @@ -271,14 +277,26 @@ export const EMITTER_OPTIONS: Record<string, Record<string, string> | Record<str
"package-name": "typetest-model-nesteddiscriminator",
namespace: "typetest.model.nesteddiscriminator",
},
"type/model/inheritance/not-discriminated": {
"package-name": "typetest-model-notdiscriminated",
namespace: "typetest.model.notdiscriminated",
},
"type/model/inheritance/single-discriminator": {
"package-name": "typetest-model-singlediscriminator",
namespace: "typetest.model.singlediscriminator",
},
"type/model/inheritance/not-discriminated": [
{
"package-name": "typetest-model-notdiscriminated",
namespace: "typetest.model.notdiscriminated",
},
{
"package-name": "typetest-model-notdiscriminated-typeddict",
namespace: "typetest.model.notdiscriminated.typeddict",
},
],
"type/model/inheritance/single-discriminator": [
{
"package-name": "typetest-model-singlediscriminator",
namespace: "typetest.model.singlediscriminator",
},
{
"package-name": "typetest-model-singlediscriminator-typeddict",
namespace: "typetest.model.singlediscriminator.typeddict",
},
],
"type/model/inheritance/recursive": [
{
"package-name": "typetest-model-recursive",
Expand All @@ -292,10 +310,17 @@ export const EMITTER_OPTIONS: Record<string, Record<string, string> | Record<str
"clear-output-folder": "true",
},
],
"type/model/usage": {
"package-name": "typetest-model-usage",
namespace: "typetest.model.usage",
},
"type/model/usage": [
{
"package-name": "typetest-model-usage",
namespace: "typetest.model.usage",
},
{
"package-name": "typetest-model-usage-typeddictonly",
namespace: "typetest.model.usage.typeddictonly",
"models-mode": "typeddict",
},
],
"type/model/visibility": [
{
"package-name": "typetest-model-visibility",
Expand Down
6 changes: 3 additions & 3 deletions packages/http-client-python/generator/pygen/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,10 @@ def _validate_and_transform(self, key: str, value: Any) -> Any:
if key == "models-mode" and value == "none":
value = False # switch to falsy value for easier code writing

if key == "models-mode" and value not in ["msrest", "dpg", False]:
if key == "models-mode" and value not in ["msrest", "dpg", "typeddict", False]:
raise ValueError(
"--models-mode can only be 'msrest', 'dpg' or 'none'. "
"Pass in 'msrest' if you want msrest models, or "
"--models-mode can only be 'msrest', 'dpg', 'typeddict', or 'none'. "
"Pass in 'msrest' if you want msrest models, 'typeddict' for TypedDict models, or "
"'none' if you don't want any."
)
if key == "package-mode":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from .base_builder import BaseBuilder, ParameterListType
from .code_model import CodeModel
from .client import Client
from .model_type import ModelType, JSONModelType, DPGModelType, MsrestModelType
from .model_type import ModelType, JSONModelType, DPGModelType, MsrestModelType, TypedDictModelType
from .dictionary_type import DictionaryType
from .list_type import ListType
from .combined_type import CombinedType
Expand Down Expand Up @@ -167,7 +167,9 @@ def build_type(yaml_data: dict[str, Any], code_model: CodeModel) -> BaseType:
response: Optional[BaseType] = None
if yaml_data["type"] == "model":
# need to special case model to avoid recursion
if yaml_data["base"] == "json" or not code_model.options["models-mode"]:
if yaml_data["base"] == "typeddict":
model_type = TypedDictModelType # type: ignore
elif yaml_data["base"] == "json" or not code_model.options["models-mode"]:
model_type = JSONModelType
elif yaml_data["base"] == "dpg":
model_type = DPGModelType # type: ignore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,16 +152,28 @@ def get_relative_import_path(
return result
return f"{result}{module_name}" if result.endswith(".") else f"{result}.{module_name}"

def get_unique_models_alias(self, serialize_namespace: str, imported_namespace: str) -> str:
def _get_unique_import_alias(self, serialize_namespace: str, imported_namespace: str, module_name: str) -> str:
if not self.has_subnamespace:
return "_models"
return f"_{module_name}"
relative_path = self.get_relative_import_path(
serialize_namespace, self.get_imported_namespace_for_model(imported_namespace)
)
dot_num = max(relative_path.count(".") - 1, 0)
parts = [""] + ([p for p in relative_path.split(".") if p] or ["models"])
path_parts = [p for p in relative_path.split(".") if p]
# For "models", keep existing format: _<path_parts><dot_num> (e.g. _models1, _firstnamespace_models2)
# For other modules like "types", prefix with module name: _types_<path_parts><dot_num>
if module_name == "models":
parts = [""] + (path_parts or [module_name])
else:
parts = [f"_{module_name}"] + (path_parts or [])
return "_".join(parts) + (str(dot_num) if dot_num > 0 else "")

def get_unique_models_alias(self, serialize_namespace: str, imported_namespace: str) -> str:
return self._get_unique_import_alias(serialize_namespace, imported_namespace, "models")

def get_unique_types_alias(self, serialize_namespace: str, imported_namespace: str) -> str:
return self._get_unique_import_alias(serialize_namespace, imported_namespace, "types")

@property
def client_namespace_types(self) -> dict[str, ClientNamespaceType]:
if not self._client_namespace_types:
Expand All @@ -174,6 +186,14 @@ def client_namespace_types(self) -> dict[str, ClientNamespaceType]:
if model.client_namespace not in self._client_namespace_types:
self._client_namespace_types[model.client_namespace] = ClientNamespaceType()
self._client_namespace_types[model.client_namespace].models.append(model)
# TypedDict copies (base="typeddict") are excluded from model_types to keep
# them out of _models.py, but they need to be in the namespace model list
# so the TypesSerializer can render them in types.py.
for t in self.types_map.values():
if isinstance(t, ModelType) and t.base == "typeddict" and t.usage != UsageFlags.Default.value:
if t.client_namespace not in self._client_namespace_types:
self._client_namespace_types[t.client_namespace] = ClientNamespaceType()
self._client_namespace_types[t.client_namespace].models.append(t)
for enum in self.enums:
if enum.client_namespace not in self._client_namespace_types:
self._client_namespace_types[enum.client_namespace] = ClientNamespaceType()
Expand Down Expand Up @@ -339,7 +359,9 @@ def model_types(self) -> list[ModelType]:
"""All of the model types in this class"""
if not self._model_types:
self._model_types = [
t for t in self.types_map.values() if isinstance(t, ModelType) and t.usage != UsageFlags.Default.value
t
for t in self.types_map.values()
if isinstance(t, ModelType) and t.usage != UsageFlags.Default.value and t.base != "typeddict"
]
return self._model_types

Expand All @@ -349,7 +371,7 @@ def model_types(self, val: list[ModelType]) -> None:

@staticmethod
def get_public_model_types(models: list[ModelType]) -> list[ModelType]:
return [m for m in models if not m.internal and not m.base == "json"]
return [m for m in models if not m.internal and not m.base == "json" and not m.is_typed_dict_only]

@property
def public_model_types(self) -> list[ModelType]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def docstring_type(self, **kwargs: Any) -> str:

def type_annotation(self, **kwargs: Any) -> str:
if self.name:
return f'"_types.{self.name}"'
return f'"_unions.{self.name}"'
Comment thread
iscai-msft marked this conversation as resolved.
return self.type_definition(**kwargs)

def type_definition(self, **kwargs: Any) -> str:
Expand Down Expand Up @@ -116,10 +116,10 @@ def imports(self, **kwargs: Any) -> FileImport:
file_import = FileImport(self.code_model)
serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
serialize_namespace_type = kwargs.get("serialize_namespace_type")
if self.name and serialize_namespace_type != NamespaceType.TYPES_FILE:
if self.name and serialize_namespace_type != NamespaceType.UNIONS_FILE:
file_import.add_submodule_import(
self.code_model.get_relative_import_path(serialize_namespace),
"_types",
"_unions",
ImportType.LOCAL,
TypingSection.TYPING,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,16 +167,31 @@ def description(self, *, is_operation_file: bool) -> str:
enum_description = f"Known values are: {possible_values_str}."
return enum_description

@property
def is_typeddict_mode(self) -> bool:
return self.code_model.options["models-mode"] == "typeddict"

def type_annotation(self, **kwargs: Any) -> str:
"""The python type used for type annotation

:return: The type annotation for this schema
:rtype: str
"""
if self.code_model.options["models-mode"]:
if self.is_typeddict_mode:
# In typeddict mode, enums are Literal aliases defined in types.py
Comment thread
iscai-msft marked this conversation as resolved.
serialize_namespace_type = kwargs.get("serialize_namespace_type")
if serialize_namespace_type == NamespaceType.TYPES_FILE:
# Same file — just the name, no module prefix
return self.name
# From operation/client files, use types.EnumName (matching model pattern)
return f"types.{self.name}"

module_name = ""
if kwargs.get("need_model_alias", True):
serialize_namespace_type = kwargs.get("serialize_namespace_type")
if serialize_namespace_type == NamespaceType.TYPES_FILE:
pass # no module prefix for types.py
elif kwargs.get("need_model_alias", True):
serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
model_alias = self.code_model.get_unique_models_alias(serialize_namespace, self.client_namespace)
module_name = f"{model_alias}."
Expand Down Expand Up @@ -240,31 +255,66 @@ def imports(self, **kwargs: Any) -> FileImport:
file_import = FileImport(self.code_model)
file_import.merge(self.value_type.imports(**kwargs))
if self.code_model.options["models-mode"]:
file_import.add_submodule_import("typing", "Union", ImportType.STDLIB, TypingSection.REGULAR)
if self.is_typeddict_mode:
# In typeddict mode, enums are Literal aliases in types.py — no Union needed
serialize_namespace_type = kwargs.get("serialize_namespace_type")
if serialize_namespace_type == NamespaceType.TYPES_FILE:
# Same file — no import needed for same-namespace enums
serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
if self.client_namespace != serialize_namespace:
# Cross-namespace: import from sibling types module
relative_path = self.code_model.get_relative_import_path(
serialize_namespace, self.client_namespace
)
file_import.add_submodule_import(
f"{relative_path}types" if relative_path != "." else ".types",
self.name,
ImportType.LOCAL,
typing_section=TypingSection.REGULAR,
)
elif serialize_namespace_type in [NamespaceType.OPERATION, NamespaceType.CLIENT]:
# Import types module directly (matching model pattern)
serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
relative_path = self.code_model.get_relative_import_path(serialize_namespace, self.client_namespace)
file_import.add_submodule_import(
relative_path,
"types",
ImportType.LOCAL,
)
else:
file_import.add_submodule_import("typing", "Union", ImportType.STDLIB, TypingSection.REGULAR)

serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
relative_path = self.code_model.get_relative_import_path(serialize_namespace, self.client_namespace)
alias = self.code_model.get_unique_models_alias(serialize_namespace, self.client_namespace)
serialize_namespace_type = kwargs.get("serialize_namespace_type")
called_by_property = kwargs.get("called_by_property", False)
if serialize_namespace_type in [NamespaceType.OPERATION, NamespaceType.CLIENT]:
file_import.add_submodule_import(
relative_path,
"models",
ImportType.LOCAL,
alias=alias,
typing_section=TypingSection.REGULAR,
)
elif serialize_namespace_type == NamespaceType.TYPES_FILE or (
serialize_namespace_type == NamespaceType.MODEL and called_by_property
):
file_import.add_submodule_import(
relative_path,
"models",
ImportType.LOCAL,
alias=alias,
typing_section=TypingSection.TYPING,
)
serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
relative_path = self.code_model.get_relative_import_path(serialize_namespace, self.client_namespace)
alias = self.code_model.get_unique_models_alias(serialize_namespace, self.client_namespace)
serialize_namespace_type = kwargs.get("serialize_namespace_type")
called_by_property = kwargs.get("called_by_property", False)
if serialize_namespace_type in [NamespaceType.OPERATION, NamespaceType.CLIENT]:
file_import.add_submodule_import(
relative_path,
"models",
ImportType.LOCAL,
alias=alias,
typing_section=TypingSection.REGULAR,
)
elif serialize_namespace_type == NamespaceType.TYPES_FILE:
# Import enum name directly to avoid dotted forward refs in TypedDict annotations
file_import.add_submodule_import(
f"{relative_path}models" if relative_path != "." else ".models",
self.name,
ImportType.LOCAL,
typing_section=TypingSection.TYPING,
)
elif serialize_namespace_type == NamespaceType.UNIONS_FILE or (
serialize_namespace_type == NamespaceType.MODEL and called_by_property
):
file_import.add_submodule_import(
relative_path,
"models",
ImportType.LOCAL,
alias=alias,
typing_section=TypingSection.TYPING,
)

file_import.merge(self.value_type.imports(**kwargs))
return file_import
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from typing import Any, Optional, Union, TYPE_CHECKING
from .base import BaseType
from .imports import FileImport
from .utils import NamespaceType

if TYPE_CHECKING:
from .code_model import CodeModel
Expand Down Expand Up @@ -41,12 +42,17 @@ def type_annotation(self, **kwargs: Any) -> str:
# this means we're version tolerant XML, we just return the XML element
return self.element_type.type_annotation(**kwargs)

# if there is a function/property named `list` we have to make sure there's no conflict with the built-in `list`
# if there is a function named `list` we have to make sure there's no conflict with the built-in `list`
# in operation files. The operation_groups_serializer defines `List = list` alias for this case.
serialize_namespace_type = kwargs.get("serialize_namespace_type")
is_operation_file = kwargs.get("is_operation_file", False)
use_list_import = (self.code_model.has_operation_named_list and is_operation_file) or (
self.code_model.has_property_named_list and not is_operation_file
in_operation_context = (
serialize_namespace_type in (NamespaceType.OPERATION, NamespaceType.CLIENT) or is_operation_file
)
list_type = "List" if use_list_import else "list"
if in_operation_context and self.code_model.has_operation_named_list:
list_type = "List"
else:
list_type = "list"
return f"{list_type}[{self.element_type.type_annotation(**kwargs)}]"

def description(self, *, is_operation_file: bool) -> str:
Expand Down
Loading
Loading