From 5a052830b1cbbe1246163d1b8f1320223b75ed3a Mon Sep 17 00:00:00 2001 From: Janne Husberg <112867847+janne-slamcore@users.noreply.github.com> Date: Thu, 16 May 2024 12:45:54 +0100 Subject: [PATCH] fix: treat nullable property as optional for pydantic (#2001) --- src/generators/python/presets/Pydantic.ts | 7 +++-- .../python/presets/Pydantic.spec.ts | 29 +++++++++++++++++++ .../__snapshots__/Pydantic.spec.ts.snap | 13 +++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/generators/python/presets/Pydantic.ts b/src/generators/python/presets/Pydantic.ts index 90621732ab..fff3304986 100644 --- a/src/generators/python/presets/Pydantic.ts +++ b/src/generators/python/presets/Pydantic.ts @@ -29,7 +29,10 @@ const PYTHON_PYDANTIC_CLASS_PRESET: ClassPresetType = { type = `Union[${unionTypes.join(', ')}]`; } - if (!params.property.required) { + const isOptional = + !params.property.required || + params.property.property.options.isNullable === true; + if (isOptional) { type = `Optional[${type}]`; } @@ -40,7 +43,7 @@ const PYTHON_PYDANTIC_CLASS_PRESET: ClassPresetType = { `description='''${params.property.property.originalInput['description']}'''` ); } - if (!params.property.required) { + if (isOptional) { decoratorArgs.push('default=None'); } if ( diff --git a/test/generators/python/presets/Pydantic.spec.ts b/test/generators/python/presets/Pydantic.spec.ts index b3442d2048..a76f8f93de 100644 --- a/test/generators/python/presets/Pydantic.spec.ts +++ b/test/generators/python/presets/Pydantic.spec.ts @@ -65,4 +65,33 @@ describe('PYTHON_PYDANTIC_PRESET', () => { const models = await generator.generate(doc); expect(models.map((model) => model.result)).toMatchSnapshot(); }); + + test('should render nullable union', async () => { + const doc = { + title: 'NullableUnionTest', + type: 'object', + required: ['nullableUnionTest'], + properties: { + nullableUnionTest: { + anyOf: [ + { + title: 'Union1', + type: 'object', + properties: { + testProp1: { + type: 'string' + } + } + }, + { + type: 'null' + } + ] + } + } + }; + + const models = await generator.generate(doc); + expect(models.map((model) => model.result)).toMatchSnapshot(); + }); }); diff --git a/test/generators/python/presets/__snapshots__/Pydantic.spec.ts.snap b/test/generators/python/presets/__snapshots__/Pydantic.spec.ts.snap index 4cba95efa5..71e7e71ea8 100644 --- a/test/generators/python/presets/__snapshots__/Pydantic.spec.ts.snap +++ b/test/generators/python/presets/__snapshots__/Pydantic.spec.ts.snap @@ -1,5 +1,18 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`PYTHON_PYDANTIC_PRESET should render nullable union 1`] = ` +Array [ + "class NullableUnionTest(BaseModel): + nullableUnionTest: Optional[Union[Union1]] = Field(default=None) + additionalProperties: Optional[dict[Any, Any]] = Field(default=None) +", + "class Union1(BaseModel): + testProp1: Optional[str] = Field(default=None) + additionalProperties: Optional[dict[Any, Any]] = Field(default=None) +", +] +`; + exports[`PYTHON_PYDANTIC_PRESET should render pydantic for class 1`] = ` "class Test(BaseModel): prop: Optional[str] = Field(description='''test