From 8e9a17fe0252c1290f585d1fb680c4e64cb5495a Mon Sep 17 00:00:00 2001 From: Huan-Cheng Chang Date: Sat, 13 Jan 2024 11:45:22 +0100 Subject: [PATCH] [Python] Handle nullable dictionary values (#17605) * fix nullable elements in maps * update examples * exclude values typed as Any --- .../languages/AbstractPythonCodegen.java | 20 +++++++++++-------- .../python-aiohttp/docs/NullableClass.md | 4 ++-- .../petstore_api/models/nullable_class.py | 4 ++-- .../petstore/python/docs/NullableClass.md | 4 ++-- .../petstore_api/models/nullable_class.py | 4 ++-- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java index e6c9e36846f6..749f832af958 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java @@ -693,14 +693,10 @@ public String getTypeDeclaration(Schema p) { if (ModelUtils.isArraySchema(p)) { ArraySchema ap = (ArraySchema) p; Schema inner = ap.getItems(); - String innerDeclaration = getTypeDeclaration(inner); - if (inner.getNullable() != null && inner.getNullable()) { - innerDeclaration = "Optional[" + innerDeclaration + "]"; - } - return getSchemaType(p) + "[" + innerDeclaration + "]"; + return getSchemaType(p) + "[" + getCollectionItemTypeDeclaration(inner) + "]"; } else if (ModelUtils.isMapSchema(p)) { Schema inner = ModelUtils.getAdditionalProperties(p); - return getSchemaType(p) + "[str, " + getTypeDeclaration(inner) + "]"; + return getSchemaType(p) + "[str, " + getCollectionItemTypeDeclaration(inner) + "]"; } String openAPIType = getSchemaType(p); @@ -715,6 +711,14 @@ public String getTypeDeclaration(Schema p) { return toModelName(openAPIType); } + private String getCollectionItemTypeDeclaration(Schema inner) { + String innerDeclaration = getTypeDeclaration(inner); + if (Boolean.TRUE.equals(inner.getNullable())) { + innerDeclaration = "Optional[" + innerDeclaration + "]"; + } + return innerDeclaration; + } + @Override public String getSchemaType(Schema p) { String openAPIType = super.getSchemaType(p); @@ -1758,7 +1762,7 @@ private PythonType arrayType(IJsonSchemaValidationProperties cp) { private PythonType collectionItemType(CodegenProperty itemCp) { PythonType itemPt = getType(itemCp); - if (itemCp != null && itemCp.isNullable) { + if (itemCp != null && !itemPt.type.equals("Any") && itemCp.isNullable) { moduleImports.add("typing", "Optional"); PythonType opt = new PythonType("Optional"); opt.addTypeParam(itemPt); @@ -1802,7 +1806,7 @@ private PythonType mapType(IJsonSchemaValidationProperties cp) { moduleImports.add("typing", "Dict"); PythonType pt = new PythonType("Dict"); pt.addTypeParam(new PythonType("str")); - pt.addTypeParam(getType(cp.getItems())); + pt.addTypeParam(collectionItemType(cp.getItems())); return pt; } diff --git a/samples/openapi3/client/petstore/python-aiohttp/docs/NullableClass.md b/samples/openapi3/client/petstore/python-aiohttp/docs/NullableClass.md index 9dc167e54e9d..866a4b571864 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/docs/NullableClass.md +++ b/samples/openapi3/client/petstore/python-aiohttp/docs/NullableClass.md @@ -16,8 +16,8 @@ Name | Type | Description | Notes **array_and_items_nullable_prop** | **List[Optional[object]]** | | [optional] **array_items_nullable** | **List[Optional[object]]** | | [optional] **object_nullable_prop** | **Dict[str, object]** | | [optional] -**object_and_items_nullable_prop** | **Dict[str, object]** | | [optional] -**object_items_nullable** | **Dict[str, object]** | | [optional] +**object_and_items_nullable_prop** | **Dict[str, Optional[object]]** | | [optional] +**object_items_nullable** | **Dict[str, Optional[object]]** | | [optional] ## Example diff --git a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/models/nullable_class.py b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/models/nullable_class.py index 41e660fc73e4..64a2fe91b29d 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/models/nullable_class.py +++ b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/models/nullable_class.py @@ -38,8 +38,8 @@ class NullableClass(BaseModel): array_and_items_nullable_prop: Optional[List[Optional[Dict[str, Any]]]] = None array_items_nullable: Optional[List[Optional[Dict[str, Any]]]] = None object_nullable_prop: Optional[Dict[str, Dict[str, Any]]] = None - object_and_items_nullable_prop: Optional[Dict[str, Dict[str, Any]]] = None - object_items_nullable: Optional[Dict[str, Dict[str, Any]]] = None + object_and_items_nullable_prop: Optional[Dict[str, Optional[Dict[str, Any]]]] = None + object_items_nullable: Optional[Dict[str, Optional[Dict[str, Any]]]] = None additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["required_integer_prop", "integer_prop", "number_prop", "boolean_prop", "string_prop", "date_prop", "datetime_prop", "array_nullable_prop", "array_and_items_nullable_prop", "array_items_nullable", "object_nullable_prop", "object_and_items_nullable_prop", "object_items_nullable"] diff --git a/samples/openapi3/client/petstore/python/docs/NullableClass.md b/samples/openapi3/client/petstore/python/docs/NullableClass.md index 9dc167e54e9d..866a4b571864 100644 --- a/samples/openapi3/client/petstore/python/docs/NullableClass.md +++ b/samples/openapi3/client/petstore/python/docs/NullableClass.md @@ -16,8 +16,8 @@ Name | Type | Description | Notes **array_and_items_nullable_prop** | **List[Optional[object]]** | | [optional] **array_items_nullable** | **List[Optional[object]]** | | [optional] **object_nullable_prop** | **Dict[str, object]** | | [optional] -**object_and_items_nullable_prop** | **Dict[str, object]** | | [optional] -**object_items_nullable** | **Dict[str, object]** | | [optional] +**object_and_items_nullable_prop** | **Dict[str, Optional[object]]** | | [optional] +**object_items_nullable** | **Dict[str, Optional[object]]** | | [optional] ## Example diff --git a/samples/openapi3/client/petstore/python/petstore_api/models/nullable_class.py b/samples/openapi3/client/petstore/python/petstore_api/models/nullable_class.py index 5ad5c19a06cd..1ad6d35535e0 100644 --- a/samples/openapi3/client/petstore/python/petstore_api/models/nullable_class.py +++ b/samples/openapi3/client/petstore/python/petstore_api/models/nullable_class.py @@ -38,8 +38,8 @@ class NullableClass(BaseModel): array_and_items_nullable_prop: Optional[List[Optional[Dict[str, Any]]]] = None array_items_nullable: Optional[List[Optional[Dict[str, Any]]]] = None object_nullable_prop: Optional[Dict[str, Dict[str, Any]]] = None - object_and_items_nullable_prop: Optional[Dict[str, Dict[str, Any]]] = None - object_items_nullable: Optional[Dict[str, Dict[str, Any]]] = None + object_and_items_nullable_prop: Optional[Dict[str, Optional[Dict[str, Any]]]] = None + object_items_nullable: Optional[Dict[str, Optional[Dict[str, Any]]]] = None additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["required_integer_prop", "integer_prop", "number_prop", "boolean_prop", "string_prop", "date_prop", "datetime_prop", "array_nullable_prop", "array_and_items_nullable_prop", "array_items_nullable", "object_nullable_prop", "object_and_items_nullable_prop", "object_items_nullable"]