Skip to content

Commit

Permalink
fix: exclude unwrappable dictionaries for pydantic preset (#1860)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonaslagoni committed Mar 6, 2024
1 parent e9272bf commit e0e1741
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 6 deletions.
3 changes: 3 additions & 0 deletions docs/languages/Python.md
Expand Up @@ -17,6 +17,9 @@ There are special use-cases that each language supports; this document pertains
In some cases you might want to use [pydantic](https://pypi.org/project/pydantic/) data validation and settings management using Python type hints for the models.
Modelina follows Pydantic v2.

There are some limitations to the current implementation:
1. The preset doesn't unwrap properties of type `ConstrainedDictionaryModel` with `serialilzationType = unwrap`, they are simply excluded from the serialization

You can find an example of its use [here](../../examples/generate-python-pydantic-models/index.ts)

## Generate models with JSON Serializer and Deserializer methods
Expand Down
14 changes: 12 additions & 2 deletions src/generators/python/presets/Pydantic.ts
@@ -1,4 +1,7 @@
import { ConstrainedUnionModel } from '../../../models';
import {
ConstrainedDictionaryModel,
ConstrainedUnionModel
} from '../../../models';
import { PythonOptions } from '../PythonGenerator';
import { ClassPresetType, PythonPreset } from '../PythonPreset';

Expand Down Expand Up @@ -38,7 +41,14 @@ const PYTHON_PYDANTIC_CLASS_PRESET: ClassPresetType<PythonOptions> = {
: undefined;
const defaultValue = params.property.required ? undefined : 'default=None';
const jsonAlias = `serialization_alias='${params.property.unconstrainedPropertyName}'`;
const fieldTags = [description, defaultValue, jsonAlias].filter(
let exclude = undefined;
if (
params.property.property instanceof ConstrainedDictionaryModel &&
params.property.property.serializationType === 'unwrap'
) {
exclude = 'exclude=True';
}
const fieldTags = [description, defaultValue, jsonAlias, exclude].filter(
(value) => value
);
return `${propertyName}: ${type} = Field(${fieldTags.join(', ')})`;
Expand Down
Expand Up @@ -6,23 +6,23 @@ exports[`PYTHON_PYDANTIC_PRESET should render pydantic for class 1`] = `
multi
line
description''', default=None, serialization_alias='prop')
additionalProperties: Optional[dict[Any, Any]] = Field(default=None, serialization_alias='additionalProperties')
additionalProperties: Optional[dict[Any, Any]] = Field(default=None, serialization_alias='additionalProperties', exclude=True)
"
`;

exports[`PYTHON_PYDANTIC_PRESET should render union to support Python < 3.10 1`] = `
Array [
"class UnionTest(BaseModel):
unionTest: Optional[Union[Union1, Union2]] = Field(default=None, serialization_alias='unionTest')
additionalProperties: Optional[dict[Any, Any]] = Field(default=None, serialization_alias='additionalProperties')
additionalProperties: Optional[dict[Any, Any]] = Field(default=None, serialization_alias='additionalProperties', exclude=True)
",
"class Union1(BaseModel):
testProp1: Optional[str] = Field(default=None, serialization_alias='testProp1')
additionalProperties: Optional[dict[Any, Any]] = Field(default=None, serialization_alias='additionalProperties')
additionalProperties: Optional[dict[Any, Any]] = Field(default=None, serialization_alias='additionalProperties', exclude=True)
",
"class Union2(BaseModel):
testProp2: Optional[str] = Field(default=None, serialization_alias='testProp2')
additionalProperties: Optional[dict[Any, Any]] = Field(default=None, serialization_alias='additionalProperties')
additionalProperties: Optional[dict[Any, Any]] = Field(default=None, serialization_alias='additionalProperties', exclude=True)
",
]
`;

0 comments on commit e0e1741

Please sign in to comment.