Breaking Changes
Custom Template Update Required
- Parser subclass signature change - The
Parserbase class now requires two generic type parameters:Parser[ParserConfigT, SchemaFeaturesT]instead of justParser[ParserConfigT]. Custom parser subclasses must be updated to include the second type parameter. (#2929)# Before class MyCustomParser(Parser["MyParserConfig"]): ... # After class MyCustomParser(Parser["MyParserConfig", "JsonSchemaFeatures"]): ...
- New abstract
schema_featuresproperty required - Custom parser subclasses must now implement theschema_featuresabstract property that returns aJsonSchemaFeatures(or subclass) instance. (#2929)from functools import cached_property from datamodel_code_generator.parser.schema_version import JsonSchemaFeatures from datamodel_code_generator.enums import JsonSchemaVersion class MyCustomParser(Parser["MyParserConfig", "JsonSchemaFeatures"]): @cached_property def schema_features(self) -> JsonSchemaFeatures: return JsonSchemaFeatures.from_version(JsonSchemaVersion.Draft202012)
- Parser
_create_default_configrefactored to use class variable - Subclasses that override_create_default_configshould now set the_config_class_nameclass variable instead. The base implementation uses this variable to dynamically instantiate the correct config class. (#2929)# Before @classmethod def _create_default_config(cls, options: MyConfigDict) -> MyParserConfig: # custom implementation... # After _config_class_name: ClassVar[str] = "MyParserConfig" # No need to override _create_default_config if using standard config creation
- Template condition for default values changed - If you use custom Jinja2 templates based on
BaseModel_root.jinja2orRootModel.jinja2, the condition for including default values has changed fromfield.requiredto(field.required and not field.has_default). Update your custom templates if you override these files. (#2960)
Code Generation Changes
- RootModel default values now included in generated code - Previously, default values defined in JSON Schema or OpenAPI specifications for root models were not being applied to the generated Pydantic code. Now these defaults are correctly included. For example, a schema defining a root model with
default: 1will generate__root__: int = 1(Pydantic v1) orroot: int = 1(Pydantic v2) instead of just__root__: intorroot: int. This may affect code that relied on the previous behavior where RootModel fields had no default values. (#2960) - Required fields with list defaults now use
default_factory- Previously, required fields with list-type defaults (like__root__: list[ID] = ['abc', 'efg']) were generated with direct list assignments. Now they correctly useField(default_factory=lambda: ...)which follows Python best practices for mutable defaults. This changes the structure of generated code for root models and similar patterns with list defaults. (#2958)
Before:After:class Family(BaseModel): __root__: list[ID] = ['abc', 'efg']
class Family(BaseModel): __root__: list[ID] = Field( default_factory=lambda: [ID.parse_obj(v) for v in ['abc', 'efg']] )
What's Changed
- Separate pytest-benchmark into dedicated benchmark dependency group by @koxudaxi in #2937
- Support ClassVar for Pydantic v2 by @ubaumann in #2920
- Add schema version detection and feature flags by @koxudaxi in #2924
- Fix MRO ordering for multiple inheritance in GraphQL and JSON Schema/OpenAPI by @koxudaxi in #2941
- Add schema_features property to parsers for version detection by @koxudaxi in #2929
- Fix $ref handling in request-response mode for readOnly/writeOnly schemas by @koxudaxi in #2942
- Ensure codecov upload runs even when coverage check fails by @koxudaxi in #2944
- Add FeatureMetadata to schema feature classes for doc generation by @koxudaxi in #2945
- Add schema-docs auto-generation with pre-commit and CI by @koxudaxi in #2949
- Add comprehensive feature metadata to schema version dataclasses by @koxudaxi in #2946
- fix: move UnionMode import outside TYPE_CHECKING for Pydantic runtime… by @phil65 in #2950
- Fix IndexError when using --reuse-scope=tree with single file output by @koxudaxi in #2954
- Add --use-closed-typed-dict option to control PEP 728 TypedDict generation by @koxudaxi in #2956
- Fix RootModel default value not being applied by @koxudaxi in #2960
- Fix required list fields ignoring empty default values by @koxudaxi in #2958
- Add GenerateConfig lazy import from top-level module by @koxudaxi in #2961
- Fix allOf array property merging to preserve child $ref by @koxudaxi in #2962
- Fix array RootModel default value handling in parser by @koxudaxi in #2963
- Fix bug in handling of graphql empty list defaults by @rpmcginty in #2948
New Contributors
Full Changelog: 0.52.2...0.53.0