Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 0 additions & 2 deletions docs/generators/python-aiohttp.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
## LANGUAGE PRIMITIVES

<ul class="column-ul">
<li>Dict</li>
<li>List</li>
<li>UUID</li>
<li>bool</li>
<li>bytes</li>
Expand Down
2 changes: 0 additions & 2 deletions docs/generators/python-blueplanet.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
## LANGUAGE PRIMITIVES

<ul class="column-ul">
<li>Dict</li>
<li>List</li>
<li>UUID</li>
<li>bool</li>
<li>bytes</li>
Expand Down
2 changes: 0 additions & 2 deletions docs/generators/python-fastapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
## LANGUAGE PRIMITIVES

<ul class="column-ul">
<li>Dict</li>
<li>List</li>
<li>UUID</li>
<li>bool</li>
<li>bytes</li>
Expand Down
2 changes: 0 additions & 2 deletions docs/generators/python-flask.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
## LANGUAGE PRIMITIVES

<ul class="column-ul">
<li>Dict</li>
<li>List</li>
<li>UUID</li>
<li>bool</li>
<li>bytes</li>
Expand Down
2 changes: 0 additions & 2 deletions docs/generators/python-pydantic-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
## LANGUAGE PRIMITIVES

<ul class="column-ul">
<li>Dict</li>
<li>List</li>
<li>bool</li>
<li>bytearray</li>
<li>bytes</li>
Expand Down
2 changes: 0 additions & 2 deletions docs/generators/python.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
## LANGUAGE PRIMITIVES

<ul class="column-ul">
<li>Dict</li>
<li>List</li>
<li>UUID</li>
<li>bool</li>
<li>bytearray</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,6 @@ public AbstractPythonCodegen() {
languageSpecificPrimitives.add("float");
languageSpecificPrimitives.add("list");
languageSpecificPrimitives.add("dict");
languageSpecificPrimitives.add("List");
languageSpecificPrimitives.add("Dict");
languageSpecificPrimitives.add("bool");
languageSpecificPrimitives.add("str");
languageSpecificPrimitives.add("datetime");
Expand Down Expand Up @@ -896,7 +894,6 @@ private ModelsMap postProcessModelsMap(ModelsMap objs) {
if (!model.oneOf.isEmpty()) { // oneOfValidationError
codegenProperties = model.getComposedSchemas().getOneOf();
moduleImports.add("typing", "Any");
moduleImports.add("typing", "List");
moduleImports.add("pydantic", "Field");
moduleImports.add("pydantic", "StrictStr");
moduleImports.add("pydantic", "ValidationError");
Expand Down Expand Up @@ -932,11 +929,7 @@ private ModelsMap postProcessModelsMap(ModelsMap objs) {
// if model_generic.mustache is used
if (model.oneOf.isEmpty() && model.anyOf.isEmpty() && !model.isEnum) {
moduleImports.add("typing", "ClassVar");
moduleImports.add("typing", "Dict");
moduleImports.add("typing", "Any");
if (this.disallowAdditionalPropertiesIfNotPresent || model.isAdditionalPropertiesTrue) {
moduleImports.add("typing", "List");
}
}

// if pydantic model
Expand Down Expand Up @@ -1571,7 +1564,7 @@ public PythonType addTypeParam(PythonType typeParam) {
* The Python / Pydantic type can be as expressive as needed:
*
* - it could simply be `str`
* - or something more complex like `Optional[List[Dict[str, List[int]]]]`.
* - or something more complex like `Optional[list[dict[str, list[int]]]]`.
*
* Note that the default value (if available) and/or the metadata about
* the field / variable being defined are *not* part of the
Expand Down Expand Up @@ -1773,13 +1766,9 @@ private PythonType arrayType(IJsonSchemaValidationProperties cp) {
// Also, having a set instead of list creates complications:
// random JSON serialization order, unable to easily serialize
// to JSON, etc.
//pt.setType("Set");
//moduleImports.add("typing", "Set");
pt.setType("List");
moduleImports.add("typing", "List");
pt.setType("list");
} else {
pt.setType("List");
moduleImports.add("typing", "List");
pt.setType("list");
}
pt.addTypeParam(collectionItemType(cp.getItems()));
return pt;
Expand Down Expand Up @@ -1828,8 +1817,7 @@ private PythonType stringType(IJsonSchemaValidationProperties cp) {
}

private PythonType mapType(IJsonSchemaValidationProperties cp) {
moduleImports.add("typing", "Dict");
PythonType pt = new PythonType("Dict");
PythonType pt = new PythonType("dict");
pt.addTypeParam(new PythonType("str"));
pt.addTypeParam(collectionItemType(cp.getItems()));
return pt;
Expand Down Expand Up @@ -1954,9 +1942,7 @@ private PythonType binaryType(IJsonSchemaValidationProperties cp) {
pt.addTypeParam(strt);

if (cp.getIsBinary()) {
moduleImports.add("typing", "Tuple");

PythonType tt = new PythonType("Tuple");
PythonType tt = new PythonType("tuple");
// this string is a filename, not a validated value
tt.addTypeParam(new PythonType("str"));
tt.addTypeParam(bytest);
Expand All @@ -1976,9 +1962,7 @@ private PythonType binaryType(IJsonSchemaValidationProperties cp) {
pt.addTypeParam(new PythonType("StrictStr"));

if (cp.getIsBinary()) {
moduleImports.add("typing", "Tuple");

PythonType tt = new PythonType("Tuple");
PythonType tt = new PythonType("tuple");
tt.addTypeParam(new PythonType("StrictStr"));
tt.addTypeParam(new PythonType("StrictBytes"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,6 @@ public AbstractPythonConnexionServerCodegen(String templateDirectory, boolean fi
simpleModule.addSerializer(Boolean.class, new PythonBooleanSerializer());
MAPPER.registerModule(simpleModule);

// TODO may remove these later to default to the setting in abstract python base class instead
languageSpecificPrimitives.add("List");
languageSpecificPrimitives.add("Dict");
typeMapping.put("array", "List");
typeMapping.put("map", "Dict");

// set the output folder here
outputFolder = "generated-code" + File.separatorChar + "connexion";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,6 @@ public AbstractPythonPydanticV1Codegen() {
languageSpecificPrimitives.add("float");
languageSpecificPrimitives.add("list");
languageSpecificPrimitives.add("dict");
languageSpecificPrimitives.add("List");
languageSpecificPrimitives.add("Dict");
languageSpecificPrimitives.add("bool");
languageSpecificPrimitives.add("str");
languageSpecificPrimitives.add("datetime");
Expand Down Expand Up @@ -843,7 +841,6 @@ private ModelsMap postProcessModelsMap(ModelsMap objs) {
if (!model.oneOf.isEmpty()) { // oneOfValidationError
codegenProperties = model.getComposedSchemas().getOneOf();
typingImports.add("Any");
typingImports.add("List");
pydanticImports.add("Field");
pydanticImports.add("StrictStr");
pydanticImports.add("ValidationError");
Expand Down Expand Up @@ -879,7 +876,6 @@ private ModelsMap postProcessModelsMap(ModelsMap objs) {
if (model.oneOf.isEmpty() && model.anyOf.isEmpty()
&& !model.isEnum
&& !this.disallowAdditionalPropertiesIfNotPresent) {
typingImports.add("Dict");
typingImports.add("Any");
}

Expand Down Expand Up @@ -1070,8 +1066,7 @@ private String getPydanticType(CodegenParameter cp,
getPydanticType(cp.items, typingImports, pydanticImports, datetimeImports, modelImports, exampleImports, postponedModelImports, postponedExampleImports, classname),
constraints);
} else if (cp.isMap) {
typingImports.add("Dict");
return String.format(Locale.ROOT, "Dict[str, %s]",
return String.format(Locale.ROOT, "dict[str, %s]",
getPydanticType(cp.items, typingImports, pydanticImports, datetimeImports, modelImports, exampleImports, postponedModelImports, postponedExampleImports, classname));
} else if (cp.isString) {
if (cp.hasValidation) {
Expand Down Expand Up @@ -1266,9 +1261,8 @@ private String getPydanticType(CodegenParameter cp,
} else if (cp.isUuid) {
return cp.dataType;
} else if (cp.isFreeFormObject) { // type: object
typingImports.add("Dict");
typingImports.add("Any");
return "Dict[str, Any]";
return "dict[str, Any]";
} else if (!cp.isPrimitiveType) {
// add model prefix
hasModelsToImport = true;
Expand Down Expand Up @@ -1351,13 +1345,11 @@ private String getPydanticType(CodegenProperty cp,
constraints += ", unique_items=True";
}
pydanticImports.add("conlist");
typingImports.add("List"); // for return type
return String.format(Locale.ROOT, "conlist(%s%s)",
getPydanticType(cp.items, typingImports, pydanticImports, datetimeImports, modelImports, exampleImports, postponedModelImports, postponedExampleImports, classname),
constraints);
} else if (cp.isMap) {
typingImports.add("Dict");
return String.format(Locale.ROOT, "Dict[str, %s]", getPydanticType(cp.items, typingImports, pydanticImports, datetimeImports, modelImports, exampleImports, postponedModelImports, postponedExampleImports, classname));
return String.format(Locale.ROOT, "dict[str, %s]", getPydanticType(cp.items, typingImports, pydanticImports, datetimeImports, modelImports, exampleImports, postponedModelImports, postponedExampleImports, classname));
} else if (cp.isString) {
if (cp.hasValidation) {
List<String> fieldCustomization = new ArrayList<>();
Expand Down Expand Up @@ -1550,9 +1542,8 @@ private String getPydanticType(CodegenProperty cp,
} else if (cp.isUuid) {
return cp.dataType;
} else if (cp.isFreeFormObject) { // type: object
typingImports.add("Dict");
typingImports.add("Any");
return "Dict[str, Any]";
return "dict[str, Any]";
} else if (!cp.isPrimitiveType || cp.isModel) { // model
// skip import if it's a circular reference
if (classname == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,7 @@ public PythonClientCodegen() {
// at the moment
importMapping.clear();

// override type mapping in abstract python codegen
typeMapping.put("array", "List");
typeMapping.put("set", "List");
typeMapping.put("map", "Dict");
// extend type mapping in abstract python codegen
typeMapping.put("decimal", "decimal.Decimal");
typeMapping.put("file", "bytearray");
typeMapping.put("binary", "bytearray");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,6 @@ public PythonFastAPIServerCodegen() {
additionalProperties.put(CodegenConstants.PACKAGE_NAME, DEFAULT_PACKAGE_NAME);
additionalProperties.put(CodegenConstants.FASTAPI_IMPLEMENTATION_PACKAGE, DEFAULT_IMPL_FOLDER);

languageSpecificPrimitives.add("List");
languageSpecificPrimitives.add("Dict");
typeMapping.put("array", "List");
typeMapping.put("map", "Dict");

outputFolder = "generated-code" + File.separator + NAME;
modelTemplateFiles.put("model.mustache", ".py");
apiTemplateFiles.put("api.mustache", ".py");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,7 @@ public PythonPydanticV1ClientCodegen() {
// at the moment
importMapping.clear();

// override type mapping in abstract python codegen
typeMapping.put("array", "List");
typeMapping.put("set", "List");
typeMapping.put("map", "Dict");
// extend type mapping in abstract python codegen
typeMapping.put("decimal", "decimal.Decimal");
typeMapping.put("file", "bytearray");
typeMapping.put("binary", "bytearray");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from typing import List, Dict
from aiohttp import web

{{#imports}}{{import}}
Expand Down Expand Up @@ -36,7 +35,7 @@ async def {{operationId}}(request: web.Request, {{#allParams}}{{paramName}}{{^re
{{#isArray}}
{{#items}}
{{#isPrimitiveType}}
:type {{paramName}}: List[{{>param_type}}]
:type {{paramName}}: list[{{>param_type}}]
{{/isPrimitiveType}}
{{^isPrimitiveType}}
:type {{paramName}}: list | bytes
Expand All @@ -46,7 +45,7 @@ async def {{operationId}}(request: web.Request, {{#allParams}}{{paramName}}{{^re
{{#isMap}}
{{#items}}
{{#isPrimitiveType}}
:type {{paramName}}: Dict[str, {{>param_type}}]
:type {{paramName}}: dict[str, {{>param_type}}]
{{/isPrimitiveType}}
{{^isPrimitiveType}}
:type {{paramName}}: dict | bytes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

from datetime import date, datetime

from typing import List, Dict, Type

from {{modelPackage}}.base_model import Model
{{#models}}
{{#model}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from typing import List

{{#authMethods}}
{{#isOAuth}}

Expand All @@ -14,7 +12,7 @@ def info_from_{{name}}(token: str) -> dict:
return {'scopes': ['read:pets', 'write:pets'], 'uid': 'user_id'}


def validate_scope_{{name}}(required_scopes: List[str], token_scopes: List[str]) -> bool:
def validate_scope_{{name}}(required_scopes: list[str], token_scopes: list[str]) -> bool:
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Using list[str] without from __future__ import annotations breaks generated code on Python <3.9, but the python‑aiohttp templates still declare support for Python 3.6+ (and even 3.4/3.5). This is a compatibility regression.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At modules/openapi-generator/src/main/resources/python-aiohttp/security_controller.mustache, line 15:

<comment>Using `list[str]` without `from __future__ import annotations` breaks generated code on Python <3.9, but the python‑aiohttp templates still declare support for Python 3.6+ (and even 3.4/3.5). This is a compatibility regression.</comment>

<file context>
@@ -14,7 +12,7 @@ def info_from_{{name}}(token: str) -> dict:
 
 
-def validate_scope_{{name}}(required_scopes: List[str], token_scopes: List[str]) -> bool:
+def validate_scope_{{name}}(required_scopes: list[str], token_scopes: list[str]) -> bool:
     """ Validate required scopes are included in token scope """
     return set(required_scopes).issubset(set(token_scopes))
</file context>
Fix with Cubic

""" Validate required scopes are included in token scope """
return set(required_scopes).issubset(set(token_scopes))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ if sys.version_info < (3, 7):
return type(klass) == typing.GenericMeta

def is_dict(klass):
""" Determine whether klass is a Dict """
""" Determine whether klass is a dict """
return klass.__extra__ == dict

def is_list(klass):
""" Determine whether klass is a List """
""" Determine whether klass is a list """
return klass.__extra__ == list

else:
Expand All @@ -24,9 +24,9 @@ else:
return hasattr(klass, '__origin__')

def is_dict(klass):
""" Determine whether klass is a Dict """
""" Determine whether klass is a dict """
return klass.__origin__ == dict

def is_list(klass):
""" Determine whether klass is a List """
""" Determine whether klass is a list """
return klass.__origin__ == list
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ from typing import Union
from {{packageName}} import typing_utils

T = typing.TypeVar('T')
Class = typing.Type[T]
Class = type[T]


def _deserialize(data: Union[dict, list, str], klass: Union[Class, str]) -> Union[dict, list, Class, int, float, str, bool, datetime.date, datetime.datetime]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def {{operationId}}({{#allParams}}{{paramName}}{{^required}}=None{{/required}}{{
{{#isArray}}
{{#items}}
{{#isPrimitiveType}}
:type {{paramName}}: List[{{#isString}}str{{/isString}}{{#isInteger}}int{{/isInteger}}{{#isLong}}int{{/isLong}}{{#isFloat}}float{{/isFloat}}{{#isDouble}}float{{/isDouble}}{{#isByteArray}}str{{/isByteArray}}{{#isBinary}}str{{/isBinary}}{{#isBoolean}}bool{{/isBoolean}}{{#isDate}}str{{/isDate}}{{#isDateTime}}str{{/isDateTime}}]
:type {{paramName}}: list[{{#isString}}str{{/isString}}{{#isInteger}}int{{/isInteger}}{{#isLong}}int{{/isLong}}{{#isFloat}}float{{/isFloat}}{{#isDouble}}float{{/isDouble}}{{#isByteArray}}str{{/isByteArray}}{{#isBinary}}str{{/isBinary}}{{#isBoolean}}bool{{/isBoolean}}{{#isDate}}str{{/isDate}}{{#isDateTime}}str{{/isDateTime}}]
{{/isPrimitiveType}}
{{^isPrimitiveType}}
:type {{paramName}}: list | bytes
Expand All @@ -45,7 +45,7 @@ def {{operationId}}({{#allParams}}{{paramName}}{{^required}}=None{{/required}}{{
{{#isMap}}
{{#items}}
{{#isPrimitiveType}}
:type {{paramName}}: Dict[str, {{#isString}}str{{/isString}}{{#isInteger}}int{{/isInteger}}{{#isLong}}int{{/isLong}}{{#isFloat}}float{{/isFloat}}{{#isDouble}}float{{/isDouble}}{{#isByteArray}}str{{/isByteArray}}{{#isBinary}}str{{/isBinary}}{{#isBoolean}}bool{{/isBoolean}}{{#isDate}}str{{/isDate}}{{#isDateTime}}str{{/isDateTime}}]
:type {{paramName}}: dict[str, {{#isString}}str{{/isString}}{{#isInteger}}int{{/isInteger}}{{#isLong}}int{{/isLong}}{{#isFloat}}float{{/isFloat}}{{#isDouble}}float{{/isDouble}}{{#isByteArray}}str{{/isByteArray}}{{#isBinary}}str{{/isBinary}}{{#isBoolean}}bool{{/isBoolean}}{{#isDate}}str{{/isDate}}{{#isDateTime}}str{{/isDateTime}}]
{{/isPrimitiveType}}
{{^isPrimitiveType}}
:type {{paramName}}: dict | bytes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Model(object):
attribute_map = {}

@classmethod
def from_dict(cls: typing.Type[T], dikt) -> T:
def from_dict(cls: type[T], dikt) -> T:
"""Returns the dict as a model"""
return util.deserialize_model(dikt, cls)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
from __future__ import absolute_import
from datetime import date, datetime # noqa: F401

from typing import List, Dict # noqa: F401

from {{modelPackage}}.base_model import Model
{{#imports}}{{import}} # noqa: F401,E501
{{/imports}}
Expand Down
Loading
Loading