Breaking Changes
Code Generation Changes
- Enum member names from oneOf/anyOf const constructs now use
titlefield when provided - Previously, when creating enums fromoneOf/anyOfconstructs withconstvalues, thetitlefield was incorrectly ignored and enum member names were generated using the pattern{type}_{value}(e.g.,integer_200). Now, when atitleis specified, it is correctly used as the enum member name (e.g.,OKinstead ofinteger_200). Users who have code depending on the previously generated enum member names will need to update their references. (#2975)
Before:After:class StatusCode(IntEnum): integer_200 = 200 integer_404 = 404 integer_500 = 500
class StatusCode(IntEnum): OK = 200 Not_Found = 404 Server_Error = 500
- Field names matching Python builtins are now automatically sanitized - When a field name matches a Python builtin type AND the field's type annotation uses that same builtin (e.g.,
int: int,list: list[str],dict: dict[str, Any]), the field is now renamed with a trailing underscore (e.g.,int_) and an alias is added to preserve the original JSON field name. This prevents Python syntax issues and shadowing of builtin types. Previously, such fields were generated as-is (e.g.,int: int | None = None), which could cause code that shadows Python builtins. After this change, the same field becomesint_: int | None = Field(None, alias='int'). This affects fields named:int,float,bool,str,bytes,list,dict,set,frozenset,tuple, and other Python builtins when their type annotation uses the matching builtin type. (#2968) - $ref with non-standard metadata fields no longer triggers schema merging - Previously, when a
$refwas combined with non-standard fields likemarkdownDescription,if,then,else, or other extras not in the whitelist, the generator would merge schemas and potentially create duplicate models (e.g.,UserWithExtraalongsideUser). Now, only whitelisted schema-affecting extras (currently justconst) trigger merging. This means:- Fewer merged/duplicate models will be generated
- References are preserved directly instead of being expanded
- Field types may change from inline merged types to direct references
Example schema:
Before: Could generate a mergedproperties: user: $ref: "#/definitions/User" nullable: true markdownDescription: "A user object"
UserWithMarkdownDescriptionmodel
After: Directly usesUser | Nonereference (#2993) - Enum member names no longer get underscore suffix with
--capitalise-enum-members- Previously, enum values likereplace,count,indexwould generateREPLACE_,COUNT_,INDEX_when using--capitalise-enum-members. Now they correctly generateREPLACE,COUNT,INDEX. The underscore suffix is only added when--use-subclass-enumis also used AND the lowercase name conflicts with builtin type methods. Users relying on the previous naming (e.g., referencingMyEnum.REPLACE_in code) will need to update to use the new names without trailing underscores. (#2999) - Fields using
$refwith inline keywords now include merged metadata - When a schema property uses$refalongside additional keywords (e.g.,const,enum,readOnly, constraints), the generator now correctly merges metadata (description, title, constraints, defaults, readonly/writeOnly) from the referenced schema into the field definition. Previously, this metadata was lost. For example, a field liketype: Typemay now becometype: Type = Field(..., description='Type of this object.', title='type')when the referenced schema includes those attributes. This also affectsadditionalPropertiesand OpenAPI parameter schemas. (#2997)
What's Changed
- Refactor ruff check+format to use sequential subprocess calls by @koxudaxi in #2967
- Fix title ignored when creating enums from merging
allOf's oranyOf's objects by @ilovelinux in #2975 - Fix aliased imports not applied to base classes and non-matching fields by @koxudaxi in #2981
- Fix handling of falsy default values for enums in set-default-enum-member option by @kkinugasa in #2977
- Fix use_union_operator with Python builtin type field names by @koxudaxi in #2968
- Support $recursiveRef/$dynamicRef in JSON Schema and OpenAPI by @koxudaxi in #2982
- Address review feedback for recursive/dynamic ref support by @koxudaxi in #2985
- Fix RecursionError in _merge_ref_with_schema for circular $ref by @koxudaxi in #2983
- Fix missing Field import with multiple aliases on required fields by @koxudaxi in #2992
- Fix patternProperties/propertyNames key constraints lost with field_constraints by @koxudaxi in #2994
- Fix type loss when $ref is used with non-standard metadata fields by @koxudaxi in #2993
- Fix missing | None for nullable enum literals in TypedDict by @koxudaxi in #2991
- Fix exact imports with module/class name collision by @koxudaxi in #2998
- Fix extra underscore on enum members like replace with --capitalise-enum-members by @koxudaxi in #2999
- Fix merged result in parse_item not passed back to parse_object_fields by @koxudaxi in #2997
- Fix codespeed python version by @koxudaxi in #3000
- Fix incorrect relative imports with --use-exact-imports and --collapse-root-models by @koxudaxi in #2996
New Contributors
- @kkinugasa made their first contribution in #2977
Full Changelog: 0.53.0...0.54.0